From f4a702e212d1853735f8dae399da69d23bfa510e Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期四, 26 三月 2026 18:16:16 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into h5version

---
 Main/System/HeroDebut/HeroDebutCallHistoryOutCell.cs.meta                                                 |   11 
 Main/System/OSActivity/OSRankGiftBaseWin.cs.meta                                                          |   11 
 Main/Config/Configs/ModelConfig.cs                                                                        |    5 
 Main/Core/NetworkPackage/ClientPack/CAA SaleActivity.meta                                                 |    8 
 Main/System/Store/SkinStoreWin.cs                                                                         |   87 
 Main/System/OSActivity/OSRankHeroTrainAwardWin.cs.meta                                                    |   11 
 Main/System/OtherPlayerDetail/OtherPlayerDetailWin.cs                                                     |    2 
 Main/System/HeroDebut/HeroDebutSkinWin.cs                                                                 |  229 
 Main/Core/GameEngine/Launch/RequestPermissionStart.cs                                                     |   14 
 Main/System/PhantasmPavilion/IPhantasmPavilionTabHandler.cs                                               |    1 
 Main/System/OtherPlayerDetail/BuffInfoWin.cs.meta                                                         |   11 
 Main/Core/NetworkPackage/ServerPack/HA3_Function/HA350_tagMCTreasureResult.cs                             |   14 
 Main/System/TianziBillborad/TianziBillboradWin.cs                                                         |    1 
 Main/System/Store/HeroSkinGiftWin.cs                                                                      |  120 
 Main/Config/Configs/TreasureSetConfig.cs                                                                  |   77 
 Main/System/PlayerProfile/PlayerProfileWin.cs                                                             |   13 
 Main/System/PhantasmPavilion/PhantasmPavilionTilteWin.cs                                                  |   17 
 Main/System/HeroUI/HeroSkinCell.cs                                                                        |   47 
 Main/System/PlayerProfile/RenameManager.cs                                                                |    2 
 Main/System/OSActivity/OSActivityManager.cs                                                               |  116 
 Main/System/Recharge/RechargeGoldCell.cs                                                                  |    2 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA21_tagSCActHeroAppearInfo.cs.meta       |   11 
 Main/System/PhantasmPavilion/PhantasmPavilionModelHandler.cs                                              |   21 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA20_tagSCActSignPlayerInfo.cs.meta                 |   11 
 Main/System/OpenServerActivity/OperationTimeHepler.cs                                                     |  132 
 Main/Config/PartialConfigs/TreasureItemLibConfig.cs                                                       |   16 
 Main/System/OSActivity/OSRankHeroTrainAwardCell.cs.meta                                                   |   11 
 Main/System/HeroDebut/HeroDebutGiftWin.cs.meta                                                            |   11 
 Main/Config/PartialConfigs/HeroConfig.cs.meta                                                             |   11 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA21_tagSCActHeroAppearInfo.cs            |   12 
 Main/System/Battle/BattleConst.cs                                                                         |   12 
 Main/System/HeroDebut/HeroDebutCallHistoryCell.cs                                                         |   42 
 Main/System/SystemSetting/SystemSetting.cs                                                                |    2 
 Main/System/HeroDebut/HeroDebutGiftWin.cs                                                                 |   86 
 Main/System/BeautyMM/BeautyMMShowWin.cs                                                                   |   21 
 Main/System/Battle/BattleFieldFactory.cs                                                                  |    6 
 Main/System/OSActivity/OSRankBeautyMMAwardWin.cs                                                          |   18 
 Main/System/BillboardRank/PlayerTop3Cell.cs                                                               |   17 
 Main/System/Recharge/PrivilegeCardCell.cs                                                                 |    4 
 Main/Config/PartialConfigs/ActBillboardAwardConfig.cs                                                     |   77 
 Main/System/HeroDebut/HeroDebutStarUpCell.cs                                                              |  126 
 Main/System/OSActivity/OSRankMinggeGiftCell.cs                                                            |    8 
 Main/Config/Configs/TitleConfig.cs                                                                        |  175 
 Main/Config/Configs/ActBillboardAwardConfig.cs                                                            |   53 
 Main/System/HeroDebut/HeroDebutCallChangeItem.cs                                                          |   41 
 Main/System/Store/SkinStoreLineCell.cs.meta                                                               |   11 
 Main/System/HeroUI/HeroTrainWin.cs                                                                        |   71 
 Main/System/Horse/HorseController.cs                                                                      |   86 
 Main/System/KnapSack/Logic/RolePackWin.cs                                                                 |    2 
 Main/System/HeroUI/HeroCollectionCardCell.cs                                                              |   30 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA106_tagMCCoinToGoldReport.cs.meta                 |   11 
 Main/System/HeroDebut/HeroDebutManager.cs                                                                 | 1051 +++
 Main/System/HeroUI/HeroBestBaseWin.cs.meta                                                                |   11 
 Main/System/HeroDebut/HeroDebutRankTop3Cell.cs.meta                                                       |   11 
 Main/System/HeroDebut/HeroDebutCell.cs.meta                                                               |   11 
 Main/Config/Configs/ActHeroAppearConfig.cs.meta                                                           |   11 
 Main/System/OSActivity/OSGalaGiftCell.cs                                                                  |   50 
 Main/System/HeroDebut/HeroDebutCallChangeWin.cs                                                           |  100 
 Main/System/OSActivity/OSRankHeroTrainAwardWin.cs                                                         |   16 
 Main/System/HeroDebut/HeroDebutCallResultCell.cs                                                          |  104 
 Main/System/Battle/BattleField/QYBattleField.cs.meta                                                      |   11 
 Main/System/Qunying/QYNoteWin.cs.meta                                                                     |   11 
 Main/System/Qunying/QYNoteWin.cs                                                                          |   63 
 Main/Core/GameEngine/Player/PlayerDatas.cs                                                                |    5 
 Main/System/PlayerProfile/RenameWin.cs                                                                    |   51 
 Main/System/BoneField/AdsManager.cs                                                                       |   56 
 Main/System/HeroDebut/HeroDebutCallResultWin.cs.meta                                                      |   11 
 Main/Utility/DeviceUtility.cs                                                                             |    2 
 Main/System/Main/HomeGridLayout.cs                                                                        |  178 
 Main/Core/NetworkPackage/ServerPack/HA3_Function/HA351_tagMCTreasureInfo.cs                               |    8 
 Main/System/Settlement/BattleSettlementManager.cs                                                         |   16 
 Main/Config/Configs/HeroConfig.cs                                                                         |    8 
 Main/System/OSActivity/OSRankAwardBaseCell.cs.meta                                                        |   11 
 Main/System/PhantasmPavilion/PhantasmPavilionManager.Attr.cs                                              |   74 
 Main/System/Store/StoreModel.cs                                                                           |   78 
 Main/System/HeroDebut/HeroDebutCell.cs                                                                    |   31 
 Main/System/ViewNPC/ViewBuffManager.cs.meta                                                               |   11 
 Main/System/Battle/Skill/SkillFactory.cs                                                                  |    1 
 Main/System/HeroUI/HeroSkinRoleCell.cs                                                                    |   23 
 Main/Config/Configs/PlayerFaceConfig.cs                                                                   |    5 
 Main/Config/PartialConfigs/ActSignAwardConfig.cs                                                          |   57 
 Main/System/Store/BuyItemWin.cs                                                                           |   24 
 Main/System/ItemTip/BoxGetItemModel.cs                                                                    |   28 
 Main/System/OSActivity/OSRankAwardBaseWin.cs.meta                                                         |   11 
 Main/System/OtherPlayerDetail/BuffInfoWin.cs                                                              |   83 
 Main/System/UIBase/UIBase.cs                                                                              |  128 
 Main/System/OSActivity/OSRankBaseWin.cs                                                                   |   42 
 Main/System/Recharge/RechargeManager.cs                                                                   |   26 
 Main/System/Main/FightPowerFormula.cs                                                                     |   15 
 Main/System/DailySpecials/DailySpecialsItem.cs                                                            |    2 
 Main/System/Tip/ItemsConfirmWin.cs                                                                        |    2 
 Main/System/HeroUI/HeroCardCell.cs                                                                        |    7 
 Main/System/MainLevel/MainBossEnterWin.cs                                                                 |   12 
 Main/System/KnapSack/Logic/ItemLogicUtility.cs                                                            |   21 
 Main/System/BeautyMM/BeautyMMActiveWin.cs                                                                 |   13 
 Main/System/PhantasmPavilion/PhantasmPavilionFacePicHandler.cs                                            |    4 
 Main/Config/PartialConfigs/ModelConfig.cs                                                                 |   20 
 Main/System/HeroDebut/HeroDebutShopLineCell.cs.meta                                                       |   11 
 Main/System/HeroDebut/HeroDebutRankWin.cs.meta                                                            |   11 
 Main/System/Qunying/QYRankAwardCell.cs                                                                    |   54 
 Main/System/HeroDebut/HeroDebutRankAwardCell.cs.meta                                                      |   11 
 Main/Component/UI/Common/SliderPanel.cs                                                                   |    2 
 Main/System/Guild/GuildBossManager.cs                                                                     |    2 
 Main/Core/NetworkPackage/ServerPack/HA9_Function/HA925_tagSCQunyingPlayerInfo.cs                          |   23 
 Main/System/HappyXB/HeroCallWin.cs                                                                        |    2 
 Main/System/HeroDebut/HeroDebutCallChangeCell.cs.meta                                                     |   11 
 Main/System/HeroUI/HeroBestWin.cs                                                                         |   19 
 Main/System/DayMission/WeekBattlePassWin.cs                                                               |    2 
 Main/System/DailySpecials/DailySpecialsWeekGiftCell.cs                                                    |    2 
 Main/System/HeroDebut/HeroDebutSkinAwardCell.cs                                                           |   18 
 Main/System/Main/HomeGridLayoutCell.cs.meta                                                               |   11 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA21_tagSCActHeroAppearInfo.cs.meta                 |   11 
 Main/System/OSActivity/OSRankBeautyMMAwardCell.cs                                                         |   12 
 Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA01_tagCSActHeroAppearStarHeroSelect.cs            |   20 
 Main/System/OtherPlayerDetail/BuffInfoCell.cs.meta                                                        |   11 
 Main/Config/PartialConfigs/ActHeroAppearConfig.cs                                                         |   18 
 Main/System/OSActivity/OSRankHeroTrainGiftCell.cs                                                         |    8 
 Main/System/HappyXB/HeroCallXYFinishWin.cs                                                                |   23 
 Main/System/GeneralConfig/DayRemind.cs                                                                    |    8 
 Main/System/OSActivity/OSActivityBaseWin.cs                                                               |   41 
 Main/System/Qunying/QYStoreWin.cs.meta                                                                    |   11 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA21_tagSCActHeroAppearInfo.cs                      |   25 
 Main/System/HeroDebut/HeroDebutCallRateHeroCell.cs                                                        |   28 
 Main/System/Qunying/QunyingManager.cs                                                                     |  448 +
 Main/System/TimeRush/TimeRushWin.cs                                                                       |    4 
 Main/System/Message/RichText.cs                                                                           |   13 
 Main/System/PhantasmPavilion/PhantasmPavilionFaceWin.cs                                                   |   19 
 Main/System/HeroDebut/HeroDebutCheckInWin.cs                                                              |   82 
 Main/System/SmallFunc/SmallFuncManager.cs                                                                 |  129 
 Main/Utility/EnumHelper.cs                                                                                |   35 
 Main/System/SmallFunc/GoodReviewWin.cs                                                                    |   84 
 Main/System/OSActivity/OSRankMinggeGiftWin.cs                                                             |   16 
 Main/Config/PartialConfigs/HeroSkinAttrConfig.cs                                                          |   25 
 Main/System/PhantasmPavilion/PhantasmPavilionFaceHandler.cs                                               |   20 
 Main/Config/PartialConfigs/ActBillboardAwardConfig.cs.meta                                                |   11 
 Main/System/Gubao/GubaoSuiteListWin.cs                                                                    |    1 
 Main/System/LineupRecommend/LineupRecommendItem.cs                                                        |   55 
 Main/System/NewBieGuidance/NewBieCenter.cs                                                                |    8 
 Main/System/HeroUI/HeroSkinRoleCell.cs.meta                                                               |   11 
 Main/System/OSActivity/OSRankHeroCallGiftCell.cs                                                          |   51 
 Main/Utility/TimeUtility.cs                                                                               |   61 
 Main/System/Qunying/QYAchievementCell.cs.meta                                                             |   11 
 Main/System/HeroDebut/HeroDebutCallRateHeroWin.cs.meta                                                    |   11 
 Main/System/HeroDebut/HeroDebutStarUpWin.cs.meta                                                          |   11 
 Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA103_tagMCOpenServerDay.cs                                   |    2 
 Main/System/BoneField/BoneFieldManager.cs                                                                 |    4 
 Main/System/FirstCharge/FirstChargeWin.cs                                                                 |    6 
 Main/System/BoneField/AdsCell.cs                                                                          |    1 
 Main/System/UIBase/UIJumpManager.cs                                                                       |   63 
 Main/System/HeroDebut/HeroDebutCallRateItem.cs.meta                                                       |   11 
 Main/Config/Configs/StoreConfig.cs                                                                        |   19 
 Main/System/Qunying/QYFighterCell.cs                                                                      |  194 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HA0_Sys/DTCA009_tagSCGameRecInfo.cs                           |    2 
 Main/Config/PartialConfigs/ActHeroAppearStarConfig.cs                                                     |   85 
 Main/System/OSActivity/OSRankAwardBaseWin.cs                                                              |   56 
 Main/System/SmallFunc/SmallFuncManager.cs.meta                                                            |   11 
 Main/System/HeroDebut/BubbleFloat.cs                                                                      |   76 
 Main/System/HeroUI/HeroSkinCell.cs.meta                                                                   |   11 
 Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA106_tagMCCoinToGoldReport.cs.meta                           |   11 
 Main/System/PhantasmPavilion/PhantasmPavilionUnlockButton.cs                                              |    9 
 Main/System/InternalAffairs/GoldRushAutoWin.cs                                                            |    2 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA925_tagSCQunyingPlayerInfo.cs.meta           |   11 
 Main/System/HeroDebut/HeroDebutCallBubbleCell.cs.meta                                                     |   11 
 Main/System/OfficialRank/OfficialTitleCell.cs                                                             |   28 
 Main/Core/NetworkPackage/ServerPack/HA3_Function/HA30C_tagMCPlayerRewardGetRecord.cs                      |   19 
 Main/Utility/UIHelper.cs                                                                                  |   45 
 Main/Config/PartialConfigs/HeroSkinAttrConfig.cs.meta                                                     |   11 
 Main/System/HeroDebut/HeroDebutGiftCell.cs.meta                                                           |   11 
 Main/Config/Configs/ActHeroAppearArtConfig.cs.meta                                                        |   11 
 Main/System/HeroDebut/HeroDebutCallWin.cs.meta                                                            |   11 
 Main/System/OSActivity/OSRankAwardBaseCell.cs                                                             |   63 
 Main/System/OSActivity/OSRankBeautyMMGiftCell.cs.meta                                                     |   11 
 Main/System/Guild/GuildBaseWin.cs                                                                         |    2 
 Main/System/OSActivity/OSHeroTrainBaseWin.cs.meta                                                         |   11 
 Main/System/HeroUI/HeroCollectionLvUpWin.cs                                                               |    7 
 Main/Config/Configs/PopWinOrderConfig.cs.meta                                                             |   11 
 Main/System/Store/SkinStoreLineCell.cs                                                                    |   28 
 Main/System/Invest/InvestModel.cs                                                                         |   48 
 Main/Component/UI/Common/PopupWindowsProcessor.cs                                                         |   31 
 Main/System/OSActivity/OSRankBeautyMMGiftCell.cs                                                          |   11 
 Main/System/PlayerProfile/ChangeLanguageWin.cs                                                            |   77 
 Main/System/UIBase/OneLevelWin.cs                                                                         |    1 
 Main/System/OSActivity/OSRankMinggeAwardCell.cs                                                           |   10 
 Main/System/Qunying/QYAchievementWin.cs                                                                   |   62 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA20_tagSCActSignPlayerInfo.cs            |   14 
 Main/System/OSActivity/OSRankTipWin.cs                                                                    |   98 
 Main/System/OSActivity/OSRankMinggeAwardCell.cs.meta                                                      |   11 
 Main/Config/Configs/ChatBubbleBoxConfig.cs                                                                |    5 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA22_tagSCActHeroAppearPlayerInfo.cs      |   14 
 Main/System/OSActivity/OSRankBeautyMMWin.cs                                                               |    8 
 Main/Config/Configs/OrderInfoConfig.cs                                                                    |    8 
 Main/System/BillboardRank/RankModel.cs                                                                    |   41 
 Main/System/ItemTip/ItemTipWayWin.cs                                                                      |    9 
 Main/System/Tip/ConfirmCancel.cs                                                                          |    4 
 Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB236_tagCSHeroSkinOP.cs.meta                         |   11 
 Main/Core/NetworkPackage/ServerPack/HB1_Role/HB122_tagSCHeroInfo.cs                                       |   32 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA124_tagMCPlayerInfo.cs.meta                       |   11 
 Main/System/BeautyMM/BeautyMMUpgradeWin.cs                                                                |   13 
 Main/System/Store/SkinStoreWin.cs.meta                                                                    |   11 
 Main/System/OSActivity/OSHeroTrainBaseWin.cs                                                              |   14 
 Main/System/HeroDebut/HeroDebutCallButton.cs                                                              |   95 
 Main/System/InternalAffairs/GoldRushRefreshWin.cs                                                         |    3 
 Main/System/Mail/MailInfoWin.cs                                                                           |    4 
 Main/System/Qunying/QYWin.cs.meta                                                                         |   11 
 Main/System/OSActivity/OSBeautyMMBaseWin.cs.meta                                                          |   11 
 Main/System/HeroDebut/HeroDebutStarUpPaidItemCell.cs                                                      |   17 
 Main/System/HeroDebut/HeroDebutRankCell.cs                                                                |   76 
 Main/System/HeroDebut/HeroDebutSkinWin.cs.meta                                                            |   11 
 Main/System/Scroll/ScrollerController.cs                                                                  |    6 
 Main/System/HeroDebut/HeroDebutCallHistoryWin.cs                                                          |   57 
 Main/System/HeroUI/HeroListWin.cs                                                                         |    2 
 Main/System/HeroDebut/HeroDebutRankCell.cs.meta                                                           |   11 
 Main/Config/ConfigManager.cs                                                                              |  118 
 Main/Config/PartialConfigs/ActHeroAppearStarConfig.cs.meta                                                |   11 
 Main/System/CustomizedGift/CustomizedGiftModel.cs                                                         |   10 
 Main/System/FirstCharge/HeroShowLHWin.cs                                                                  |    4 
 Main/System/HeroUI/HeroTrainBaseWin.cs                                                                    |   95 
 Main/System/HeroDebut/HeroDebutCallResultWin.cs                                                           |  370 +
 Main/Config/Configs/ActHeroAppearStarConfig.cs.meta                                                       |   11 
 Main/Config/Configs/HeroSkinAttrConfig.cs                                                                 |  137 
 Main/System/GeneralConfig/GeneralDefine.cs                                                                |   25 
 Main/Core/NetworkPackage/ServerPack/HA9_Function/HA924_tagSCQunyingMatchList.cs.meta                      |   11 
 Main/System/HeroDebut/HeroDebutStarUpCell.cs.meta                                                         |   11 
 Main/System/HeroDebut/BubbleFloat.cs.meta                                                                 |   11 
 Main/System/PhantasmPavilion/PhantasmPavilionChatBoxHandler.cs                                            |    5 
 Main/System/PhantasmPavilion/AvatarCell.cs                                                                |    2 
 Main/Core/NetworkPackage/ServerPack/HA9_Function/HA924_tagSCQunyingMatchList.cs                           |   51 
 Main/System/HeroDebut/GeneralActInfoManager.cs                                                            |   69 
 Main/Config/Configs/HeroQualityConfig.cs                                                                  |   11 
 Main/System/HappyXB/HeroCallXYFinishWin.cs.meta                                                           |   11 
 Main/System/Qunying/QYBattleFailWin.cs                                                                    |   99 
 Main/System/HeroDebut/HeroDebutCallButton.cs.meta                                                         |   11 
 Main/System/DailySpecials/DailySpecialsDayGiftCell.cs                                                     |    2 
 Main/System/DailySpecials/DailySpecialsWin.cs                                                             |    3 
 Main/Core/NetworkPackage/ServerPack/HA3_Function/HA30C_tagMCPlayerRewardGetRecord.cs.meta                 |   11 
 Main/System/InternalAffairs/GoldRushAutoBuyWin.cs                                                         |    2 
 Main/System/PhantasmPavilion/PhantasmPavilionInfoCell.cs                                                  |   11 
 Main/System/Qunying/QYStoreWin.cs                                                                         |   73 
 Main/Config/Configs/PopWinOrderConfig.cs                                                                  |   44 
 Main/System/Recharge/ExpSecretCollectionWin.cs                                                            |    2 
 Main/System/OSActivity/OSRankGiftBaseCell.cs                                                              |  176 
 Main/System/HeroDebut/HeroDebutGiftCell.cs                                                                |  165 
 Main/System/Qunying/QYFighterCell.cs.meta                                                                 |   11 
 Main/System/Qunying/QYAchievementCell.cs                                                                  |   76 
 Main/System/Qunying/QYBattleWin.cs                                                                        |  306 +
 Main/System/HeroDebut/HeroDebutCallRateCell.cs.meta                                                       |   11 
 Main/System/HappyXB/HeroCallResultWin.cs                                                                  |   48 
 Main/System/Recharge/RechargeWin.cs                                                                       |    4 
 Main/System/HeroDebut/HeroDebutCallChangeItem.cs.meta                                                     |   11 
 Main/System/HeroDebut/HeroDebutCallRateWin.cs.meta                                                        |   11 
 Main/System/BeautyMM/BeautyMMCell.cs                                                                      |    1 
 Main/System/Main/HeroFightingCardCell.cs                                                                  |   86 
 Main/System/HeroDebut/HeroDebutCheckInWin.cs.meta                                                         |   11 
 Main/System/OSActivity/OSRankBaseWin.cs.meta                                                              |   11 
 Main/System/Battle/UIComp/BattleHeroInfoBar.cs                                                            |   19 
 Main/System/OSActivity/OSRankBeautyMMGiftWin.cs                                                           |   19 
 Main/System/HeroUI/HeroDeleteWin.cs                                                                       |   67 
 Main/System/OSActivity/OSMinggeBaseWin.cs                                                                 |   14 
 Main/System/HappyXB/HeroCallHopeWin.cs                                                                    |   23 
 Main/System/Hero/HeroInfo.Skin.cs                                                                         |   54 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HA3_Function/DTCA30C_tagMCPlayerRewardGetRecord.cs            |   13 
 Main/System/HeroUI/HeroTrainBaseWin.cs.meta                                                               |   11 
 Main/System/Login/ServerBehaviour.cs                                                                      |    2 
 Main/System/OSActivity/OSRankMinggeAwardWin.cs.meta                                                       |   11 
 Main/System/Store/SkinStoreCell.cs                                                                        |   72 
 Main/System/HeroDebut/HeroDebutManager.cs.meta                                                            |   11 
 Main/System/HeroDebut/HeroDebutShopCell.cs                                                                |  134 
 Main/System/Qunying/QYRankAwardCell.cs.meta                                                               |   11 
 Main/System/HeroUI/HeroSkinChooseWin.cs                                                                   |   84 
 Main/System/HeroUI/HeroSkinWin.cs                                                                         |  354 +
 Main/Config/Configs/HeroSkinConfig.cs                                                                     |   88 
 Main/System/HeroDebut/HeroDebutRankTop3Cell.cs                                                            |   47 
 Main/System/HeroDebut/OperationHeroAppearInfo.cs                                                          |   21 
 Main/System/HeroDebut/HeroDebutRankWin.cs                                                                 |  175 
 Main/System/OtherPlayerDetail/BuffInfoCell.cs                                                             |   33 
 Main/Config/Configs/PlayerFacePicConfig.cs                                                                |    5 
 Main/System/HeroDebut/HeroDebutCallChangeWin.cs.meta                                                      |   11 
 Main/System/Qunying/QYBattleVictoryWin.cs.meta                                                            |   11 
 Main/System/OpenServerActivity/OpenServerActivityCenter.cs                                                |   17 
 Main/System/HeroDebut/HeroDebutPopWin.cs.meta                                                             |   11 
 Main/System/OSActivity/OSRankBeautyMMAwardWin.cs.meta                                                     |   11 
 Main/System/OSActivity/OSRankHeroTrainWin.cs.meta                                                         |   11 
 Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA106_tagMCCoinToGoldReport.cs                                |   27 
 Main/System/HeroUI/HeroSkinRoleLineCell.cs                                                                |   23 
 Main/SDK/SDKUtils.cs                                                                                      |  689 +-
 Main/System/Qunying/QYAchievementWin.cs.meta                                                              |   11 
 Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB210_tagCSQunyingMatch.cs.meta                       |   11 
 Main/Core/NetworkPackage/DTCFile/ServerPack/H03_MainCharacter/DTC0320_tagFBEnd.cs                         |    1 
 Main/System/BattlePass/BattlePassCommonWin.cs                                                             |    2 
 Main/System/HeroFates/HeroFatesIHItem.cs                                                                  |    5 
 Main/System/BeautyMM/BeautyMMManager.cs                                                                   |   18 
 Main/Config/PartialConfigs/ActHeroAppearConfig.cs.meta                                                    |   11 
 Main/System/Main/HomeGridLayout.cs.meta                                                                   |   11 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA22_tagSCActHeroAppearPlayerInfo.cs.meta |   11 
 Main/System/HeroDebut/HeroDebutSkinTabCell.cs.meta                                                        |   11 
 Main/System/Main/RightFuncInHome.cs                                                                       |    7 
 Main/System/HeroDebut/HeroDebutCheckInCell.cs                                                             |   60 
 Main/System/Store/StoreCell.cs                                                                            |    9 
 Main/System/BeautyMM/BeautyMMListWin.cs                                                                   |   27 
 Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB210_tagCSQunyingMatch.cs                            |   18 
 Main/System/Qunying/QYBattleFailWin.cs.meta                                                               |   11 
 Main/System/HeroDebut/HeroDebutCallRateHeroCell.cs.meta                                                   |   11 
 Main/System/Qunying/QYPlayerTop3Cell.cs                                                                   |   52 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA106_tagMCCoinToGoldReport.cs                      |   12 
 Main/System/HeroDebut/HeroDebutShopWin.cs                                                                 |   80 
 Main/System/Qunying/QYNoteCell.cs.meta                                                                    |   11 
 Main/System/HappyXB/HappyXBModel.cs                                                                       |   84 
 Main/System/OSActivity/OSRankBeautyMMAwardCell.cs.meta                                                    |   11 
 Main/System/HeroDebut/GeneralActInfoManager.cs.meta                                                       |   11 
 Main/Config/Configs/ActSignAwardConfig.cs.meta                                                            |   11 
 Main/System/Language/Language.cs                                                                          |  100 
 Main/Config/Configs/ActHeroAppearConfig.cs                                                                |  104 
 Main/System/HeroUI/HeroSkinRoleLineCell.cs.meta                                                           |   11 
 Main/System/PhantasmPavilion/PhantasmPavilionManager.cs                                                   |  146 
 Main/System/Battle/PreviewBattleWin.cs                                                                    |   34 
 Main/System/HeroDebut/HeroDebutCallRateWin.cs                                                             |   83 
 Main/Config/Configs/ActHeroAppearArtConfig.cs                                                             |  107 
 Main/System/OSActivity/OSRankHeroTrainAwardCell.cs                                                        |   10 
 Main/System/TimingGift/TimingGiftWin.cs                                                                   |    2 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA925_tagSCQunyingPlayerInfo.cs                |   12 
 Main/System/HeroDebut/HeroDebutCheckInCell.cs.meta                                                        |   11 
 Main/System/Main/FightPowerManager.cs                                                                     |   15 
 Main/System/BoneField/BoneFieldWin.cs                                                                     |    1 
 Main/System/KnapSack/BackpackData.cs                                                                      |    7 
 Main/Core/NetworkPackage/GameNetSystem.cs                                                                 |    4 
 Main/System/Chat/ChatTabCell.cs                                                                           |    2 
 Main/System/HeroUI/HeroCollectionWin.cs                                                                   |   36 
 Main/System/OSActivity/OSHeroCallBaseWin.cs                                                               |   11 
 Main/System/OSActivity/OSRankMinggeWin.cs                                                                 |   20 
 Main/System/Qunying.meta                                                                                  |    8 
 Main/System/Login/LoginManager.cs                                                                         |    2 
 Main/Core/NetworkPackage/ServerPack/HA8_Item/HA801_tagMCGiveAwardInfo.cs                                  |    2 
 Main/System/Battle/Sound/BattleSoundManager.cs                                                            |   37 
 Main/System/Message/RichTextMgr.cs                                                                        |   15 
 Main/System/Chat/ChatManager.cs                                                                           |   83 
 Main/System/HeroDebut/HeroDebutCallResultCell.cs.meta                                                     |   11 
 Main/System/OSActivity/OSRankMinggeWin.cs.meta                                                            |   11 
 Main/System/HeroDebut/HeroDebutShopCell.cs.meta                                                           |   11 
 Main/System/Arena/ArenaChallengeCell.cs                                                                   |    2 
 Main/System/OSActivity/OSRankGiftBaseCell.cs.meta                                                         |   11 
 Main/System/HeroUI/HeroBestBaseWin.cs                                                                     |   74 
 Main/System/OSActivity/OSRankTipWin.cs.meta                                                               |   11 
 Main/System/PlayerProfile/ChangeLanguageWin.cs.meta                                                       |   11 
 Main/System/Chat/ChatWin.cs                                                                               |   31 
 Main/Utility/OperationLogCollect.cs                                                                       |  238 
 Main/System/PhantasmPavilion/PhantasmPavilionChatBoxItem.cs                                               |    2 
 Main/System/HeroUI/HeroUIManager.Collect.cs                                                               |  224 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA924_tagSCQunyingMatchList.cs.meta            |   11 
 Main/System/SmallFunc.meta                                                                                |    8 
 Main/System/HeroDebut.meta                                                                                |    8 
 Main/System/OSActivity/OSRankBeautyMMGiftWin.cs.meta                                                      |   11 
 Main/Config/Configs/ActBillboardAwardConfig.cs.meta                                                       |   11 
 Main/System/ViewNPC/ViewNPCManager.cs                                                                     |   12 
 Main/Config/Configs/ActSignAwardConfig.cs                                                                 |   47 
 Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA02_tagCSActHeroAppearCallHeroSelect.cs.meta       |   11 
 Main/System/Equip/BlessLVADWin.cs                                                                         |    1 
 Main/System/HeroDebut/HeroDebutCallWin.cs                                                                 |  398 +
 Main/Config/Configs/GubaoResonanceConfig.cs                                                               |    5 
 Main/System/Qunying/QYWin.cs                                                                              |  270 
 Main/System/Recharge/RechargeDJQCell.cs                                                                   |    2 
 Main/System/ViewNPC/ViewBuffManager.cs                                                                    |   35 
 Main/Config/Configs/ActHeroAppearSkinArtConfig.cs.meta                                                    |   11 
 Main/System/Store/StoreBaseWin.cs                                                                         |    4 
 Main/System/PhantasmPavilion/PhantasmPavilionTitleHandler.cs                                              |    5 
 Main/System/Chat/ChatPlayerMineCell.cs                                                                    |    6 
 Main/System/KnapSack/Logic/CommonGetItemWin.cs                                                            |    3 
 Main/System/OSActivity/OSRankBeautyMMWin.cs.meta                                                          |   11 
 Main/System/Redpoint/MainRedDot.cs                                                                        |    8 
 Main/Component/UI/Common/FuncOpen.cs                                                                      |    7 
 Main/System/Qunying/QunyingManager.cs.meta                                                                |   11 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HA3_Function/DTCA30C_tagMCPlayerRewardGetRecord.cs.meta       |   11 
 Main/System/Battle/BattleField/QYBattleField.cs                                                           |  106 
 Main/Config/Configs/ActHeroAppearStarConfig.cs                                                            |   56 
 Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA01_tagCSActHeroAppearStarHeroSelect.cs.meta       |   11 
 Main/System/Mail/MailCell.cs                                                                              |    7 
 Main/System/TimeRush/TimeRushGiftCell.cs                                                                  |   40 
 Main/Config/PartialConfigs/HeroConfig.cs                                                                  |   29 
 Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA124_tagMCPlayerInfo.cs.meta                                 |   11 
 Main/System/BillboardRank/PlayerRankCell.cs                                                               |   12 
 Main/System/TimeRush/TimeRushTaskCell.cs                                                                  |  139 
 Main/System/Tip/ItemsConfirmCell.cs                                                                       |   14 
 Main/System/OSActivity/OSRankHeroTrainWin.cs                                                              |   20 
 Main/System/HeroDebut/OperationHeroAppearInfo.cs.meta                                                     |   11 
 Main/System/Battle/BattleField/PriviewBattleField.cs                                                      |   75 
 Main/System/HeroDebut/HeroDebutRankAwardCell.cs                                                           |   45 
 Main/System/HeroDebut/HeroDebutCallBubbleCell.cs                                                          |   23 
 Main/System/HeroDebut/HeroDebutStarUpPaidItemCell.cs.meta                                                 |   11 
 Main/System/HeroDebut/HeroDebutCallRateCell.cs                                                            |   28 
 Main/Config/PartialConfigs/ActSignAwardConfig.cs.meta                                                     |   11 
 Main/System/HeroDebut/HeroDebutShopLineCell.cs                                                            |   30 
 Main/System/HeroUI/HeroSkinWin.cs.meta                                                                    |   11 
 Main/System/Login/LoginWin.cs                                                                             |    1 
 Main/System/Qunying/QYPlayerTop3Cell.cs.meta                                                              |   11 
 Main/System/Store/SkinStoreBuyTipWin.cs                                                                   |   85 
 Main/System/Battle/BattleField/PriviewBattleField.cs.meta                                                 |   11 
 Main/System/BillboardRank/PlayerRankWin.cs                                                                |   13 
 Main/System/HeroDebut/HeroDebutWin.cs.meta                                                                |   11 
 Main/System/OSActivity/OSRankMinggeGiftCell.cs.meta                                                       |   11 
 Main/System/Qunying/QYBattleVictoryWin.cs                                                                 |  141 
 Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA02_tagCSActHeroAppearCallHeroSelect.cs            |   20 
 Main/System/OSActivity/OSMainLevelBaseWin.cs                                                              |    9 
 Main/System/Store/SkinStoreBuyTipWin.cs.meta                                                              |   11 
 Main/System/HeroDebut/HeroDebutCallHistoryOutCell.cs                                                      |   21 
 Main/System/OSActivity/OSBeautyMMBaseWin.cs                                                               |   15 
 Main/System/HeroDebut/HeroDebutStarUpWin.cs                                                               |  121 
 Main/System/Qunying/QYNoteCell.cs                                                                         |   74 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA20_tagSCActSignPlayerInfo.cs.meta       |   11 
 Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA124_tagMCPlayerInfo.cs                                      |   19 
 Main/Config/PartialConfigs/OrderInfoConfig.cs                                                             |    2 
 Main/System/Store/SkinStoreCell.cs.meta                                                                   |   11 
 Main/System/HeroDebut/HeroDebutCallHistoryCell.cs.meta                                                    |   11 
 Main/System/HappyXB/HeroCallHopeAddCell.cs                                                                |   17 
 Main/System/OSActivity/OSRankMinggeGiftWin.cs.meta                                                        |   11 
 Main/System/PhantasmPavilion/PhantasmPavilionWin.cs                                                       |    2 
 Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs                                                      |    9 
 Main/System/HeroDebut/HeroDebutCallRateItem.cs                                                            |  123 
 Main/System/OSActivity/OSRankHeroTrainGiftCell.cs.meta                                                    |   11 
 Main/Config/Configs/HeroSkinAttrConfig.cs.meta                                                            |   11 
 Main/System/ChallengeTab/QunyingTabHandler.cs                                                             |   67 
 Main/System/HeroDebut/HeroDebutPopWin.cs                                                                  |   96 
 Main/System/HeroUI/HeroUIManager.cs                                                                       |  147 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA22_tagSCActHeroAppearPlayerInfo.cs.meta           |   11 
 Main/System/SmallFunc/GoodReviewWin.cs.meta                                                               |   11 
 Main/System/OSActivity/OSRankHeroTrainGiftWin.cs.meta                                                     |   11 
 Main/System/PhantasmPavilion/PhantasmPavilionFacePicItem.cs                                               |    2 
 Main/System/Arena/ArenaRecordCell.cs                                                                      |    2 
 Main/System/BeautyMM/BeautyMMTalentEffectCell.cs                                                          |   13 
 Main/System/OSActivity/OSMinggeBaseWin.cs.meta                                                            |   11 
 Main/System/FuncPreset/FuncPresetManager.cs                                                               |    7 
 Main/System/OSActivity/OSActivityBaseWin.cs.meta                                                          |   11 
 Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB236_tagCSHeroSkinOP.cs                              |   24 
 Main/System/OSActivity/OSRankGiftBaseWin.cs                                                               |   48 
 Main/System/HeroDebut/HeroDebutCallHistoryWin.cs.meta                                                     |   11 
 Main/System/OSActivity/OSRankMinggeAwardWin.cs                                                            |   16 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA22_tagSCActHeroAppearPlayerInfo.cs                |   23 
 Main/Config/Configs/ActHeroAppearSkinArtConfig.cs                                                         |   56 
 Main/System/HeroDebut/HeroDebutCallChangeCell.cs                                                          |   33 
 Main/System/Qunying/QYRankAwardWin.cs                                                                     |  140 
 Main/System/OSActivity/OSRankHeroTrainGiftWin.cs                                                          |   16 
 Main/System/Qunying/QYBattleWin.cs.meta                                                                   |   11 
 Main/System/HeroDebut/HeroDebutSkinTabCell.cs                                                             |   28 
 Main/Core/GameEngine/Launch/ConfigInitTask.cs                                                             |    6 
 Main/System/HeroDebut/HeroDebutSkinAwardCell.cs.meta                                                      |   11 
 Main/Manager/UIManager.cs                                                                                 |    5 
 Main/System/HeroDebut/HeroDebutWin.cs                                                                     |  115 
 Main/System/Battle/PreviewBattleWin.cs.meta                                                               |   11 
 Main/System/Store/HeroSkinGiftWin.cs.meta                                                                 |   11 
 Main/System/BillboardRank/GuildRankWin.cs                                                                 |   27 
 Main/System/PhantasmPavilion/PhantasmPavilionModelWin.cs                                                  |   18 
 Main/System/PhantasmPavilion/PhantasmPavilionManager.LoadConfig.cs                                        |    8 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA124_tagMCPlayerInfo.cs                            |   12 
 Main/Core/NetworkPackage/ServerPack/HA9_Function/HA925_tagSCQunyingPlayerInfo.cs.meta                     |   11 
 Main/System/Qunying/QYRankAwardWin.cs.meta                                                                |   11 
 Main/System/HeroDebut/HeroDebutCallRateHeroWin.cs                                                         |  119 
 Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA20_tagSCActSignPlayerInfo.cs                      |   21 
 Main/System/Login/ServerListParser.cs                                                                     |    7 
 Main/Core/NetworkPackage/DTCFile/ServerPack/H01_System/DTC0102_tagCDBPlayer.cs                            |    2 
 Main/Common/EventName.cs                                                                                  |    5 
 Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA924_tagSCQunyingMatchList.cs                 |   12 
 Main/System/Main/HomeGridLayoutCell.cs                                                                    |   42 
 Main/System/Battle/BattleField/BattleField.cs                                                             |    3 
 Main/System/Message/RichTableEvent.cs                                                                     |    2 
 Main/System/Main/HomeWin.cs                                                                               |   67 
 Main/Main.cs                                                                                              |    5 
 Main/System/ItemTip/OwnMoneyCell.cs                                                                       |    9 
 Main/System/TimingGift/TimingGiftCtgIdCell.cs                                                             |    2 
 Main/System/Hero/UIHeroController.cs                                                                      |  410 +
 Main/System/Battle/BattleManager.cs                                                                       |    4 
 Main/System/HeroUI/HeroSkinChooseWin.cs.meta                                                              |   11 
 Main/System/TimeRush/TimeRushManager.cs                                                                   |    6 
 Main/System/Chat/ChatPlayerOtherCell.cs                                                                   |    6 
 Main/System/ChallengeTab/QunyingTabHandler.cs.meta                                                        |   11 
 /dev/null                                                                                                 |   11 
 Main/System/PhantasmPavilion/PhantasmPavilionTitleItem.cs                                                 |    9 
 Main/System/Equip/BlessLVWin.cs                                                                           |    2 
 Main/System/PhantasmPavilion/PhantasmPavilionManager.Redpoint.cs                                          |  142 
 Main/System/HeroDebut/HeroDebutShopWin.cs.meta                                                            |   11 
 477 files changed, 16,287 insertions(+), 1,949 deletions(-)

diff --git a/Main/Common/EventName.cs b/Main/Common/EventName.cs
index ca978ab..d4cc0af 100644
--- a/Main/Common/EventName.cs
+++ b/Main/Common/EventName.cs
@@ -20,4 +20,9 @@
 	public const string BATTLE_TIANZI_REFRESH_HP = "BATTLE_TIANZI_REFRESH_HP";//澶╁瓙鑰冮獙 鍒锋柊琛�閲�
 	
 	public const string BATTLE_CLICK_HERO = "BATTLE_CLICK_HERO";//鐐瑰嚮鑻遍泟
+	public const string BATTLE_CLICK_BUFF = "BATTLE_CLICK_BUFF";//鐐瑰嚮Buff
+
+	public const string SOUND_EFFECT_VOLUME_CHANGE = "SOUND_EFFECT_VOLUME_CHANGE";	//闊虫晥澹伴煶澶у皬璋冩暣
+
+	public const string SOUND_EFFECT_MUTE_CHANGE = "SOUND_EFFECT_MUTE_CHANGE";//	闊虫晥闈欓煶璋冩暣
 }
\ No newline at end of file
diff --git a/Main/Component/UI/Common/FuncOpen.cs b/Main/Component/UI/Common/FuncOpen.cs
index d48b4fb..e92c9b8 100644
--- a/Main/Component/UI/Common/FuncOpen.cs
+++ b/Main/Component/UI/Common/FuncOpen.cs
@@ -38,8 +38,10 @@
 
         DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= BeforePlayerDataInitializeEvent;
         DTC0102_tagCDBPlayer.switchAccountEvent -= SwitchAccountEvent;
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin;
         DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += BeforePlayerDataInitializeEvent;
         DTC0102_tagCDBPlayer.switchAccountEvent += SwitchAccountEvent;
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
 
         funcClientLVLimitDict.Clear();
         var jsonConfig = JsonMapper.ToObject(FuncConfigConfig.Get("FuncLevelLimitClient").Numerical1);
@@ -49,6 +51,11 @@
         }
     }
 
+    private void OnBeforePlayerDataInitializeEventOnRelogin()
+    {
+        awardStateDict.Clear();
+    }
+
     private void BeforePlayerDataInitializeEvent()
     {
         for (int i = 0; i < funcArray.Length; i++)
diff --git a/Main/Component/UI/Common/PopupWindowsProcessor.cs b/Main/Component/UI/Common/PopupWindowsProcessor.cs
index 049e3a4..ac50586 100644
--- a/Main/Component/UI/Common/PopupWindowsProcessor.cs
+++ b/Main/Component/UI/Common/PopupWindowsProcessor.cs
@@ -44,7 +44,36 @@
         }
 
         popupWindowQueue.Add(popupWindow);
-        popupWindowQueue.Sort((x, y) => y.isNeedHomeWin.CompareTo(x.isNeedHomeWin));
+        popupWindowQueue.Sort((x, y) =>
+        {
+            // 1. 棣栧厛鎸� isNeedHomeWin 鎺掑簭 (true 鎺掑湪鍓嶉潰)
+            int homeWinCompare = y.isNeedHomeWin.CompareTo(x.isNeedHomeWin);
+            if (homeWinCompare != 0)
+                return homeWinCompare;
+
+            // 2. 鑾峰彇鍚勮嚜鐨� WinOrder (閫氳繃 WinName 鏌ユ壘閰嶇疆琛�)
+            int xOrder = GetWinOrder(x.window);
+            int yOrder = GetWinOrder(y.window);
+            int orderCompare = xOrder.CompareTo(yOrder);
+            if (orderCompare != 0)
+                return orderCompare;
+
+            // 3. WinOrder 鐩稿悓鏃讹紝鎸� ID 鎺掑簭 (ID 灏忕殑鎺掑墠闈�)
+            return x.functionId.CompareTo(y.functionId);
+        });
+    }
+
+    private int GetWinOrder(string winName)
+    {
+        var allConfigs = PopWinOrderConfig.GetValues();
+        foreach (var config in allConfigs)
+        {
+            if (config.WinName == winName)
+            {
+                return config.WinOrder;
+            }
+        }
+        return int.MinValue; 
     }
 
     /// <summary>
diff --git a/Main/Component/UI/Common/SliderPanel.cs b/Main/Component/UI/Common/SliderPanel.cs
index e3548be..caa1814 100644
--- a/Main/Component/UI/Common/SliderPanel.cs
+++ b/Main/Component/UI/Common/SliderPanel.cs
@@ -65,7 +65,7 @@
         maxCount = _maxCount;
         slider.minValue = 0;
         slider.maxValue = _maxCount;
-        slider.value = count;
+        slider.value = _count;
 
         Refresh();
         OnChangeEvent = _OnChangeEvent;
diff --git a/Main/Config/ConfigManager.cs b/Main/Config/ConfigManager.cs
index 364bfb3..049c450 100644
--- a/Main/Config/ConfigManager.cs
+++ b/Main/Config/ConfigManager.cs
@@ -55,7 +55,13 @@
         // 鑷姩鐢熸垚锛氭敹闆嗘墍鏈夐厤缃被鍨�
         // 鑷姩鐢熸垚锛氭敹闆嗘墍鏈夐厤缃被鍨�
         HashSet<Type> configTypes = new HashSet<Type>() {
+            typeof(ActBillboardAwardConfig),
+            typeof(ActHeroAppearArtConfig),
+            typeof(ActHeroAppearConfig),
+            typeof(ActHeroAppearSkinArtConfig),
+            typeof(ActHeroAppearStarConfig),
             typeof(ActLunhuidianTypeConfig),
+            typeof(ActSignAwardConfig),
             typeof(ADAwardConfig),
             typeof(AppointItemConfig),
             typeof(AudioConfig),
@@ -114,6 +120,7 @@
             typeof(HeroQualityBreakConfig),
             typeof(HeroQualityConfig),
             typeof(HeroQualityLVConfig),
+            typeof(HeroSkinAttrConfig),
             typeof(HeroSkinConfig),
             typeof(HeroTalentConfig),
             typeof(HorseClassConfig),
@@ -143,6 +150,7 @@
             typeof(PlayerFacePicConfig),
             typeof(PlayerLVConfig),
             typeof(PlayerPropertyConfig),
+            typeof(PopWinOrderConfig),
             typeof(PresetUnlockConfig),
             typeof(PriorBundleConfig),
             typeof(RandomNameConfig),
@@ -379,8 +387,20 @@
 
     public override void Release()
     {
+        // 娓呯┖ ActBillboardAwardConfig 瀛楀吀
+        ClearConfigDictionary<ActBillboardAwardConfig>();
+        // 娓呯┖ ActHeroAppearArtConfig 瀛楀吀
+        ClearConfigDictionary<ActHeroAppearArtConfig>();
+        // 娓呯┖ ActHeroAppearConfig 瀛楀吀
+        ClearConfigDictionary<ActHeroAppearConfig>();
+        // 娓呯┖ ActHeroAppearSkinArtConfig 瀛楀吀
+        ClearConfigDictionary<ActHeroAppearSkinArtConfig>();
+        // 娓呯┖ ActHeroAppearStarConfig 瀛楀吀
+        ClearConfigDictionary<ActHeroAppearStarConfig>();
         // 娓呯┖ ActLunhuidianTypeConfig 瀛楀吀
         ClearConfigDictionary<ActLunhuidianTypeConfig>();
+        // 娓呯┖ ActSignAwardConfig 瀛楀吀
+        ClearConfigDictionary<ActSignAwardConfig>();
         // 娓呯┖ ADAwardConfig 瀛楀吀
         ClearConfigDictionary<ADAwardConfig>();
         // 娓呯┖ BattleMapConfig 瀛楀吀
@@ -445,6 +465,8 @@
         ClearConfigDictionary<HeroLineupHaloConfig>();
         // 娓呯┖ HeroQualityLVConfig 瀛楀吀
         ClearConfigDictionary<HeroQualityLVConfig>();
+        // 娓呯┖ HeroSkinAttrConfig 瀛楀吀
+        ClearConfigDictionary<HeroSkinAttrConfig>();
         // 娓呯┖ HorseClassConfig 瀛楀吀
         ClearConfigDictionary<HorseClassConfig>();
         // 娓呯┖ HorseSkinConfig 瀛楀吀
@@ -485,6 +507,8 @@
         ClearConfigDictionary<PlayerAttrConfig>();
         // 娓呯┖ PlayerFaceConfig 瀛楀吀
         ClearConfigDictionary<PlayerFaceConfig>();
+        // 娓呯┖ PopWinOrderConfig 瀛楀吀
+        ClearConfigDictionary<PopWinOrderConfig>();
         // 娓呯┖ PresetUnlockConfig 瀛楀吀
         ClearConfigDictionary<PresetUnlockConfig>();
         // 娓呯┖ PriorBundleConfig 瀛楀吀
@@ -532,10 +556,104 @@
     /// </summary>
     private async UniTask<string[]> LoadConfigTextAsync(Type configType)
     {
+<<<<<<< HEAD
         string configName = configType.Name;
         if (configName.EndsWith("Config"))
             configName = configName.Substring(0, configName.Length - 6);
         return await ResManager.Instance.LoadConfigAsync(configName);
+=======
+        // 鑾峰彇 Editor Assembly
+        var editorAsm = System.AppDomain.CurrentDomain.GetAssemblies()
+            .FirstOrDefault(a => a.FullName.Contains("Editor"));
+
+        if (editorAsm == null)
+        {
+            Debug.LogError("[鑷] 鏈壘鍒� Editor Assembly锛屾棤娉曡嚜妫�銆�");
+            return;
+        }
+
+        // 鍙嶅皠鑾峰彇 ConfigGenerater 绫诲瀷
+        var configGeneraterType = editorAsm.GetType("ConfigGenerater");
+        if (configGeneraterType == null)
+        {
+            Debug.LogError("[鑷] 鏈壘鍒� ConfigGenerater 绫诲瀷銆�");
+            return;
+        }
+
+        // 璋冪敤 GetAllConfigClasses 闈欐�佹柟娉�
+        var getAllConfigClassesMethod = configGeneraterType.GetMethod("GetAllConfigClasses", BindingFlags.Public | BindingFlags.Static);
+        var allConfigClasses = getAllConfigClassesMethod?.Invoke(null, null) as List<string>;
+        if (allConfigClasses == null)
+        {
+            Debug.LogError("[鑷] 鑾峰彇鍏ㄩ儴閰嶇疆绫诲け璐ャ��");
+            return;
+        }
+
+        // 鑾峰彇 ExcludeClassList 瀛楁
+        var excludeField = configGeneraterType.GetField("ExcludeClassList", BindingFlags.Public | BindingFlags.Static);
+        var excludeClassList = excludeField?.GetValue(null) as List<string> ?? new List<string>();
+
+        // 鎺掗櫎涓嶉渶瑕佺殑绫�
+        var checkClasses = allConfigClasses.Where(c => !excludeClassList.Contains(c)).ToList();
+
+        List<string> fastName = new List<string>();
+
+        foreach (var className in checkClasses)
+        {
+            // 杩欓噷涔熻鐢� Editor Assembly 鑾峰彇绫诲瀷
+            var configType = editorAsm.GetType(className) ?? Type.GetType(className);
+            if (configType == null)
+            {
+                Debug.LogWarning($"[鑷] 鏈壘鍒扮被鍨�: {className}");
+                continue;
+            }
+
+            var sw = System.Diagnostics.Stopwatch.StartNew();
+
+            // 鍙嶅皠璋冪敤闈欐�両nit鏂规硶
+            string configName = configType.Name;
+            if (configName.EndsWith("Config"))
+                configName = configName.Substring(0, configName.Length - 6);
+
+            string[] texts = ResManager.Instance.LoadConfig(configName);
+            if (texts != null)
+            {
+                string[] lines = texts;
+                var methodInfo = configType.GetMethod("Init", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);
+                if (methodInfo != null)
+                {
+                    methodInfo.Invoke(null, new object[] { lines });
+                }
+            }
+
+            sw.Stop();
+
+            if (sw.ElapsedMilliseconds >= 500)
+            {
+                Debug.LogError($"[鑷] 鍔犺浇閰嶇疆 {configType.Name} 鑰楁椂杈冮暱: {sw.ElapsedMilliseconds} ms");
+            }
+            else if (sw.ElapsedMilliseconds <= 5)
+            {
+                fastName.Add(configType.Name);
+            }
+            Debug.Log($"[鑷] 鍔犺浇閰嶇疆: {configType.Name} 鐢ㄦ椂: {sw.ElapsedMilliseconds} ms");
+        }
+
+        // 閲婃斁鎵�鏈夊凡鍔犺浇鐨勯厤缃�
+        foreach (var className in checkClasses)
+        {
+            var configType = editorAsm.GetType(className) ?? Type.GetType(className);
+            if (configType == null) continue;
+            var methodInfo = configType.GetMethod("ForceRelease", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);
+            if (methodInfo != null)
+            {
+                methodInfo.Invoke(null, null);
+            }
+        }
+
+        System.IO.File.WriteAllText(Application.dataPath + "/fastConfig.txt", string.Join("\n", fastName));
+        Debug.Log($"[鑷] fastConfig.txt 鐢熸垚瀹屾瘯锛屽揩閫熻〃鏈夛細{string.Join(", ", fastName)}");
+>>>>>>> origin/master
     }
 
     /// <summary>
diff --git a/Main/Config/Configs/ActBillboardAwardConfig.cs b/Main/Config/Configs/ActBillboardAwardConfig.cs
new file mode 100644
index 0000000..a72974a
--- /dev/null
+++ b/Main/Config/Configs/ActBillboardAwardConfig.cs
@@ -0,0 +1,53 @@
+锘�//--------------------------------------------------------
+//    [Author]:           YYL
+//    [  Date ]:           2026骞�3鏈�6鏃�
+//--------------------------------------------------------
+
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using LitJson;
+
+public partial class ActBillboardAwardConfig : ConfigBase<int, ActBillboardAwardConfig>
+{
+    static ActBillboardAwardConfig()
+    {
+        // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
+        visit = true; 
+    }
+
+    public int ID;
+	public int TemplateID;
+	public int RankA;
+	public int RankB;
+	public float NeedValue;
+	public int[][] AwardItemList;
+
+    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 RankA); 
+
+			int.TryParse(tables[3],out RankB); 
+
+			float.TryParse(tables[4],out NeedValue); 
+
+			AwardItemList = JsonMapper.ToObject<int[][]>(tables[5].Replace("(", "[").Replace(")", "]")); 
+        }
+        catch (Exception exception)
+        {
+            Debug.LogError(exception);
+        }
+    }
+}
diff --git a/Main/Config/Configs/ActBillboardAwardConfig.cs.meta b/Main/Config/Configs/ActBillboardAwardConfig.cs.meta
new file mode 100644
index 0000000..52997c1
--- /dev/null
+++ b/Main/Config/Configs/ActBillboardAwardConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9bd0535e10f3bc74bb3ec887f2cb87d2
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/Configs/ActHeroAppearArtConfig.cs b/Main/Config/Configs/ActHeroAppearArtConfig.cs
new file mode 100644
index 0000000..8e1ef2d
--- /dev/null
+++ b/Main/Config/Configs/ActHeroAppearArtConfig.cs
@@ -0,0 +1,107 @@
+锘�//--------------------------------------------------------
+//    [Author]:           YYL
+//    [  Date ]:           2026骞�3鏈�26鏃�
+//--------------------------------------------------------
+
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using LitJson;
+
+public partial class ActHeroAppearArtConfig : ConfigBase<int, ActHeroAppearArtConfig>
+{
+    static ActHeroAppearArtConfig()
+    {
+        // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
+        visit = true; 
+    }
+
+    public int HeroID;
+	public int[][] HeroNameColor;
+	public int[][] CallBubbleItems;
+	public string EntryBgImage;
+	public string EntryTitleText;
+	public string PopBgImage;
+	public string PopTitleBgImage;
+	public string PopTitleImage;
+	public string PopInfoBgImage;
+	public int PopInfoBgUIEffectId;
+	public string PopInfoText;
+	public int[] PopInfoColor;
+	public string MainBgImage;
+	public string MainTitleImage;
+	public int MainSkinID;
+	public string StarUpHeroImage;
+	public string GiftBgImage;
+	public string GiftHeroImage;
+	public string RankAwardHeroImage;
+	public string CheckInBgImage;
+
+    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 HeroID); 
+
+			HeroNameColor = JsonMapper.ToObject<int[][]>(tables[1].Replace("(", "[").Replace(")", "]")); 
+
+			CallBubbleItems = JsonMapper.ToObject<int[][]>(tables[2].Replace("(", "[").Replace(")", "]")); 
+
+			EntryBgImage = tables[3];
+
+			EntryTitleText = tables[4];
+
+			PopBgImage = tables[5];
+
+			PopTitleBgImage = tables[6];
+
+			PopTitleImage = tables[7];
+
+			PopInfoBgImage = tables[8];
+
+			int.TryParse(tables[9],out PopInfoBgUIEffectId); 
+
+			PopInfoText = tables[10];
+
+			if (tables[11].Contains("["))
+			{
+				PopInfoColor = JsonMapper.ToObject<int[]>(tables[11]);
+			}
+			else
+			{
+				string[] PopInfoColorStringArray = tables[11].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				PopInfoColor = new int[PopInfoColorStringArray.Length];
+				for (int i=0;i<PopInfoColorStringArray.Length;i++)
+				{
+					 int.TryParse(PopInfoColorStringArray[i],out PopInfoColor[i]);
+				}
+			}
+
+			MainBgImage = tables[12];
+
+			MainTitleImage = tables[13];
+
+			int.TryParse(tables[14],out MainSkinID); 
+
+			StarUpHeroImage = tables[15];
+
+			GiftBgImage = tables[16];
+
+			GiftHeroImage = tables[17];
+
+			RankAwardHeroImage = tables[18];
+
+			CheckInBgImage = tables[19];
+        }
+        catch (Exception exception)
+        {
+            Debug.LogError(exception);
+        }
+    }
+}
diff --git a/Main/Config/Configs/ActHeroAppearArtConfig.cs.meta b/Main/Config/Configs/ActHeroAppearArtConfig.cs.meta
new file mode 100644
index 0000000..9ab1682
--- /dev/null
+++ b/Main/Config/Configs/ActHeroAppearArtConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: bde3ad9e23ce4ed4480784d86e068190
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/Configs/ActHeroAppearConfig.cs b/Main/Config/Configs/ActHeroAppearConfig.cs
new file mode 100644
index 0000000..a2d2229
--- /dev/null
+++ b/Main/Config/Configs/ActHeroAppearConfig.cs
@@ -0,0 +1,104 @@
+锘�//--------------------------------------------------------
+//    [Author]:           YYL
+//    [  Date ]:           2026骞�3鏈�9鏃�
+//--------------------------------------------------------
+
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using LitJson;
+
+public partial class ActHeroAppearConfig : ConfigBase<int, ActHeroAppearConfig>
+{
+    static ActHeroAppearConfig()
+    {
+        // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
+        visit = true; 
+    }
+
+    public int CfgID;
+	public int[] ActHeroIDList;
+	public int ActTreasureType;
+	public int StarGiftTempID;
+	public int[] SkinCTGIDList;
+	public int[] GiftCTGIDList;
+	public int GiftShopType;
+	public int ExShopType;
+	public int ExShopCostItemID;
+	public int SignTempID;
+	public int BillTempID;
+
+    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("["))
+			{
+				ActHeroIDList = JsonMapper.ToObject<int[]>(tables[1]);
+			}
+			else
+			{
+				string[] ActHeroIDListStringArray = tables[1].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				ActHeroIDList = new int[ActHeroIDListStringArray.Length];
+				for (int i=0;i<ActHeroIDListStringArray.Length;i++)
+				{
+					 int.TryParse(ActHeroIDListStringArray[i],out ActHeroIDList[i]);
+				}
+			}
+
+			int.TryParse(tables[2],out ActTreasureType); 
+
+			int.TryParse(tables[3],out StarGiftTempID); 
+
+			if (tables[4].Contains("["))
+			{
+				SkinCTGIDList = JsonMapper.ToObject<int[]>(tables[4]);
+			}
+			else
+			{
+				string[] SkinCTGIDListStringArray = tables[4].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				SkinCTGIDList = new int[SkinCTGIDListStringArray.Length];
+				for (int i=0;i<SkinCTGIDListStringArray.Length;i++)
+				{
+					 int.TryParse(SkinCTGIDListStringArray[i],out SkinCTGIDList[i]);
+				}
+			}
+
+			if (tables[5].Contains("["))
+			{
+				GiftCTGIDList = JsonMapper.ToObject<int[]>(tables[5]);
+			}
+			else
+			{
+				string[] GiftCTGIDListStringArray = tables[5].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				GiftCTGIDList = new int[GiftCTGIDListStringArray.Length];
+				for (int i=0;i<GiftCTGIDListStringArray.Length;i++)
+				{
+					 int.TryParse(GiftCTGIDListStringArray[i],out GiftCTGIDList[i]);
+				}
+			}
+
+			int.TryParse(tables[6],out GiftShopType); 
+
+			int.TryParse(tables[7],out ExShopType); 
+
+			int.TryParse(tables[8],out ExShopCostItemID); 
+
+			int.TryParse(tables[9],out SignTempID); 
+
+			int.TryParse(tables[10],out BillTempID); 
+        }
+        catch (Exception exception)
+        {
+            Debug.LogError(exception);
+        }
+    }
+}
diff --git a/Main/Config/Configs/ActHeroAppearConfig.cs.meta b/Main/Config/Configs/ActHeroAppearConfig.cs.meta
new file mode 100644
index 0000000..077a80a
--- /dev/null
+++ b/Main/Config/Configs/ActHeroAppearConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1b5b7653c8be0c24790efdb595f1c96e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/Configs/ActHeroAppearSkinArtConfig.cs b/Main/Config/Configs/ActHeroAppearSkinArtConfig.cs
new file mode 100644
index 0000000..94221ae
--- /dev/null
+++ b/Main/Config/Configs/ActHeroAppearSkinArtConfig.cs
@@ -0,0 +1,56 @@
+锘�//--------------------------------------------------------
+//    [Author]:           YYL
+//    [  Date ]:           2026骞�3鏈�11鏃�
+//--------------------------------------------------------
+
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using LitJson;
+
+public partial class ActHeroAppearSkinArtConfig : ConfigBase<int, ActHeroAppearSkinArtConfig>
+{
+    static ActHeroAppearSkinArtConfig()
+    {
+        // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
+        visit = true; 
+    }
+
+    public int SkinID;
+	public string MainSkinBuyBgImage;
+	public string BGImage;
+	public string HeroNameImage;
+	public string SkinInfoImage;
+	public string AwardBGImage;
+	public string TabInfoImage;
+
+    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 SkinID); 
+
+			MainSkinBuyBgImage = tables[1];
+
+			BGImage = tables[2];
+
+			HeroNameImage = tables[3];
+
+			SkinInfoImage = tables[4];
+
+			AwardBGImage = tables[5];
+
+			TabInfoImage = tables[6];
+        }
+        catch (Exception exception)
+        {
+            Debug.LogError(exception);
+        }
+    }
+}
diff --git a/Main/Config/Configs/ActHeroAppearSkinArtConfig.cs.meta b/Main/Config/Configs/ActHeroAppearSkinArtConfig.cs.meta
new file mode 100644
index 0000000..862a125
--- /dev/null
+++ b/Main/Config/Configs/ActHeroAppearSkinArtConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1eaa4cc2eb8e0c84eb8519d6b09adf67
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/Configs/ActHeroAppearStarConfig.cs b/Main/Config/Configs/ActHeroAppearStarConfig.cs
new file mode 100644
index 0000000..65eb620
--- /dev/null
+++ b/Main/Config/Configs/ActHeroAppearStarConfig.cs
@@ -0,0 +1,56 @@
+锘�//--------------------------------------------------------
+//    [Author]:           YYL
+//    [  Date ]:           2026骞�3鏈�2鏃�
+//--------------------------------------------------------
+
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using LitJson;
+
+public partial class ActHeroAppearStarConfig : ConfigBase<int, ActHeroAppearStarConfig>
+{
+    static ActHeroAppearStarConfig()
+    {
+        // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
+        visit = true; 
+    }
+
+    public int ID;
+	public int StarTempID;
+	public int NeedStar;
+	public int AwardIndex;
+	public int[][] FreeAwardItemList;
+	public int StarGiftCTGID;
+	public string HeroGiftItemInfo;
+
+    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 StarTempID); 
+
+			int.TryParse(tables[2],out NeedStar); 
+
+			int.TryParse(tables[3],out AwardIndex); 
+
+			FreeAwardItemList = JsonMapper.ToObject<int[][]>(tables[4].Replace("(", "[").Replace(")", "]")); 
+
+			int.TryParse(tables[5],out StarGiftCTGID); 
+
+			HeroGiftItemInfo = tables[6];
+        }
+        catch (Exception exception)
+        {
+            Debug.LogError(exception);
+        }
+    }
+}
diff --git a/Main/Config/Configs/ActHeroAppearStarConfig.cs.meta b/Main/Config/Configs/ActHeroAppearStarConfig.cs.meta
new file mode 100644
index 0000000..9967d71
--- /dev/null
+++ b/Main/Config/Configs/ActHeroAppearStarConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b4cb144f745e63f4e911c2c4085b36e9
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/Configs/ActSignAwardConfig.cs b/Main/Config/Configs/ActSignAwardConfig.cs
new file mode 100644
index 0000000..6fc6ac4
--- /dev/null
+++ b/Main/Config/Configs/ActSignAwardConfig.cs
@@ -0,0 +1,47 @@
+锘�//--------------------------------------------------------
+//    [Author]:           YYL
+//    [  Date ]:           2026骞�2鏈�28鏃�
+//--------------------------------------------------------
+
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using LitJson;
+
+public partial class ActSignAwardConfig : ConfigBase<int, ActSignAwardConfig>
+{
+    static ActSignAwardConfig()
+    {
+        // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
+        visit = true; 
+    }
+
+    public int ID;
+	public int TemplateID;
+	public int DayNum;
+	public int[][] SignAwardItemList;
+
+    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 DayNum); 
+
+			SignAwardItemList = JsonMapper.ToObject<int[][]>(tables[3].Replace("(", "[").Replace(")", "]")); 
+        }
+        catch (Exception exception)
+        {
+            Debug.LogError(exception);
+        }
+    }
+}
diff --git a/Main/Config/Configs/ActSignAwardConfig.cs.meta b/Main/Config/Configs/ActSignAwardConfig.cs.meta
new file mode 100644
index 0000000..8c61a98
--- /dev/null
+++ b/Main/Config/Configs/ActSignAwardConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8af4002ac6b45894d8f80435a2310fc1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/Configs/ChatBubbleBoxConfig.cs b/Main/Config/Configs/ChatBubbleBoxConfig.cs
index b851bc7..b6b718d 100644
--- a/Main/Config/Configs/ChatBubbleBoxConfig.cs
+++ b/Main/Config/Configs/ChatBubbleBoxConfig.cs
@@ -1,6 +1,6 @@
 锘�//--------------------------------------------------------
 //    [Author]:           YYL
-//    [  Date ]:           2025骞�12鏈�1鏃�
+//    [  Date ]:           2026骞�3鏈�17鏃�
 //--------------------------------------------------------
 
 using System.Collections.Generic;
@@ -35,6 +35,7 @@
 	public int Top;
 	public int[] MyColor;
 	public int[] OtherColor;
+	public int SortIndex;
 
     public override int LoadKey(string _key)
     {
@@ -167,6 +168,8 @@
 					 int.TryParse(OtherColorStringArray[i],out OtherColor[i]);
 				}
 			}
+
+			int.TryParse(tables[19],out SortIndex); 
         }
         catch (Exception exception)
         {
diff --git a/Main/Config/Configs/GubaoResonanceConfig.cs b/Main/Config/Configs/GubaoResonanceConfig.cs
index 16d03c2..14e6863 100644
--- a/Main/Config/Configs/GubaoResonanceConfig.cs
+++ b/Main/Config/Configs/GubaoResonanceConfig.cs
@@ -1,6 +1,6 @@
 锘�//--------------------------------------------------------
 //    [Author]:           YYL
-//    [  Date ]:           2026骞�1鏈�5鏃�
+//    [  Date ]:           2026骞�3鏈�1鏃�
 //--------------------------------------------------------
 
 using System.Collections.Generic;
@@ -19,6 +19,7 @@
     public int ResonanceID;
 	public string ResonanceName;
 	public int[] GubaoIDList;
+	public int sortIndex;
 
     public override int LoadKey(string _key)
     {
@@ -47,6 +48,8 @@
 					 int.TryParse(GubaoIDListStringArray[i],out GubaoIDList[i]);
 				}
 			}
+
+			int.TryParse(tables[3],out sortIndex); 
         }
         catch (Exception exception)
         {
diff --git a/Main/Config/Configs/HeroConfig.cs b/Main/Config/Configs/HeroConfig.cs
index e827a51..4c4ed0c 100644
--- a/Main/Config/Configs/HeroConfig.cs
+++ b/Main/Config/Configs/HeroConfig.cs
@@ -1,6 +1,6 @@
 锘�//--------------------------------------------------------
 //    [Author]:           YYL
-//    [  Date ]:           Tuesday, December 16, 2025
+//    [  Date ]:           2026骞�3鏈�16鏃�
 //--------------------------------------------------------
 
 using System.Collections.Generic;
@@ -40,6 +40,8 @@
 	public int HurtType;
 	public int[] Specialty2;
 	public int[] TalentList;
+	public int OpenCollectionDay;
+	public int IsActLimit;
 
     public override int LoadKey(string _key)
     {
@@ -146,6 +148,10 @@
 					 int.TryParse(TalentListStringArray[i],out TalentList[i]);
 				}
 			}
+
+			int.TryParse(tables[24],out OpenCollectionDay); 
+
+			int.TryParse(tables[25],out IsActLimit); 
         }
         catch (Exception exception)
         {
diff --git a/Main/Config/Configs/HeroQualityConfig.cs b/Main/Config/Configs/HeroQualityConfig.cs
index 4bae93b..ed155dc 100644
--- a/Main/Config/Configs/HeroQualityConfig.cs
+++ b/Main/Config/Configs/HeroQualityConfig.cs
@@ -1,6 +1,6 @@
 锘�//--------------------------------------------------------
 //    [Author]:           YYL
-//    [  Date ]:           Monday, December 8, 2025
+//    [  Date ]:           Friday, March 20, 2026
 //--------------------------------------------------------
 
 using System.Collections.Generic;
@@ -24,6 +24,7 @@
 	public int StarAddPer;
 	public int[] BookActAwardMoney;
 	public int[][] DismissReturnItems;
+	public int[][] TitleReturnItems;
 	public int[] RecommendAwardMoney;
 
     public override int LoadKey(string _key)
@@ -64,13 +65,15 @@
 
 			DismissReturnItems = JsonMapper.ToObject<int[][]>(tables[7].Replace("(", "[").Replace(")", "]")); 
 
-			if (tables[8].Contains("["))
+			TitleReturnItems = JsonMapper.ToObject<int[][]>(tables[8].Replace("(", "[").Replace(")", "]")); 
+
+			if (tables[9].Contains("["))
 			{
-				RecommendAwardMoney = JsonMapper.ToObject<int[]>(tables[8]);
+				RecommendAwardMoney = JsonMapper.ToObject<int[]>(tables[9]);
 			}
 			else
 			{
-				string[] RecommendAwardMoneyStringArray = tables[8].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				string[] RecommendAwardMoneyStringArray = tables[9].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
 				RecommendAwardMoney = new int[RecommendAwardMoneyStringArray.Length];
 				for (int i=0;i<RecommendAwardMoneyStringArray.Length;i++)
 				{
diff --git a/Main/Config/Configs/HeroSkinAttrConfig.cs b/Main/Config/Configs/HeroSkinAttrConfig.cs
new file mode 100644
index 0000000..6b65dea
--- /dev/null
+++ b/Main/Config/Configs/HeroSkinAttrConfig.cs
@@ -0,0 +1,137 @@
+锘�//--------------------------------------------------------
+//    [Author]:           YYL
+//    [  Date ]:           2026骞�3鏈�13鏃�
+//--------------------------------------------------------
+
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using LitJson;
+
+public partial class HeroSkinAttrConfig : ConfigBase<int, HeroSkinAttrConfig>
+{
+    static HeroSkinAttrConfig()
+    {
+        // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
+        visit = true; 
+    }
+
+    public int SkinID;
+	public int Quality;
+	public int NeedItemID;
+	public int StarMax;
+	public int[] WearAttrIDList;
+	public int[] WearAttrValueList;
+	public int[] WearAttrPerStarAddList;
+	public int[] RoleAttrIDList;
+	public int[] RoleAttrValueList;
+	public int[] RoleAttrPerStarAddList;
+
+    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 SkinID); 
+
+			int.TryParse(tables[1],out Quality); 
+
+			int.TryParse(tables[2],out NeedItemID); 
+
+			int.TryParse(tables[3],out StarMax); 
+
+			if (tables[4].Contains("["))
+			{
+				WearAttrIDList = JsonMapper.ToObject<int[]>(tables[4]);
+			}
+			else
+			{
+				string[] WearAttrIDListStringArray = tables[4].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				WearAttrIDList = new int[WearAttrIDListStringArray.Length];
+				for (int i=0;i<WearAttrIDListStringArray.Length;i++)
+				{
+					 int.TryParse(WearAttrIDListStringArray[i],out WearAttrIDList[i]);
+				}
+			}
+
+			if (tables[5].Contains("["))
+			{
+				WearAttrValueList = JsonMapper.ToObject<int[]>(tables[5]);
+			}
+			else
+			{
+				string[] WearAttrValueListStringArray = tables[5].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				WearAttrValueList = new int[WearAttrValueListStringArray.Length];
+				for (int i=0;i<WearAttrValueListStringArray.Length;i++)
+				{
+					 int.TryParse(WearAttrValueListStringArray[i],out WearAttrValueList[i]);
+				}
+			}
+
+			if (tables[6].Contains("["))
+			{
+				WearAttrPerStarAddList = JsonMapper.ToObject<int[]>(tables[6]);
+			}
+			else
+			{
+				string[] WearAttrPerStarAddListStringArray = tables[6].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				WearAttrPerStarAddList = new int[WearAttrPerStarAddListStringArray.Length];
+				for (int i=0;i<WearAttrPerStarAddListStringArray.Length;i++)
+				{
+					 int.TryParse(WearAttrPerStarAddListStringArray[i],out WearAttrPerStarAddList[i]);
+				}
+			}
+
+			if (tables[7].Contains("["))
+			{
+				RoleAttrIDList = JsonMapper.ToObject<int[]>(tables[7]);
+			}
+			else
+			{
+				string[] RoleAttrIDListStringArray = tables[7].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				RoleAttrIDList = new int[RoleAttrIDListStringArray.Length];
+				for (int i=0;i<RoleAttrIDListStringArray.Length;i++)
+				{
+					 int.TryParse(RoleAttrIDListStringArray[i],out RoleAttrIDList[i]);
+				}
+			}
+
+			if (tables[8].Contains("["))
+			{
+				RoleAttrValueList = JsonMapper.ToObject<int[]>(tables[8]);
+			}
+			else
+			{
+				string[] RoleAttrValueListStringArray = tables[8].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				RoleAttrValueList = new int[RoleAttrValueListStringArray.Length];
+				for (int i=0;i<RoleAttrValueListStringArray.Length;i++)
+				{
+					 int.TryParse(RoleAttrValueListStringArray[i],out RoleAttrValueList[i]);
+				}
+			}
+
+			if (tables[9].Contains("["))
+			{
+				RoleAttrPerStarAddList = JsonMapper.ToObject<int[]>(tables[9]);
+			}
+			else
+			{
+				string[] RoleAttrPerStarAddListStringArray = tables[9].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				RoleAttrPerStarAddList = new int[RoleAttrPerStarAddListStringArray.Length];
+				for (int i=0;i<RoleAttrPerStarAddListStringArray.Length;i++)
+				{
+					 int.TryParse(RoleAttrPerStarAddListStringArray[i],out RoleAttrPerStarAddList[i]);
+				}
+			}
+        }
+        catch (Exception exception)
+        {
+            Debug.LogError(exception);
+        }
+    }
+}
diff --git a/Main/Config/Configs/HeroSkinAttrConfig.cs.meta b/Main/Config/Configs/HeroSkinAttrConfig.cs.meta
new file mode 100644
index 0000000..0be7bcf
--- /dev/null
+++ b/Main/Config/Configs/HeroSkinAttrConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 19252a3a70e332947a5a71105bfe19a0
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/Configs/HeroSkinConfig.cs b/Main/Config/Configs/HeroSkinConfig.cs
index fded4ef..0deff42 100644
--- a/Main/Config/Configs/HeroSkinConfig.cs
+++ b/Main/Config/Configs/HeroSkinConfig.cs
@@ -1,6 +1,6 @@
 锘�//--------------------------------------------------------
 //    [Author]:           YYL
-//    [  Date ]:           2026骞�2鏈�13鏃�
+//    [  Date ]:           2026骞�3鏈�13鏃�
 //--------------------------------------------------------
 
 using System.Collections.Generic;
@@ -17,14 +17,14 @@
     }
 
     public int SkinID;
-	public int[] WearAttrIDList;
-	public int[] WearAttrValueList;
-	public int[] AllBatAttrIDList;
-	public int[] AllBatAttrValueList;
+	public string SkinName;
+	public string BG;
+	public int AudioID;
 	public string Tachie;
 	public float[] TachieParam;
 	public string SquareIcon;
 	public string RectangleIcon;
+	public string CardPic;
 	public string SpineRes;
 	public string InitialSkinName;
 	public string ApearMotionName;
@@ -43,71 +43,21 @@
         string[] tables = input.Split('\t');
         int.TryParse(tables[0],out SkinID); 
 
-			if (tables[1].Contains("["))
+			SkinName = tables[1];
+
+			BG = tables[2];
+
+			int.TryParse(tables[3],out AudioID); 
+
+			Tachie = tables[4];
+
+			if (tables[5].Contains("["))
 			{
-				WearAttrIDList = JsonMapper.ToObject<int[]>(tables[1]);
+				TachieParam = JsonMapper.ToObject<float[]>(tables[5]);
 			}
 			else
 			{
-				string[] WearAttrIDListStringArray = tables[1].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
-				WearAttrIDList = new int[WearAttrIDListStringArray.Length];
-				for (int i=0;i<WearAttrIDListStringArray.Length;i++)
-				{
-					 int.TryParse(WearAttrIDListStringArray[i],out WearAttrIDList[i]);
-				}
-			}
-
-			if (tables[2].Contains("["))
-			{
-				WearAttrValueList = JsonMapper.ToObject<int[]>(tables[2]);
-			}
-			else
-			{
-				string[] WearAttrValueListStringArray = tables[2].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
-				WearAttrValueList = new int[WearAttrValueListStringArray.Length];
-				for (int i=0;i<WearAttrValueListStringArray.Length;i++)
-				{
-					 int.TryParse(WearAttrValueListStringArray[i],out WearAttrValueList[i]);
-				}
-			}
-
-			if (tables[3].Contains("["))
-			{
-				AllBatAttrIDList = JsonMapper.ToObject<int[]>(tables[3]);
-			}
-			else
-			{
-				string[] AllBatAttrIDListStringArray = tables[3].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
-				AllBatAttrIDList = new int[AllBatAttrIDListStringArray.Length];
-				for (int i=0;i<AllBatAttrIDListStringArray.Length;i++)
-				{
-					 int.TryParse(AllBatAttrIDListStringArray[i],out AllBatAttrIDList[i]);
-				}
-			}
-
-			if (tables[4].Contains("["))
-			{
-				AllBatAttrValueList = JsonMapper.ToObject<int[]>(tables[4]);
-			}
-			else
-			{
-				string[] AllBatAttrValueListStringArray = tables[4].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
-				AllBatAttrValueList = new int[AllBatAttrValueListStringArray.Length];
-				for (int i=0;i<AllBatAttrValueListStringArray.Length;i++)
-				{
-					 int.TryParse(AllBatAttrValueListStringArray[i],out AllBatAttrValueList[i]);
-				}
-			}
-
-			Tachie = tables[5];
-
-			if (tables[6].Contains("["))
-			{
-				TachieParam = JsonMapper.ToObject<float[]>(tables[6]);
-			}
-			else
-			{
-				string[] TachieParamStringArray = tables[6].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				string[] TachieParamStringArray = tables[5].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
 				TachieParam = new float[TachieParamStringArray.Length];
 				for (int i=0;i<TachieParamStringArray.Length;i++)
 				{
@@ -115,9 +65,11 @@
 				}
 			}
 
-			SquareIcon = tables[7];
+			SquareIcon = tables[6];
 
-			RectangleIcon = tables[8];
+			RectangleIcon = tables[7];
+
+			CardPic = tables[8];
 
 			SpineRes = tables[9];
 
diff --git a/Main/Config/Configs/ModelConfig.cs b/Main/Config/Configs/ModelConfig.cs
index ff78c7c..42ee750 100644
--- a/Main/Config/Configs/ModelConfig.cs
+++ b/Main/Config/Configs/ModelConfig.cs
@@ -1,6 +1,6 @@
 锘�//--------------------------------------------------------
 //    [Author]:           YYL
-//    [  Date ]:           2025骞�11鏈�25鏃�
+//    [  Date ]:           2026骞�3鏈�17鏃�
 //--------------------------------------------------------
 
 using System.Collections.Generic;
@@ -31,6 +31,7 @@
 	public int[] InitAttrValueList;
 	public int[] AttrPerStarAddList;
 	public string GetWayString;
+	public int SortIndex;
 
     public override int LoadKey(string _key)
     {
@@ -107,6 +108,8 @@
 			}
 
 			GetWayString = tables[14];
+
+			int.TryParse(tables[15],out SortIndex); 
         }
         catch (Exception exception)
         {
diff --git a/Main/Config/Configs/OrderInfoConfig.cs b/Main/Config/Configs/OrderInfoConfig.cs
index e5e10b3..10ed6bf 100644
--- a/Main/Config/Configs/OrderInfoConfig.cs
+++ b/Main/Config/Configs/OrderInfoConfig.cs
@@ -1,6 +1,6 @@
 锘�//--------------------------------------------------------
 //    [Author]:           YYL
-//    [  Date ]:           2025骞�8鏈�5鏃�
+//    [  Date ]:           Tuesday, March 24, 2026
 //--------------------------------------------------------
 
 using System.Collections.Generic;
@@ -24,8 +24,6 @@
 	public float UsdMoney;
 	public string StoreOrderInfo;
 	public string StoreOrderInfo2;
-	public string Name;
-	public string StoreOrderInfo3;
 
     public override int LoadKey(string _key)
     {
@@ -52,10 +50,6 @@
 			StoreOrderInfo = tables[6];
 
 			StoreOrderInfo2 = tables[7];
-
-			Name = tables[8];
-
-			StoreOrderInfo3 = tables[9];
         }
         catch (Exception exception)
         {
diff --git a/Main/Config/Configs/PlayerFaceConfig.cs b/Main/Config/Configs/PlayerFaceConfig.cs
index f8f9abb..641356a 100644
--- a/Main/Config/Configs/PlayerFaceConfig.cs
+++ b/Main/Config/Configs/PlayerFaceConfig.cs
@@ -1,6 +1,6 @@
 锘�//--------------------------------------------------------
 //    [Author]:           YYL
-//    [  Date ]:           Wednesday, November 19, 2025
+//    [  Date ]:           2026骞�3鏈�17鏃�
 //--------------------------------------------------------
 
 using System.Collections.Generic;
@@ -31,6 +31,7 @@
 	public int[] InitAttrValueList;
 	public int[] AttrPerStarAddList;
 	public string GetWayString;
+	public int SortIndex;
 
     public override int LoadKey(string _key)
     {
@@ -107,6 +108,8 @@
 			}
 
 			GetWayString = tables[14];
+
+			int.TryParse(tables[15],out SortIndex); 
         }
         catch (Exception exception)
         {
diff --git a/Main/Config/Configs/PlayerFacePicConfig.cs b/Main/Config/Configs/PlayerFacePicConfig.cs
index 920e903..c4f2e42 100644
--- a/Main/Config/Configs/PlayerFacePicConfig.cs
+++ b/Main/Config/Configs/PlayerFacePicConfig.cs
@@ -1,6 +1,6 @@
 锘�//--------------------------------------------------------
 //    [Author]:           YYL
-//    [  Date ]:           2025骞�11鏈�16鏃�
+//    [  Date ]:           2026骞�3鏈�17鏃�
 //--------------------------------------------------------
 
 using System.Collections.Generic;
@@ -30,6 +30,7 @@
 	public int[] InitAttrValueList;
 	public int[] AttrPerStarAddList;
 	public string GetWayString;
+	public int SortIndex;
 
     public override int LoadKey(string _key)
     {
@@ -104,6 +105,8 @@
 			}
 
 			GetWayString = tables[13];
+
+			int.TryParse(tables[14],out SortIndex); 
         }
         catch (Exception exception)
         {
diff --git a/Main/Config/Configs/PopWinOrderConfig.cs b/Main/Config/Configs/PopWinOrderConfig.cs
new file mode 100644
index 0000000..bb870db
--- /dev/null
+++ b/Main/Config/Configs/PopWinOrderConfig.cs
@@ -0,0 +1,44 @@
+锘�//--------------------------------------------------------
+//    [Author]:           YYL
+//    [  Date ]:           2026骞�2鏈�27鏃�
+//--------------------------------------------------------
+
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using LitJson;
+
+public partial class PopWinOrderConfig : ConfigBase<int, PopWinOrderConfig>
+{
+    static PopWinOrderConfig()
+    {
+        // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
+        visit = true; 
+    }
+
+    public int ID;
+	public string WinName;
+	public int WinOrder;
+
+    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); 
+
+			WinName = tables[1];
+
+			int.TryParse(tables[2],out WinOrder); 
+        }
+        catch (Exception exception)
+        {
+            Debug.LogError(exception);
+        }
+    }
+}
diff --git a/Main/Config/Configs/PopWinOrderConfig.cs.meta b/Main/Config/Configs/PopWinOrderConfig.cs.meta
new file mode 100644
index 0000000..d638be1
--- /dev/null
+++ b/Main/Config/Configs/PopWinOrderConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a5c6d2fdaab52b44a824d683ed361ddf
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/Configs/StoreConfig.cs b/Main/Config/Configs/StoreConfig.cs
index 02c85ce..d8938f5 100644
--- a/Main/Config/Configs/StoreConfig.cs
+++ b/Main/Config/Configs/StoreConfig.cs
@@ -1,6 +1,6 @@
 锘�//--------------------------------------------------------
 //    [Author]:           YYL
-//    [  Date ]:           2026骞�1鏈�8鏃�
+//    [  Date ]:           2026骞�3鏈�5鏃�
 //--------------------------------------------------------
 
 using System.Collections.Generic;
@@ -24,6 +24,7 @@
 	public int[][] ItemListEx;
 	public int ResetType;
 	public int LimitCnt;
+	public int CostItemID;
 	public int MoneyType;
 	public int MoneyNum;
 	public int MoneyOriginal;
@@ -58,19 +59,21 @@
 
 			int.TryParse(tables[7],out LimitCnt); 
 
-			int.TryParse(tables[8],out MoneyType); 
+			int.TryParse(tables[8],out CostItemID); 
 
-			int.TryParse(tables[9],out MoneyNum); 
+			int.TryParse(tables[9],out MoneyType); 
 
-			int.TryParse(tables[10],out MoneyOriginal); 
+			int.TryParse(tables[10],out MoneyNum); 
 
-			int.TryParse(tables[11],out UnlockType); 
+			int.TryParse(tables[11],out MoneyOriginal); 
 
-			int.TryParse(tables[12],out UnlockValue); 
+			int.TryParse(tables[12],out UnlockType); 
 
-			int.TryParse(tables[13],out IsExclusive); 
+			int.TryParse(tables[13],out UnlockValue); 
 
-			Name = tables[14];
+			int.TryParse(tables[14],out IsExclusive); 
+
+			Name = tables[15];
         }
         catch (Exception exception)
         {
diff --git a/Main/Config/Configs/TitleConfig.cs b/Main/Config/Configs/TitleConfig.cs
index b73297e..4acf228 100644
--- a/Main/Config/Configs/TitleConfig.cs
+++ b/Main/Config/Configs/TitleConfig.cs
@@ -1,69 +1,74 @@
-锘�//--------------------------------------------------------
-//    [Author]:           YYL
-//    [  Date ]:           2025骞�11鏈�18鏃�
-//--------------------------------------------------------
-
-using System.Collections.Generic;
-using System;
-using UnityEngine;
-using LitJson;
-
-public partial class TitleConfig : ConfigBase<int, TitleConfig>
-{
-    static TitleConfig()
-    {
-        // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
-        visit = true; 
-    }
-
-    public int TitleID;
-	public int TabType;
-	public string Name;
-	public int ResourceType;
-	public string ResourceValue;
-	public int ExpireMinutes;
-	public int UnlockWay;
-	public int UnlockValue;
-	public int UnlockNeedCnt;
-	public int UpNeedCnt;
-	public int StarMax;
-	public int[] AttrIDList;
-	public int[] InitAttrValueList;
-	public int[] AttrPerStarAddList;
-	public string GetWayString;
-
-    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 TitleID); 
-
-			int.TryParse(tables[1],out TabType); 
-
-			Name = tables[2];
-
-			int.TryParse(tables[3],out ResourceType); 
-
-			ResourceValue = tables[4];
-
-			int.TryParse(tables[5],out ExpireMinutes); 
-
-			int.TryParse(tables[6],out UnlockWay); 
-
-			int.TryParse(tables[7],out UnlockValue); 
-
-			int.TryParse(tables[8],out UnlockNeedCnt); 
-
-			int.TryParse(tables[9],out UpNeedCnt); 
-
-			int.TryParse(tables[10],out StarMax); 
-
+锘�//--------------------------------------------------------
+//    [Author]:           YYL
+//    [  Date ]:           2026骞�3鏈�17鏃�
+//--------------------------------------------------------
+
+using System.Collections.Generic;
+using System;
+using UnityEngine;
+using LitJson;
+
+public partial class TitleConfig : ConfigBase<int, TitleConfig>
+{
+    static TitleConfig()
+    {
+        // 璁块棶杩囬潤鎬佹瀯閫犲嚱鏁�
+        visit = true; 
+    }
+
+    public int TitleID;
+	public int TabType;
+	public string Name;
+	public int ResourceType;
+	public string ResourceValue;
+	public int ExpireMinutes;
+	public int UnlockWay;
+	public int UnlockValue;
+	public int UnlockNeedCnt;
+	public int UpNeedCnt;
+	public int StarMax;
+	public int[] AttrIDList;
+	public int[] InitAttrValueList;
+	public int[] AttrPerStarAddList;
+	public int EffType;
+	public int EffTypeValue;
+	public int EffValue;
+	public int EffPerStarAdd;
+	public string GetWayString;
+	public int SortIndex;
+
+    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 TitleID); 
+
+			int.TryParse(tables[1],out TabType); 
+
+			Name = tables[2];
+
+			int.TryParse(tables[3],out ResourceType); 
+
+			ResourceValue = tables[4];
+
+			int.TryParse(tables[5],out ExpireMinutes); 
+
+			int.TryParse(tables[6],out UnlockWay); 
+
+			int.TryParse(tables[7],out UnlockValue); 
+
+			int.TryParse(tables[8],out UnlockNeedCnt); 
+
+			int.TryParse(tables[9],out UpNeedCnt); 
+
+			int.TryParse(tables[10],out StarMax); 
+
 			if (tables[11].Contains("["))
 			{
 				AttrIDList = JsonMapper.ToObject<int[]>(tables[11]);
@@ -76,8 +81,8 @@
 				{
 					 int.TryParse(AttrIDListStringArray[i],out AttrIDList[i]);
 				}
-			}
-
+			}
+
 			if (tables[12].Contains("["))
 			{
 				InitAttrValueList = JsonMapper.ToObject<int[]>(tables[12]);
@@ -90,8 +95,8 @@
 				{
 					 int.TryParse(InitAttrValueListStringArray[i],out InitAttrValueList[i]);
 				}
-			}
-
+			}
+
 			if (tables[13].Contains("["))
 			{
 				AttrPerStarAddList = JsonMapper.ToObject<int[]>(tables[13]);
@@ -104,13 +109,23 @@
 				{
 					 int.TryParse(AttrPerStarAddListStringArray[i],out AttrPerStarAddList[i]);
 				}
-			}
-
-			GetWayString = tables[14];
-        }
-        catch (Exception exception)
-        {
-            Debug.LogError(exception);
-        }
-    }
-}
+			}
+
+			int.TryParse(tables[14],out EffType); 
+
+			int.TryParse(tables[15],out EffTypeValue); 
+
+			int.TryParse(tables[16],out EffValue); 
+
+			int.TryParse(tables[17],out EffPerStarAdd); 
+
+			GetWayString = tables[18];
+
+			int.TryParse(tables[19],out SortIndex); 
+        }
+        catch (Exception exception)
+        {
+            Debug.LogError(exception);
+        }
+    }
+}
diff --git a/Main/Config/Configs/TreasureSetConfig.cs b/Main/Config/Configs/TreasureSetConfig.cs
index 3e187a5..440cadd 100644
--- a/Main/Config/Configs/TreasureSetConfig.cs
+++ b/Main/Config/Configs/TreasureSetConfig.cs
@@ -1,6 +1,6 @@
 锘�//--------------------------------------------------------
 //    [Author]:           YYL
-//    [  Date ]:           Monday, December 29, 2025
+//    [  Date ]:           2026骞�3鏈�5鏃�
 //--------------------------------------------------------
 
 using System.Collections.Generic;
@@ -17,8 +17,9 @@
     }
 
     public int TreasureType;
-	public int PackType;
+	public int[] CheckPackList;
 	public int DailyMaxCount;
+	public int DailyMaxCountMoney;
 	public int DailyFreeCount;
 	public int[] TreasureCountList;
 	public int CostItemID;
@@ -50,19 +51,33 @@
         string[] tables = input.Split('\t');
         int.TryParse(tables[0],out TreasureType); 
 
-			int.TryParse(tables[1],out PackType); 
-
-			int.TryParse(tables[2],out DailyMaxCount); 
-
-			int.TryParse(tables[3],out DailyFreeCount); 
-
-			if (tables[4].Contains("["))
+			if (tables[1].Contains("["))
 			{
-				TreasureCountList = JsonMapper.ToObject<int[]>(tables[4]);
+				CheckPackList = JsonMapper.ToObject<int[]>(tables[1]);
 			}
 			else
 			{
-				string[] TreasureCountListStringArray = tables[4].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				string[] CheckPackListStringArray = tables[1].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				CheckPackList = new int[CheckPackListStringArray.Length];
+				for (int i=0;i<CheckPackListStringArray.Length;i++)
+				{
+					 int.TryParse(CheckPackListStringArray[i],out CheckPackList[i]);
+				}
+			}
+
+			int.TryParse(tables[2],out DailyMaxCount); 
+
+			int.TryParse(tables[3],out DailyMaxCountMoney); 
+
+			int.TryParse(tables[4],out DailyFreeCount); 
+
+			if (tables[5].Contains("["))
+			{
+				TreasureCountList = JsonMapper.ToObject<int[]>(tables[5]);
+			}
+			else
+			{
+				string[] TreasureCountListStringArray = tables[5].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
 				TreasureCountList = new int[TreasureCountListStringArray.Length];
 				for (int i=0;i<TreasureCountListStringArray.Length;i++)
 				{
@@ -70,15 +85,15 @@
 				}
 			}
 
-			int.TryParse(tables[5],out CostItemID); 
+			int.TryParse(tables[6],out CostItemID); 
 
-			if (tables[6].Contains("["))
+			if (tables[7].Contains("["))
 			{
-				CostItemCountList = JsonMapper.ToObject<int[]>(tables[6]);
+				CostItemCountList = JsonMapper.ToObject<int[]>(tables[7]);
 			}
 			else
 			{
-				string[] CostItemCountListStringArray = tables[6].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				string[] CostItemCountListStringArray = tables[7].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
 				CostItemCountList = new int[CostItemCountListStringArray.Length];
 				for (int i=0;i<CostItemCountListStringArray.Length;i++)
 				{
@@ -86,15 +101,15 @@
 				}
 			}
 
-			int.TryParse(tables[7],out CostMoneyType); 
+			int.TryParse(tables[8],out CostMoneyType); 
 
-			if (tables[8].Contains("["))
+			if (tables[9].Contains("["))
 			{
-				CostMoneyList = JsonMapper.ToObject<int[]>(tables[8]);
+				CostMoneyList = JsonMapper.ToObject<int[]>(tables[9]);
 			}
 			else
 			{
-				string[] CostMoneyListStringArray = tables[8].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
+				string[] CostMoneyListStringArray = tables[9].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries);
 				CostMoneyList = new int[CostMoneyListStringArray.Length];
 				for (int i=0;i<CostMoneyListStringArray.Length;i++)
 				{
@@ -102,29 +117,29 @@
 				}
 			}
 
-			int.TryParse(tables[9],out EnsureCount); 
+			int.TryParse(tables[10],out EnsureCount); 
 
-			int.TryParse(tables[10],out OnceLucky); 
+			int.TryParse(tables[11],out OnceLucky); 
 
-			int.TryParse(tables[11],out LuckyGridNum); 
+			int.TryParse(tables[12],out LuckyGridNum); 
 
-			GridNumMaxLimitInfo = ConfigParse.ParseIntDict(tables[12]); 
+			GridNumMaxLimitInfo = ConfigParse.ParseIntDict(tables[13]); 
 
-			int.TryParse(tables[13],out AwardMoneyType); 
+			int.TryParse(tables[14],out AwardMoneyType); 
 
-			int.TryParse(tables[14],out AwardMoneyValue); 
+			int.TryParse(tables[15],out AwardMoneyValue); 
 
-			int.TryParse(tables[15],out WishOpen); 
+			int.TryParse(tables[16],out WishOpen); 
 
-			int.TryParse(tables[16],out WishReset); 
+			int.TryParse(tables[17],out WishReset); 
 
-			WishLibSelect = ConfigParse.ParseIntDict(tables[17]); 
+			WishLibSelect = ConfigParse.ParseIntDict(tables[18]); 
 
-			WishLibPubFreeCnt = ConfigParse.ParseIntDict(tables[18]); 
+			WishLibPubFreeCnt = ConfigParse.ParseIntDict(tables[19]); 
 
-			WishLibCard = ConfigParse.ParseIntDict(tables[19]); 
+			WishLibCard = ConfigParse.ParseIntDict(tables[20]); 
 
-			ProbabilityDisplay = tables[20];
+			ProbabilityDisplay = tables[21];
         }
         catch (Exception exception)
         {
diff --git a/Main/Config/PartialConfigs/ActBillboardAwardConfig.cs b/Main/Config/PartialConfigs/ActBillboardAwardConfig.cs
new file mode 100644
index 0000000..a830b56
--- /dev/null
+++ b/Main/Config/PartialConfigs/ActBillboardAwardConfig.cs
@@ -0,0 +1,77 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public partial class ActBillboardAwardConfig : ConfigBase<int, ActBillboardAwardConfig>
+{
+    // 妯℃澘缂栧彿: 鍚嶆A :閰嶇疆ID
+    private static Dictionary<int, Dictionary<int, int>> infoDict = new Dictionary<int, Dictionary<int, int>>();
+
+    // 妯℃澘缂栧彿 鍚嶆A
+    private static Dictionary<int, List<int>> sortDict = new Dictionary<int, List<int>>();
+
+    protected override void OnConfigParseCompleted()
+    {
+        if (!infoDict.TryGetValue(TemplateID, out var dict))
+        {
+            dict = new Dictionary<int, int>();
+            infoDict[TemplateID] = dict;
+        }
+        dict[RankA] = ID;
+    }
+
+    private static void LoadSortList()
+    {
+        if (!sortDict.IsNullOrEmpty()) return;
+        foreach (var kvp in infoDict)
+        {
+            int templateID = kvp.Key;
+            List<int> list = new List<int>(kvp.Value.Keys);
+            list.Sort();
+            sortDict[templateID] = list;
+        }
+    }
+
+    public static List<int> GetRankASortList(int templateID)
+    {
+        LoadSortList();
+        sortDict.TryGetValue(templateID, out var list);
+        return list;
+    }
+
+    public static Dictionary<int, int> GetTemplateIDDict(int templateID)
+    {
+        infoDict.TryGetValue(templateID, out var dict);
+        return dict;
+    }
+
+    public static int GetID(int templateID, int rankA)
+    {
+        var dict = GetTemplateIDDict(templateID);
+        if (dict == null) return 0;
+
+        dict.TryGetValue(rankA, out var id);
+        return id;
+    }
+
+    public static ActBillboardAwardConfig GetConfig(int templateID, int rankA)
+    {
+        int id = GetID(templateID, rankA);
+        return Get(id);
+    }
+
+    public static float GetTop3MinCalNeedValue(int templateID)
+    {
+        var list = GetRankASortList(templateID);
+        float res = float.MaxValue;
+        foreach (var rankA in list)
+        {
+            if (rankA > 3) continue;
+
+            var config = GetConfig(templateID, rankA);
+            if (config == null) continue;
+
+            res = Mathf.Min(res, config.NeedValue);
+        }
+        return res == float.MaxValue ? 0 : res;
+    }
+}
\ No newline at end of file
diff --git a/Main/Config/PartialConfigs/ActBillboardAwardConfig.cs.meta b/Main/Config/PartialConfigs/ActBillboardAwardConfig.cs.meta
new file mode 100644
index 0000000..ec15958
--- /dev/null
+++ b/Main/Config/PartialConfigs/ActBillboardAwardConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 337f905faa5a7bf44a09646897bd603f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/PartialConfigs/ActHeroAppearConfig.cs b/Main/Config/PartialConfigs/ActHeroAppearConfig.cs
new file mode 100644
index 0000000..c258cab
--- /dev/null
+++ b/Main/Config/PartialConfigs/ActHeroAppearConfig.cs
@@ -0,0 +1,18 @@
+using System.Collections.Generic;
+public partial class ActHeroAppearConfig : ConfigBase<int, ActHeroAppearConfig>
+{
+    private static List<int> actTreasureTypeList;
+    public static List<int> GetActTreasureTypeList()
+    {
+        if (actTreasureTypeList == null)
+        {
+            actTreasureTypeList = new();
+            foreach (var item in GetValues())
+            {
+                if (!actTreasureTypeList.Contains(item.ActTreasureType))
+                    actTreasureTypeList.Add(item.ActTreasureType);
+            }
+        }
+        return actTreasureTypeList;
+    }
+}
diff --git a/Main/Config/PartialConfigs/ActHeroAppearConfig.cs.meta b/Main/Config/PartialConfigs/ActHeroAppearConfig.cs.meta
new file mode 100644
index 0000000..7957a62
--- /dev/null
+++ b/Main/Config/PartialConfigs/ActHeroAppearConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c556397a9ff351e4e8895e33b7e19209
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/PartialConfigs/ActHeroAppearStarConfig.cs b/Main/Config/PartialConfigs/ActHeroAppearStarConfig.cs
new file mode 100644
index 0000000..df067a9
--- /dev/null
+++ b/Main/Config/PartialConfigs/ActHeroAppearStarConfig.cs
@@ -0,0 +1,85 @@
+using System.Collections.Generic;
+public partial class ActHeroAppearStarConfig : ConfigBase<int, ActHeroAppearStarConfig>
+{
+    // 鍗囨槦绀煎寘妯$増ID: 濂栧姳璁板綍绱㈠紩 :閰嶇疆ID
+    private static Dictionary<int, Dictionary<int, int>> infoDict = new();
+    // 鍗囨槦绀煎寘妯$増ID List<濂栧姳璁板綍绱㈠紩>
+    private static Dictionary<int, List<int>> sortDict = new();
+    protected override void OnConfigParseCompleted()
+    {
+        if (!infoDict.TryGetValue(StarTempID, out var dict))
+        {
+            dict = new Dictionary<int, int>();
+            infoDict[StarTempID] = dict;
+        }
+        dict[AwardIndex] = ID;
+    }
+
+    private static void LoadSortList()
+    {
+        if (!sortDict.IsNullOrEmpty()) return;
+        foreach (var kvp in infoDict)
+        {
+            int starTempID = kvp.Key;
+            List<int> list = new List<int>(kvp.Value.Keys);
+            list.Sort();
+            sortDict[starTempID] = list;
+        }
+    }
+
+    public static List<int> GetAwardIndexSortList(int starTempID)
+    {
+        LoadSortList();
+        sortDict.TryGetValue(starTempID, out var list);
+
+        List<int> res = new List<int>();
+        int heroId = HeroDebutManager.Instance.GetCurrentDisplayStarUpHeroId();
+        int nowStar = HeroDebutManager.Instance.GetNowHeroMaxStarCnt(heroId);
+        for (int i = HeroDebutManager.Instance.seeArr.Length - 1; i >= 0; i--)
+        {
+            int[] info = HeroDebutManager.Instance.seeArr[i];
+            int needStar = info[0];
+            int seeStar = info[1];
+            if (nowStar >= needStar)
+            {
+                for (int j = 0; j < seeStar; j++)
+                {
+                    if (j >= list.Count) continue;
+
+                    var config = GetConfig(starTempID, list[j]);
+                    if (config == null) continue;
+
+                    int tempStar = config.NeedStar;
+                    if (tempStar > seeStar) continue;
+
+                    res.Add(list[j]);
+                }
+                return res;
+            }
+        }
+
+        return null;
+    }
+
+    public static Dictionary<int, int> GetAwardIndexDict(int starTempID)
+    {
+        infoDict.TryGetValue(starTempID, out var dict);
+        return dict;
+    }
+
+    public static int GetID(int starTempID, int awardIndex)
+    {
+        var dict = GetAwardIndexDict(starTempID);
+        if (dict == null) return 0;
+
+        dict.TryGetValue(awardIndex, out var id);
+        return id;
+    }
+
+    public static ActHeroAppearStarConfig GetConfig(int starTempID, int awardIndex)
+    {
+        int id = GetID(starTempID, awardIndex);
+        return Get(id);
+    }
+
+}
diff --git a/Main/Config/PartialConfigs/ActHeroAppearStarConfig.cs.meta b/Main/Config/PartialConfigs/ActHeroAppearStarConfig.cs.meta
new file mode 100644
index 0000000..0d63b56
--- /dev/null
+++ b/Main/Config/PartialConfigs/ActHeroAppearStarConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: dfb28fa9e267ad64d8164e33078a9cdd
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/PartialConfigs/ActSignAwardConfig.cs b/Main/Config/PartialConfigs/ActSignAwardConfig.cs
new file mode 100644
index 0000000..2daed27
--- /dev/null
+++ b/Main/Config/PartialConfigs/ActSignAwardConfig.cs
@@ -0,0 +1,57 @@
+using System.Collections.Generic;
+
+public partial class ActSignAwardConfig : ConfigBase<int, ActSignAwardConfig>
+{
+    // 妯℃澘缂栧彿: 绗琗澶╀粠1寮�濮� :閰嶇疆ID
+    private static Dictionary<int, Dictionary<int, int>> infoDict = new Dictionary<int, Dictionary<int, int>>();
+    // 妯℃澘缂栧彿 绗琗澶╀粠1寮�濮�
+    private static Dictionary<int, List<int>> sortDict = new Dictionary<int, List<int>>();
+    protected override void OnConfigParseCompleted()
+    {
+        if (!infoDict.TryGetValue(TemplateID, out var dict))
+        {
+            dict = new Dictionary<int, int>();
+            infoDict[TemplateID] = dict;
+        }
+        dict[DayNum] = ID;
+    }
+
+    private static void LoadSortList()
+    {
+        if (!sortDict.IsNullOrEmpty()) return;
+        foreach (var kvp in infoDict)
+        {
+            int templateID = kvp.Key;
+            List<int> list = new List<int>(kvp.Value.Keys);
+            list.Sort();
+            sortDict[templateID] = list;
+        }
+    }
+    public static List<int> GetDayNumSortList(int templateID)
+    {
+        LoadSortList();
+        sortDict.TryGetValue(templateID, out var list);
+        return list;
+    }
+    public static Dictionary<int, int> GetTemplateIDDict(int templateID)
+    {
+        infoDict.TryGetValue(templateID, out var dict);
+        return dict;
+    }
+
+    public static int GetID(int templateID, int dayNum)
+    {
+        var dict = GetTemplateIDDict(templateID);
+        if (dict == null) return 0;
+
+        dict.TryGetValue(dayNum, out var id);
+        return id;
+    }
+
+    public static ActSignAwardConfig GetConfig(int templateID, int dayNum)
+    {
+        int id = GetID(templateID, dayNum);
+        return Get(id);
+    }
+
+}
\ No newline at end of file
diff --git a/Main/Config/PartialConfigs/ActSignAwardConfig.cs.meta b/Main/Config/PartialConfigs/ActSignAwardConfig.cs.meta
new file mode 100644
index 0000000..0713a37
--- /dev/null
+++ b/Main/Config/PartialConfigs/ActSignAwardConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8c89fb14eface4d409c9bc91038a9102
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/PartialConfigs/HeroConfig.cs b/Main/Config/PartialConfigs/HeroConfig.cs
new file mode 100644
index 0000000..c690a16
--- /dev/null
+++ b/Main/Config/PartialConfigs/HeroConfig.cs
@@ -0,0 +1,29 @@
+锘縰sing System.Collections.Generic;
+
+public partial class HeroConfig : ConfigBase<int, HeroConfig>
+{
+    static Dictionary<int, int> skinIDToHeroIDDict = new Dictionary<int, int>();
+
+    protected override void OnConfigParseCompleted()
+    {
+        if (PlayerCanUse == 0) return;
+        for (int i = 0; i < SkinIDList.Length; i++)
+        {
+            skinIDToHeroIDDict.Add(SkinIDList[i], HeroID);
+        }
+    }
+
+    public static int GetHeroIDBySkinID(int skinID)
+    {
+        if (skinIDToHeroIDDict.ContainsKey(skinID))
+        {
+            return skinIDToHeroIDDict[skinID];
+        }
+        return 0;
+    }
+}
+
+
+
+
+
diff --git a/Main/Config/PartialConfigs/HeroConfig.cs.meta b/Main/Config/PartialConfigs/HeroConfig.cs.meta
new file mode 100644
index 0000000..215732b
--- /dev/null
+++ b/Main/Config/PartialConfigs/HeroConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 602823eff16549445a1e5b1d324a9953
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/PartialConfigs/HeroSkinAttrConfig.cs b/Main/Config/PartialConfigs/HeroSkinAttrConfig.cs
new file mode 100644
index 0000000..95ed603
--- /dev/null
+++ b/Main/Config/PartialConfigs/HeroSkinAttrConfig.cs
@@ -0,0 +1,25 @@
+
+using System.Collections.Generic;
+using System.Linq;
+
+public partial class HeroSkinAttrConfig : ConfigBase<int, HeroSkinAttrConfig>
+{
+
+    public static Dictionary<int, int> itemIdToSkinIDDict = new Dictionary<int, int>();
+
+    protected override void OnConfigParseCompleted()
+    {
+        itemIdToSkinIDDict[NeedItemID] = SkinID;
+    }
+
+    public static bool TryGetSkinIDByItemID(int itemID, out int skinID)
+    {
+        return itemIdToSkinIDDict.TryGetValue(itemID, out skinID);
+    }
+
+    public static List<int> GetItemList()
+    {
+        return itemIdToSkinIDDict.Keys.ToList();
+    }
+}
+
diff --git a/Main/Config/PartialConfigs/HeroSkinAttrConfig.cs.meta b/Main/Config/PartialConfigs/HeroSkinAttrConfig.cs.meta
new file mode 100644
index 0000000..f364ff8
--- /dev/null
+++ b/Main/Config/PartialConfigs/HeroSkinAttrConfig.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 09344e2dfddc7e14f97bc871ecb8630a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Config/PartialConfigs/ModelConfig.cs b/Main/Config/PartialConfigs/ModelConfig.cs
index 84b2b20..92fee28 100644
--- a/Main/Config/PartialConfigs/ModelConfig.cs
+++ b/Main/Config/PartialConfigs/ModelConfig.cs
@@ -19,7 +19,21 @@
         {
             return new List<int>();
         }
-        return tabTypeDict[tabType];
-    }
 
-}
+        List<int> allKeys = tabTypeDict[tabType];
+        List<int> validKeys = new List<int>();
+
+        for (int i = 0; i < allKeys.Count; i++)
+        {
+            int id = allKeys[i];
+            var cfg = Get(id);
+            // 杩囨护鏈揪鍒板紑鏈嶅ぉ鏁扮殑姝﹀皢鍜岀毊鑲ゅご鍍�
+            if (PhantasmPavilionManager.Instance.IsFaceOrModelVisible(cfg.UnlockWay, cfg.UnlockValue))
+            {
+                validKeys.Add(id);
+            }
+        }
+
+        return validKeys;
+    }
+}
\ No newline at end of file
diff --git a/Main/Config/PartialConfigs/OrderInfoConfig.cs b/Main/Config/PartialConfigs/OrderInfoConfig.cs
index c42d540..3b76420 100644
--- a/Main/Config/PartialConfigs/OrderInfoConfig.cs
+++ b/Main/Config/PartialConfigs/OrderInfoConfig.cs
@@ -2,7 +2,7 @@
 
 public partial class OrderInfoConfig : ConfigBase<int, OrderInfoConfig>
 {
-    //0.1鎶�
+    //0.1鎶� 娉ㄦ剰鐢║IHelper.GetMoneyFormat(PayRMBNumOnSale)
     public float PayRMBNumOnSale
     {
         get
diff --git a/Main/Config/PartialConfigs/TreasureItemLibConfig.cs b/Main/Config/PartialConfigs/TreasureItemLibConfig.cs
index 0a189ca..9abffda 100644
--- a/Main/Config/PartialConfigs/TreasureItemLibConfig.cs
+++ b/Main/Config/PartialConfigs/TreasureItemLibConfig.cs
@@ -6,7 +6,9 @@
 {
     private static Dictionary<int, List<int>> resultDict = new Dictionary<int, List<int>>();
     private static Dictionary<int, List<int>> resultWishIDDict = new Dictionary<int, List<int>>();
-	protected override void OnConfigParseCompleted()
+    private static Dictionary<int, Dictionary<int, int>> infoDict = new Dictionary<int, Dictionary<int, int>>();
+
+    protected override void OnConfigParseCompleted()
     {
         if (!resultDict.ContainsKey(LibID))
         {
@@ -25,6 +27,12 @@
         {
             resultWishIDDict[LibID].Add(ID);
         }
+
+        if (!infoDict.ContainsKey(LibID))
+        {
+            infoDict[LibID] = new Dictionary<int, int>();
+        }
+        infoDict[LibID][ItemID] = ID;
     }
 
 
@@ -37,4 +45,10 @@
     {
         return resultWishIDDict[libID];
     }
+
+    public static bool TryGetID(int libID, int itemID, out int id)
+    {
+        id = 0;
+        return infoDict.TryGetValue(libID, out var dict) && dict.TryGetValue(itemID, out id);
+    }
 }
diff --git a/Main/Core/GameEngine/Launch/ConfigInitTask.cs b/Main/Core/GameEngine/Launch/ConfigInitTask.cs
index 186c45e..662dbbe 100644
--- a/Main/Core/GameEngine/Launch/ConfigInitTask.cs
+++ b/Main/Core/GameEngine/Launch/ConfigInitTask.cs
@@ -61,11 +61,7 @@
         if (newContent != fileContent)
         {
             File.WriteAllText(filePath, newContent);
-            Debug.LogError("鎴樻枟鍏紡鏈夊彉鏇� FightPowerFormula.cs 宸叉牴鎹厤缃叕寮忛噸鏂扮敓鎴�, 璇锋彁浜や唬鐮侊紒");
-        }
-        else
-        {
-            Debug.Log("FightPowerFormula.cs 鍐呭鏈彉鍖栵紝鏃犻渶閲嶆柊鐢熸垚");
+            Debug.LogError("鎴樻枟鍏紡鏈夊彉鏇� FightPowerFormula.cs 闇�绋嬪簭妫�鏌ヤ唬鐮佸悓姝ュ叕寮忥紒");
         }
 
 #endif
diff --git a/Main/Core/GameEngine/Launch/RequestPermissionStart.cs b/Main/Core/GameEngine/Launch/RequestPermissionStart.cs
index dc5c223..ea92668 100644
--- a/Main/Core/GameEngine/Launch/RequestPermissionStart.cs
+++ b/Main/Core/GameEngine/Launch/RequestPermissionStart.cs
@@ -6,10 +6,10 @@
 
     public override void Begin()
     {
-// #if UNITY_EDITOR
-//         done = true;
-//         LocalSave.SetBool("secretToggleStart5", true);
-// #endif
+        // #if UNITY_EDITOR
+        //         done = true;
+        //         LocalSave.SetBool("secretToggleStart5", true);
+        // #endif
 
         // if (LocalSave.GetBool("secretToggleStart5"))
         // {
@@ -26,7 +26,11 @@
         // }
 
         //鍒拌繖閲屼竴瀹氭槸鍚屾剰闅愮锛岀函瀹夊崜澶勭悊
-        LocalSave.SetBool("secretToggleStart5", true);
+        if (VersionConfig.Get().appId == "xssg")
+        {
+            //TAP鏄浜嗕竴涓殣绉佹斂绛栵紝杩欓噷鍏堜笉澶勭悊
+            LocalSave.SetBool("secretToggleStart5", true);
+        }
         SDKUtils.Instance.RequestAndroidPermissionStart();
         SDKUtils.Instance.IsAgreeSecret = true;
     }
diff --git a/Main/Core/GameEngine/Player/PlayerDatas.cs b/Main/Core/GameEngine/Player/PlayerDatas.cs
index c91b3a9..7508276 100644
--- a/Main/Core/GameEngine/Player/PlayerDatas.cs
+++ b/Main/Core/GameEngine/Player/PlayerDatas.cs
@@ -410,14 +410,13 @@
                 //涓庢湇鍔$绾﹀畾 0 鍗曡鑹茶В灏� 1 鍗曡鑹茬瑷�锛�2璁惧绂佽█锛�3璁惧瑙e皝
                 if (value == 2)
                 {
-                    LocalSave.SetBool("ServerForbidenChatDevice1", true);
+                    LocalSave.SetBool("BanChatDevice", true);
                 }
                 else if (value == 3)
                 {
                     //浠绘剰璐﹀彿瑙e皝
-                    LocalSave.SetBool("ServerForbidenChatDevice1", false);
+                    LocalSave.SetBool("BanChatDevice", false);
                 }
-                //ModelCenter.Instance.GetModel<ChatCenter>().ServerForbidenChat(extersion.forbidenTalk == 1);
                 break;
             case PlayerDataType.CDBPlayerRefresh_TalentPoint:
                 extersion.talentPoint = (int)value;
diff --git a/Main/Core/NetworkPackage/ClientPack/CAA SaleActivity.meta b/Main/Core/NetworkPackage/ClientPack/CAA SaleActivity.meta
new file mode 100644
index 0000000..be4f6d2
--- /dev/null
+++ b/Main/Core/NetworkPackage/ClientPack/CAA SaleActivity.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 81b74fbdb1ec9d743a0ea4b15fb5a97f
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA01_tagCSActHeroAppearStarHeroSelect.cs b/Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA01_tagCSActHeroAppearStarHeroSelect.cs
new file mode 100644
index 0000000..7ee3157
--- /dev/null
+++ b/Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA01_tagCSActHeroAppearStarHeroSelect.cs
@@ -0,0 +1,20 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 01 姝﹀皢鐧诲満鍗囨槦姝﹀皢閫夋嫨 #tagCSActHeroAppearStarHeroSelect
+
+public class CAA01_tagCSActHeroAppearStarHeroSelect : GameNetPackBasic {
+    public byte ActNum;    // 娲诲姩缂栧彿
+    public byte StarHeroIndex;    // 鍗囨槦璁″垝閫夋嫨鐨勬灏咺D绱㈠紩
+
+    public CAA01_tagCSActHeroAppearStarHeroSelect () {
+        combineCmd = (ushort)0x03FE;
+        _cmd = (ushort)0xAA01;
+    }
+
+    public override void WriteToBytes () {
+        WriteBytes (ActNum, NetDataType.BYTE);
+        WriteBytes (StarHeroIndex, NetDataType.BYTE);
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA01_tagCSActHeroAppearStarHeroSelect.cs.meta b/Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA01_tagCSActHeroAppearStarHeroSelect.cs.meta
new file mode 100644
index 0000000..6ecdc92
--- /dev/null
+++ b/Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA01_tagCSActHeroAppearStarHeroSelect.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4baab55a896f759449a3958baf35b816
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA02_tagCSActHeroAppearCallHeroSelect.cs b/Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA02_tagCSActHeroAppearCallHeroSelect.cs
new file mode 100644
index 0000000..a7f361d
--- /dev/null
+++ b/Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA02_tagCSActHeroAppearCallHeroSelect.cs
@@ -0,0 +1,20 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 02 姝﹀皢鐧诲満鎷涘嫙姝﹀皢閫夋嫨 #tagCSActHeroAppearCallHeroSelect
+
+public class CAA02_tagCSActHeroAppearCallHeroSelect : GameNetPackBasic {
+    public byte ActNum;    // 娲诲姩缂栧彿
+    public byte CallHeroIndex;    // 鎷涘嫙閫夋嫨鐨勬灏咺D绱㈠紩
+
+    public CAA02_tagCSActHeroAppearCallHeroSelect () {
+        combineCmd = (ushort)0x03FE;
+        _cmd = (ushort)0xAA02;
+    }
+
+    public override void WriteToBytes () {
+        WriteBytes (ActNum, NetDataType.BYTE);
+        WriteBytes (CallHeroIndex, NetDataType.BYTE);
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA02_tagCSActHeroAppearCallHeroSelect.cs.meta b/Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA02_tagCSActHeroAppearCallHeroSelect.cs.meta
new file mode 100644
index 0000000..7d43ef1
--- /dev/null
+++ b/Main/Core/NetworkPackage/ClientPack/CAA SaleActivity/CAA02_tagCSActHeroAppearCallHeroSelect.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4be187b44e045a841b23e6587bce5044
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB210_tagCSQunyingMatch.cs b/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB210_tagCSQunyingMatch.cs
new file mode 100644
index 0000000..b23430e
--- /dev/null
+++ b/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB210_tagCSQunyingMatch.cs
@@ -0,0 +1,18 @@
+using UnityEngine;
+using System.Collections;
+
+// B2 10 缇よ嫳姒滃尮閰嶇帺瀹� #tagCSQunyingMatch
+
+public class CB210_tagCSQunyingMatch : GameNetPackBasic {
+    public byte IsRefresh;    // 0-鎵撳紑鐣岄潰鏃舵煡璇紝1-寮哄埗鍒锋柊鍖归厤鍒楄〃
+
+    public CB210_tagCSQunyingMatch () {
+        combineCmd = (ushort)0x03FE;
+        _cmd = (ushort)0xB210;
+    }
+
+    public override void WriteToBytes () {
+        WriteBytes (IsRefresh, NetDataType.BYTE);
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB210_tagCSQunyingMatch.cs.meta b/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB210_tagCSQunyingMatch.cs.meta
new file mode 100644
index 0000000..68f98bb
--- /dev/null
+++ b/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB210_tagCSQunyingMatch.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 809fff7a1e32fed408b8f79146ede0c5
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB236_tagCSHeroSkinOP.cs b/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB236_tagCSHeroSkinOP.cs
new file mode 100644
index 0000000..afa1c1f
--- /dev/null
+++ b/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB236_tagCSHeroSkinOP.cs
@@ -0,0 +1,24 @@
+using UnityEngine;
+using System.Collections;
+
+// B2 36 姝﹀皢鐨偆鎿嶄綔 #tagCSHeroSkinOP
+
+public class CB236_tagCSHeroSkinOP : GameNetPackBasic {
+    public uint HeroID;    //姝﹀皢ID
+    public uint SkinID;    //鏃惰ID
+    public byte OPType;    //鎿嶄綔 1-婵�娲伙紱2-閫夋嫨褰㈣薄锛�3-鍗囨槦锛�4-閫夋嫨灞炴��
+    public ushort ItemIndex;    //姝﹀皢鐗╁搧鎵�鍦ㄦ灏嗚儗鍖呬綅缃储寮曪紝浠呬僵鎴存椂鏈夋晥
+
+    public CB236_tagCSHeroSkinOP () {
+        combineCmd = (ushort)0x03FE;
+        _cmd = (ushort)0xB236;
+    }
+
+    public override void WriteToBytes () {
+        WriteBytes (HeroID, NetDataType.DWORD);
+        WriteBytes (SkinID, NetDataType.DWORD);
+        WriteBytes (OPType, NetDataType.BYTE);
+        WriteBytes (ItemIndex, NetDataType.WORD);
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB236_tagCSHeroSkinOP.cs.meta b/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB236_tagCSHeroSkinOP.cs.meta
new file mode 100644
index 0000000..4c60ceb
--- /dev/null
+++ b/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB236_tagCSHeroSkinOP.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2dd991d5ee1914b4ca233ca3b7809e04
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB236_tagCSHeroWearSkin.cs b/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB236_tagCSHeroWearSkin.cs
deleted file mode 100644
index fd9e278..0000000
--- a/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB236_tagCSHeroWearSkin.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using UnityEngine;
-using System.Collections;
-
-// B2 36 姝﹀皢鎹㈣偆 #tagCSHeroWearSkin
-
-public class CB236_tagCSHeroWearSkin : GameNetPackBasic {
-    public ushort ItemIndex;    //姝﹀皢鐗╁搧鎵�鍦ㄦ灏嗚儗鍖呬綅缃储寮�
-    public byte SkinIndex;    //鐨偆绱㈠紩
-
-    public CB236_tagCSHeroWearSkin () {
-        combineCmd = (ushort)0x03FE;
-        _cmd = (ushort)0xB236;
-    }
-
-    public override void WriteToBytes () {
-        WriteBytes (ItemIndex, NetDataType.WORD);
-        WriteBytes (SkinIndex, NetDataType.BYTE);
-    }
-
-}
diff --git a/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB236_tagCSHeroWearSkin.cs.meta b/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB236_tagCSHeroWearSkin.cs.meta
deleted file mode 100644
index f41b819..0000000
--- a/Main/Core/NetworkPackage/ClientPack/CB2_NewFunction/CB236_tagCSHeroWearSkin.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: d05540ed30efe1e45bcf656bf5fb9518
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/H01_System/DTC0102_tagCDBPlayer.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/H01_System/DTC0102_tagCDBPlayer.cs
index 3606984..665129e 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/H01_System/DTC0102_tagCDBPlayer.cs
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/H01_System/DTC0102_tagCDBPlayer.cs
@@ -5,7 +5,7 @@
 public class DTC0102_tagCDBPlayer : DtcBasic
 {
 
-    public static event Action beforePlayerDataInitializeEvent; //閲嶇櫥鍒囨崲璐﹀彿 鎴栬�� 鐭殏鐨勬柇绾块噸杩� 閮戒細瑙﹀彂,(鎱庣敤锛侊紒锛�)
+    public static event Action beforePlayerDataInitializeEvent; //閲嶇櫥鍒囨崲璐﹀彿 鎴栬�� 鐭殏鐨勬柇绾块噸杩� 閮戒細瑙﹀彂 (閫夋嫨鎬т娇鐢紒锛侊紒)
     public static event Action beforePlayerDataInitializeEventOnRelogin;    //閲嶇櫥鍒囨崲璐﹀彿瑙﹀彂 锛堝ぇ澶氭儏鍐电敤杩欎釜锛屾敞鎰忔湇鍔$浼氬彂鍖呭垪琛ㄧ被鐨勫瓨鍌ㄩ噸澶嶆坊鍔犵殑鎯呭喌锛�
     public static event Action beforePlayerDataInitializeEventOnReconnect;    //鍚岃处鍙锋柇绾块噸杩炶Е鍙�
     public static event Action afterPlayerDataInitializeEvent;
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/H03_MainCharacter/DTC0320_tagFBEnd.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/H03_MainCharacter/DTC0320_tagFBEnd.cs
index ec94251..3790c07 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/H03_MainCharacter/DTC0320_tagFBEnd.cs
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/H03_MainCharacter/DTC0320_tagFBEnd.cs
@@ -9,5 +9,6 @@
         H0320_tagFBEnd vNetData = vNetPack as H0320_tagFBEnd;
         BoneFieldManager.Instance.UpdateFBEnd(vNetData);
         TianziBillboradManager.Instance.UpdateFBEnd(vNetData);
+        QunyingManager.Instance.UpdateFBEnd(vNetData);
     }
 }
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HA0_Sys/DTCA009_tagSCGameRecInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA0_Sys/DTCA009_tagSCGameRecInfo.cs
index 7a98be6..290e6a8 100644
--- a/Main/Core/NetworkPackage/DTCFile/ServerPack/HA0_Sys/DTCA009_tagSCGameRecInfo.cs
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA0_Sys/DTCA009_tagSCGameRecInfo.cs
@@ -8,5 +8,7 @@
         base.Done(vNetPack);
         HA009_tagSCGameRecInfo vNetData = vNetPack as HA009_tagSCGameRecInfo;
         ArenaManager.Instance.UpdateGameRecInfo(vNetData);
+        HeroDebutManager.Instance.UpdateGameRecInfo(vNetData);
+        QunyingManager.Instance.UpdateGameRecInfo(vNetData);
     }
 }
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA106_tagMCCoinToGoldReport.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA106_tagMCCoinToGoldReport.cs
new file mode 100644
index 0000000..0858221
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA106_tagMCCoinToGoldReport.cs
@@ -0,0 +1,12 @@
+using UnityEngine;
+using System.Collections;
+
+//A1 06 鐐瑰嵎杞寲鍏冨疂鍏呭�艰褰� #tagMCCoinToGoldReport
+
+public class DTCA106_tagMCCoinToGoldReport : DtcBasic {
+    public override void Done(GameNetPackBasic vNetPack) {
+        base.Done(vNetPack);
+        HA106_tagMCCoinToGoldReport vNetData = vNetPack as HA106_tagMCCoinToGoldReport;
+        SDKUtils.Instance.SendTraceEvent(6, money : (int)vNetData.Coin, orderID : vNetData.OrderID);
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA106_tagMCCoinToGoldReport.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA106_tagMCCoinToGoldReport.cs.meta
new file mode 100644
index 0000000..b6a1474
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA106_tagMCCoinToGoldReport.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c73183669494bd4448b57d8ca997ff7d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA124_tagMCPlayerInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA124_tagMCPlayerInfo.cs
new file mode 100644
index 0000000..bc3804b
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA124_tagMCPlayerInfo.cs
@@ -0,0 +1,12 @@
+using UnityEngine;
+using System.Collections;
+
+// A1 24 鐜╁鍒濆鍖栨墿灞曚俊鎭� #tagMCPlayerInfo
+
+public class DTCA124_tagMCPlayerInfo : DtcBasic {
+    public override void Done(GameNetPackBasic vNetPack) {
+        base.Done(vNetPack);
+        HA124_tagMCPlayerInfo vNetData = vNetPack as HA124_tagMCPlayerInfo;
+        TimeUtility.OnRefreshCreateRoleTime(vNetData);
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA124_tagMCPlayerInfo.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA124_tagMCPlayerInfo.cs.meta
new file mode 100644
index 0000000..7000e4f
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA1_Sys/DTCA124_tagMCPlayerInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4ecfdd87361b3b246a7ee62fe89eccf2
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HA3_Function/DTCA30C_tagMCPlayerRewardGetRecord.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA3_Function/DTCA30C_tagMCPlayerRewardGetRecord.cs
new file mode 100644
index 0000000..1a4e8c8
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA3_Function/DTCA30C_tagMCPlayerRewardGetRecord.cs
@@ -0,0 +1,13 @@
+using UnityEngine;
+using System.Collections;
+
+//A3 0C 鐜╁鍚勫鍔辩被鍨嬮鍙栬褰曚俊鎭� #tagMCPlayerRewardGetRecord
+
+public class DTCA30C_tagMCPlayerRewardGetRecord : DtcBasic {
+    public override void Done(GameNetPackBasic vNetPack) {
+        base.Done(vNetPack);
+        HA30C_tagMCPlayerRewardGetRecord vNetData = vNetPack as HA30C_tagMCPlayerRewardGetRecord;
+        SmallFuncManager.Instance.UpdatePlayerReward(vNetData);
+
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HA3_Function/DTCA30C_tagMCPlayerRewardGetRecord.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA3_Function/DTCA30C_tagMCPlayerRewardGetRecord.cs.meta
new file mode 100644
index 0000000..2bc3f33
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA3_Function/DTCA30C_tagMCPlayerRewardGetRecord.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f6149834f7edcb74cb112ba34d865e88
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA924_tagSCQunyingMatchList.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA924_tagSCQunyingMatchList.cs
new file mode 100644
index 0000000..0ba495d
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA924_tagSCQunyingMatchList.cs
@@ -0,0 +1,12 @@
+using UnityEngine;
+using System.Collections;
+
+// A9 24 缇よ嫳姒滃尮閰嶇帺瀹跺垪琛� #tagSCQunyingMatchList
+
+public class DTCA924_tagSCQunyingMatchList : DtcBasic {
+    public override void Done(GameNetPackBasic vNetPack) {
+        base.Done(vNetPack);
+        HA924_tagSCQunyingMatchList vNetData = vNetPack as HA924_tagSCQunyingMatchList;
+        QunyingManager.Instance.UpdateQunyingMatchInfo(vNetData);
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA924_tagSCQunyingMatchList.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA924_tagSCQunyingMatchList.cs.meta
new file mode 100644
index 0000000..85fa043
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA924_tagSCQunyingMatchList.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ff9bbc83b46795c4fa7c9acf79289dcb
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA925_tagSCQunyingPlayerInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA925_tagSCQunyingPlayerInfo.cs
new file mode 100644
index 0000000..4b0759c
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA925_tagSCQunyingPlayerInfo.cs
@@ -0,0 +1,12 @@
+using UnityEngine;
+using System.Collections;
+
+// A9 25 缇よ嫳姒滅帺瀹朵俊鎭� #tagSCQunyingPlayerInfo
+
+public class DTCA925_tagSCQunyingPlayerInfo : DtcBasic {
+    public override void Done(GameNetPackBasic vNetPack) {
+        base.Done(vNetPack);
+        HA925_tagSCQunyingPlayerInfo vNetData = vNetPack as HA925_tagSCQunyingPlayerInfo;
+        QunyingManager.Instance.UpdateQunyingInfo(vNetData);
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA925_tagSCQunyingPlayerInfo.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA925_tagSCQunyingPlayerInfo.cs.meta
new file mode 100644
index 0000000..099bd81
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HA9_Function/DTCA925_tagSCQunyingPlayerInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 960c25e4865aa4d4c894e9bf02f76dd0
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA20_tagSCActSignPlayerInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA20_tagSCActSignPlayerInfo.cs
new file mode 100644
index 0000000..637241e
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA20_tagSCActSignPlayerInfo.cs
@@ -0,0 +1,14 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 20 娲诲姩绛惧埌濂栧姳淇℃伅 #tagSCActSignPlayerInfo
+
+public class DTCAA20_tagSCActSignPlayerInfo : DtcBasic
+{
+    public override void Done(GameNetPackBasic vNetPack)
+    {
+        base.Done(vNetPack);
+        HAA20_tagSCActSignPlayerInfo vNetData = vNetPack as HAA20_tagSCActSignPlayerInfo;
+        GeneralActInfoManager.Instance.UpdateActSignPlayerInfo(vNetData);
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA20_tagSCActSignPlayerInfo.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA20_tagSCActSignPlayerInfo.cs.meta
new file mode 100644
index 0000000..b312df5
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA20_tagSCActSignPlayerInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d4a0cca060961b44bb617c44b0d8a319
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA21_tagSCActHeroAppearInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA21_tagSCActHeroAppearInfo.cs
new file mode 100644
index 0000000..9410b97
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA21_tagSCActHeroAppearInfo.cs
@@ -0,0 +1,12 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 21 姝﹀皢鐧诲満娲诲姩淇℃伅 #tagSCActHeroAppearInfo
+
+public class DTCAA21_tagSCActHeroAppearInfo : DtcBasic {
+    public override void Done(GameNetPackBasic vNetPack) {
+        base.Done(vNetPack);
+        HAA21_tagSCActHeroAppearInfo vNetData = vNetPack as HAA21_tagSCActHeroAppearInfo;
+        OperationTimeHepler.Instance.UpdateActHeroAppearInfo(vNetData);
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA21_tagSCActHeroAppearInfo.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA21_tagSCActHeroAppearInfo.cs.meta
new file mode 100644
index 0000000..5fef3f8
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA21_tagSCActHeroAppearInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 95268094788bf524795c5eb9affc17ac
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA22_tagSCActHeroAppearPlayerInfo.cs b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA22_tagSCActHeroAppearPlayerInfo.cs
new file mode 100644
index 0000000..4b4846c
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA22_tagSCActHeroAppearPlayerInfo.cs
@@ -0,0 +1,14 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 22 姝﹀皢鐧诲満娲诲姩鐜╁淇℃伅 #tagSCActHeroAppearPlayerInfo
+
+public class DTCAA22_tagSCActHeroAppearPlayerInfo : DtcBasic
+{
+    public override void Done(GameNetPackBasic vNetPack)
+    {
+        base.Done(vNetPack);
+        HAA22_tagSCActHeroAppearPlayerInfo vNetData = vNetPack as HAA22_tagSCActHeroAppearPlayerInfo;
+        HeroDebutManager.Instance.UpdateHeroAppearPlayerInfo(vNetData);
+    }
+}
diff --git a/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA22_tagSCActHeroAppearPlayerInfo.cs.meta b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA22_tagSCActHeroAppearPlayerInfo.cs.meta
new file mode 100644
index 0000000..e207deb
--- /dev/null
+++ b/Main/Core/NetworkPackage/DTCFile/ServerPack/HAA_SaleActivity/DTCAA22_tagSCActHeroAppearPlayerInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0358d952d0e98b349b417901b9f1c7f2
+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 3639fae..e0253d2 100644
--- a/Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
+++ b/Main/Core/NetworkPackage/DataToCtl/PackageRegedit.cs
@@ -153,6 +153,14 @@
         Register(typeof(HA131_tagSCSettingDataInfo), typeof(DTCA131_tagSCSettingDataInfo));
         Register(typeof(HAA88_tagMCActLunhuidianInfo), typeof(DTCAA88_tagMCActLunhuidianInfo));
         Register(typeof(HAA89_tagMCActLunhuidianPlayerInfo), typeof(DTCAA89_tagMCActLunhuidianPlayerInfo));
+        Register(typeof(HA124_tagMCPlayerInfo), typeof(DTCA124_tagMCPlayerInfo));
+        Register(typeof(HA106_tagMCCoinToGoldReport), typeof(DTCA106_tagMCCoinToGoldReport));
+        Register(typeof(HA30C_tagMCPlayerRewardGetRecord), typeof(DTCA30C_tagMCPlayerRewardGetRecord));
+        Register(typeof(HAA20_tagSCActSignPlayerInfo), typeof(DTCAA20_tagSCActSignPlayerInfo));
+        Register(typeof(HAA21_tagSCActHeroAppearInfo), typeof(DTCAA21_tagSCActHeroAppearInfo));
+        Register(typeof(HAA22_tagSCActHeroAppearPlayerInfo), typeof(DTCAA22_tagSCActHeroAppearPlayerInfo));
+        Register(typeof(HA924_tagSCQunyingMatchList), typeof(DTCA924_tagSCQunyingMatchList));
+        Register(typeof(HA925_tagSCQunyingPlayerInfo), typeof(DTCA925_tagSCQunyingPlayerInfo));
     }
 
     //涓诲伐绋嬫敞鍐屽皝鍖�
@@ -193,6 +201,7 @@
         catch (Exception ex)
         {
             Debug.LogError(ex.Message + "\r\n" + ex.StackTrace);
+            OperationLogCollect.Instance.BugReportSys(ex.ToString(), "10001");
             Debug.LogErrorFormat("灏佸寘鏄惁涓篘ull:{0};", _package == null);
             if (_package != null)
             {
diff --git a/Main/Core/NetworkPackage/GameNetSystem.cs b/Main/Core/NetworkPackage/GameNetSystem.cs
index 94d9e5e..64b8d2a 100644
--- a/Main/Core/NetworkPackage/GameNetSystem.cs
+++ b/Main/Core/NetworkPackage/GameNetSystem.cs
@@ -165,7 +165,7 @@
                 SendInfo(sendQueue.Dequeue());
             }
         }
-        Debug.LogError($"閲嶇偣鎻愰啋锛�0403鐧诲綍鍚� 鍙戦�佺紦瀛樺寘鏁伴噺 {cnt} 涓�");
+        Debug.Log($"閲嶇偣鎻愰啋锛�0403鐧诲綍鍚� 鍙戦�佺紦瀛樺寘鏁伴噺 {cnt} 涓�");
     }
 
     public void SendInfo(GameNetPackBasic protocol)
@@ -184,7 +184,7 @@
         {
             if (protocol is not C0123_tagCClientPackVersion && protocol is not C0101_tagCPlayerLogin)
             {
-                Debug.LogError("閲嶇偣鎻愰啋锛氱櫥褰曞畬鎴愬墠鐨勫皝鍖呭厛鍔犲叆闃熷垪 绛�0403鍥炲寘鍚庡啀涓�璧峰彂閫佹湇鍔$ " + protocol.ToString());
+                Debug.Log("閲嶇偣鎻愰啋锛氱櫥褰曞畬鎴愬墠鐨勫皝鍖呭厛鍔犲叆闃熷垪 绛�0403鍥炲寘鍚庡啀涓�璧峰彂閫佹湇鍔$ " + protocol.ToString());
                 sendQueue.Enqueue(protocol);
                 return;
             }
diff --git a/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA103_tagMCOpenServerDay.cs b/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA103_tagMCOpenServerDay.cs
index 20f7e5a..129cc59 100644
--- a/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA103_tagMCOpenServerDay.cs
+++ b/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA103_tagMCOpenServerDay.cs
@@ -16,6 +16,7 @@
     public byte NowSecond;
     public uint NowMicSecond;
     public byte WeekOfYear;    //涓�骞翠腑鐨勭鍑犲懆
+    public uint OpenServerTime;    //寮�鏈嶆椂闂存埑
 
     public HA103_tagMCOpenServerDay () {
         _cmd = (ushort)0xA103;
@@ -34,6 +35,7 @@
         TransBytes (out NowSecond, vBytes, NetDataType.BYTE);
         TransBytes (out NowMicSecond, vBytes, NetDataType.DWORD);
         TransBytes (out WeekOfYear, vBytes, NetDataType.BYTE);
+        TransBytes (out OpenServerTime, vBytes, NetDataType.DWORD);
     }
 
 }
diff --git a/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA106_tagMCCoinToGoldReport.cs b/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA106_tagMCCoinToGoldReport.cs
new file mode 100644
index 0000000..0440400
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA106_tagMCCoinToGoldReport.cs
@@ -0,0 +1,27 @@
+using UnityEngine;
+using System.Collections;
+
+//A1 06 鐐瑰嵎杞寲鍏冨疂鍏呭�艰褰� #tagMCCoinToGoldReport
+
+public class HA106_tagMCCoinToGoldReport : GameNetPackBasic {
+    public byte OrderLen;
+    public string OrderID;    // 璁㈠崟id
+    public uint Coin;    // 鍏呭�肩殑鐐瑰嵎
+    public ushort RecordID;    // ctgID
+    public byte OrderInfoLen;
+    public string OrderInfo;
+
+    public HA106_tagMCCoinToGoldReport () {
+        _cmd = (ushort)0xA106;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out OrderLen, vBytes, NetDataType.BYTE);
+        TransBytes (out OrderID, vBytes, NetDataType.Chars, OrderLen);
+        TransBytes (out Coin, vBytes, NetDataType.DWORD);
+        TransBytes (out RecordID, vBytes, NetDataType.WORD);
+        TransBytes (out OrderInfoLen, vBytes, NetDataType.BYTE);
+        TransBytes (out OrderInfo, vBytes, NetDataType.Chars, OrderInfoLen);
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA106_tagMCCoinToGoldReport.cs.meta b/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA106_tagMCCoinToGoldReport.cs.meta
new file mode 100644
index 0000000..77edb0f
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA106_tagMCCoinToGoldReport.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1a8a63a50f578424b82e430ed3d7528d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA124_tagMCPlayerInfo.cs b/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA124_tagMCPlayerInfo.cs
new file mode 100644
index 0000000..953bacb
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA124_tagMCPlayerInfo.cs
@@ -0,0 +1,19 @@
+using UnityEngine;
+using System.Collections;
+
+// A1 24 鐜╁鍒濆鍖栨墿灞曚俊鎭� #tagMCPlayerInfo
+
+public class HA124_tagMCPlayerInfo : GameNetPackBasic {
+    public byte IsAdult;    //鏄惁鎴愬勾
+    public string CreateRoleTime;
+
+    public HA124_tagMCPlayerInfo () {
+        _cmd = (ushort)0xA124;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out IsAdult, vBytes, NetDataType.BYTE);
+        TransBytes (out CreateRoleTime, vBytes, NetDataType.Chars, 19);
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA124_tagMCPlayerInfo.cs.meta b/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA124_tagMCPlayerInfo.cs.meta
new file mode 100644
index 0000000..b498f08
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HA1_Sys/HA124_tagMCPlayerInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2b001feac8eba034fbae445ae04c4e40
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/HA3_Function/HA30C_tagMCPlayerRewardGetRecord.cs b/Main/Core/NetworkPackage/ServerPack/HA3_Function/HA30C_tagMCPlayerRewardGetRecord.cs
new file mode 100644
index 0000000..3b7d032
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HA3_Function/HA30C_tagMCPlayerRewardGetRecord.cs
@@ -0,0 +1,19 @@
+using UnityEngine;
+using System.Collections;
+
+//A3 0C 鐜╁鍚勫鍔辩被鍨嬮鍙栬褰曚俊鎭� #tagMCPlayerRewardGetRecord
+
+public class HA30C_tagMCPlayerRewardGetRecord : GameNetPackBasic {
+    public byte RewardType;    //濂栧姳绫诲瀷
+    public uint RewardGetRecord;    // 鎸変簩杩涘埗浣嶆爣绀洪鍙栬褰�
+
+    public HA30C_tagMCPlayerRewardGetRecord () {
+        _cmd = (ushort)0xA30C;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out RewardType, vBytes, NetDataType.BYTE);
+        TransBytes (out RewardGetRecord, vBytes, NetDataType.DWORD);
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ServerPack/HA3_Function/HA30C_tagMCPlayerRewardGetRecord.cs.meta b/Main/Core/NetworkPackage/ServerPack/HA3_Function/HA30C_tagMCPlayerRewardGetRecord.cs.meta
new file mode 100644
index 0000000..90d31ea
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HA3_Function/HA30C_tagMCPlayerRewardGetRecord.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 842a0ed9f41346846ba3d8c619c09112
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/HA3_Function/HA350_tagMCTreasureResult.cs b/Main/Core/NetworkPackage/ServerPack/HA3_Function/HA350_tagMCTreasureResult.cs
index 1c2d19b..bf49523 100644
--- a/Main/Core/NetworkPackage/ServerPack/HA3_Function/HA350_tagMCTreasureResult.cs
+++ b/Main/Core/NetworkPackage/ServerPack/HA3_Function/HA350_tagMCTreasureResult.cs
@@ -1,14 +1,16 @@
-using UnityEngine;
-using System.Collections;
-
+using UnityEngine;
+using System.Collections;
+
 // A3 50 閫氱煡瀵诲疂缁撴灉 #tagMCTreasureResult
 
 public class HA350_tagMCTreasureResult : GameNetPackBasic {
     public byte TreasureType;    //瀵诲疂绫诲瀷
     public byte TreasureIndex;    //瀵诲疂绱㈠紩
     public byte CostType;    //娑堣�楃被鍨嬶細0-榛樿浠欑帀锛�1-鍏嶈垂娆℃暟锛�2-瀵诲疂閬撳叿
-    public byte AddMoneyType;    // 鏈瀵诲疂澧炲姞鐨勭Н鍒嗚揣甯佺被鍨嬶紝鍙兘涓�0
-    public ushort AddMoneyValue;    // 鏈瀵诲疂澧炲姞鐨勭Н鍒嗚揣甯佸�硷紝鍙兘涓�0
+    public byte AddMoneyType;    // 鏈瀵诲疂棰濆澧炲姞鐨勭Н鍒嗚揣甯佺被鍨嬶紝鍙兘涓�0
+    public ushort AddMoneyValue;    // 鏈瀵诲疂棰濆澧炲姞鐨勭Н鍒嗚揣甯佸�硷紝鍙兘涓�0
+    public uint AddItemID;    // 鏈瀵诲疂棰濆璧犻�佺殑鐗╁搧ID锛屽彲鑳戒负0
+    public uint AddItemCount;    // 鏈瀵诲疂棰濆璧犻�佺殑鐗╁搧ID涓暟锛屽彲鑳戒负0
     public ushort AddTreasureLuck;    // 鏈瀵诲疂澧炲姞鐨勫垢杩愬��
     public ushort TreasureResultLen;
     public string TreasureResult;    //  鑾峰緱鐗╁搧缁撴灉[[鏍煎瓙缂栧彿, 鐗╁搧ID,涓暟,鏄惁缁戝畾], ...]
@@ -23,6 +25,8 @@
         TransBytes (out CostType, vBytes, NetDataType.BYTE);
         TransBytes (out AddMoneyType, vBytes, NetDataType.BYTE);
         TransBytes (out AddMoneyValue, vBytes, NetDataType.WORD);
+        TransBytes (out AddItemID, vBytes, NetDataType.DWORD);
+        TransBytes (out AddItemCount, vBytes, NetDataType.DWORD);
         TransBytes (out AddTreasureLuck, vBytes, NetDataType.WORD);
         TransBytes (out TreasureResultLen, vBytes, NetDataType.WORD);
         TransBytes (out TreasureResult, vBytes, NetDataType.Chars, TreasureResultLen);
diff --git a/Main/Core/NetworkPackage/ServerPack/HA3_Function/HA351_tagMCTreasureInfo.cs b/Main/Core/NetworkPackage/ServerPack/HA3_Function/HA351_tagMCTreasureInfo.cs
index d057c54..764c117 100644
--- a/Main/Core/NetworkPackage/ServerPack/HA3_Function/HA351_tagMCTreasureInfo.cs
+++ b/Main/Core/NetworkPackage/ServerPack/HA3_Function/HA351_tagMCTreasureInfo.cs
@@ -1,6 +1,6 @@
-using UnityEngine;
-using System.Collections;
-
+using UnityEngine;
+using System.Collections;
+
 // A3 51 瀵诲疂鍔熻兘淇℃伅 #tagMCTreasureInfo
 
 public class HA351_tagMCTreasureInfo : GameNetPackBasic {
@@ -20,6 +20,7 @@
             TransBytes (out TreasuerInfoList[i].LuckValue, vBytes, NetDataType.WORD);
             TransBytes (out TreasuerInfoList[i].TreasureCount, vBytes, NetDataType.DWORD);
             TransBytes (out TreasuerInfoList[i].TreasureCountToday, vBytes, NetDataType.DWORD);
+            TransBytes (out TreasuerInfoList[i].TreasureCountTodayGold, vBytes, NetDataType.DWORD);
             TransBytes (out TreasuerInfoList[i].FreeCountToday, vBytes, NetDataType.WORD);
             TransBytes (out TreasuerInfoList[i].TreasureCntAward, vBytes, NetDataType.DWORD);
             TransBytes (out TreasuerInfoList[i].GridLimitCnt, vBytes, NetDataType.BYTE);
@@ -65,6 +66,7 @@
         public ushort LuckValue;        //褰撳墠骞歌繍鍊�
         public uint TreasureCount;        //宸插瀹濇�绘鏁�
         public uint TreasureCountToday;        //浠婃棩宸插瀹濇�绘鏁�
+        public uint TreasureCountTodayGold;        //浠婃棩娑堣�楄揣甯佸凡瀵诲疂鎬绘鏁�
         public ushort FreeCountToday;        //浠婃棩宸插厤璐瑰瀹濇鏁�
         public uint TreasureCntAward;        //绱瀵诲疂娆℃暟瀵瑰簲濂栧姳棰嗗鐘舵�侊紝鎸夊鍔辫褰曠储寮曚簩杩涘埗璁板綍鏄惁宸查鍙�
         public byte GridLimitCnt;
diff --git a/Main/Core/NetworkPackage/ServerPack/HA8_Item/HA801_tagMCGiveAwardInfo.cs b/Main/Core/NetworkPackage/ServerPack/HA8_Item/HA801_tagMCGiveAwardInfo.cs
index 13c33c1..71ad932 100644
--- a/Main/Core/NetworkPackage/ServerPack/HA8_Item/HA801_tagMCGiveAwardInfo.cs
+++ b/Main/Core/NetworkPackage/ServerPack/HA8_Item/HA801_tagMCGiveAwardInfo.cs
@@ -30,6 +30,7 @@
             MoneyList[i] = new tagMCGiveAwardMoney();
             TransBytes (out MoneyList[i].MoneyType, vBytes, NetDataType.BYTE);
             TransBytes (out MoneyList[i].MoneyValue, vBytes, NetDataType.DWORD);
+            TransBytes (out MoneyList[i].IsBind, vBytes, NetDataType.BYTE);
         }
         TransBytes (out ItemLen, vBytes, NetDataType.BYTE);
         ItemList = new tagMCGiveAwardItem[ItemLen];
@@ -47,6 +48,7 @@
     public class tagMCGiveAwardMoney {
         public byte MoneyType;
         public uint MoneyValue;
+        public byte IsBind;        // 鍚岀墿鍝両sBind鏍囪閫昏緫
     }
 
     public class tagMCGiveAwardItem {
diff --git a/Main/Core/NetworkPackage/ServerPack/HA9_Function/HA924_tagSCQunyingMatchList.cs b/Main/Core/NetworkPackage/ServerPack/HA9_Function/HA924_tagSCQunyingMatchList.cs
new file mode 100644
index 0000000..4249ee3
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HA9_Function/HA924_tagSCQunyingMatchList.cs
@@ -0,0 +1,51 @@
+using UnityEngine;
+using System.Collections;
+
+// A9 24 缇よ嫳姒滃尮閰嶇帺瀹跺垪琛� #tagSCQunyingMatchList
+
+public class HA924_tagSCQunyingMatchList : GameNetPackBasic {
+    public byte MatchCount;
+    public  tagSCQunyingMatchInfo[] MatchList;    // 鍖归厤鍒楄〃锛屼粠楂樺垎鍒颁綆鍒�
+
+    public HA924_tagSCQunyingMatchList () {
+        _cmd = (ushort)0xA924;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out MatchCount, vBytes, NetDataType.BYTE);
+        MatchList = new tagSCQunyingMatchInfo[MatchCount];
+        for (int i = 0; i < MatchCount; i ++) {
+            MatchList[i] = new tagSCQunyingMatchInfo();
+            TransBytes (out MatchList[i].Rank, vBytes, NetDataType.WORD);
+            TransBytes (out MatchList[i].PlayerID, vBytes, NetDataType.DWORD);
+            TransBytes (out MatchList[i].PlayerName, vBytes, NetDataType.Chars, 33);
+            TransBytes (out MatchList[i].LV, vBytes, NetDataType.WORD);
+            TransBytes (out MatchList[i].RealmLV, vBytes, NetDataType.WORD);
+            TransBytes (out MatchList[i].FightPower, vBytes, NetDataType.DWORD);
+            TransBytes (out MatchList[i].FightPowerEx, vBytes, NetDataType.DWORD);
+            TransBytes (out MatchList[i].Face, vBytes, NetDataType.DWORD);
+            TransBytes (out MatchList[i].FacePic, vBytes, NetDataType.DWORD);
+            TransBytes (out MatchList[i].TitleID, vBytes, NetDataType.DWORD);
+            TransBytes (out MatchList[i].ModelMark, vBytes, NetDataType.DWORD);
+            TransBytes (out MatchList[i].EquipShowSwitch, vBytes, NetDataType.DWORD);
+            TransBytes (out MatchList[i].ServerID, vBytes, NetDataType.DWORD);
+        }
+    }
+
+    public class tagSCQunyingMatchInfo {
+        public ushort Rank;        //鎺掑悕锛屼粠1寮�濮�
+        public uint PlayerID;        //鐩爣鐜╁ID
+        public string PlayerName;
+        public ushort LV;        // 鐜╁绛夌骇
+        public ushort RealmLV;        //澧冪晫锛屾満鍣ㄤ汉璇诲鐣岃〃鍙栫瓑绾у搴斿鐣�
+        public uint FightPower;        //鎴樺姏姹備綑浜块儴鍒�
+        public uint FightPowerEx;        //鎴樺姏鏁撮櫎浜块儴鍒�
+        public uint Face;        //鍩烘湰鑴稿瀷
+        public uint FacePic;        //澶村儚妗�
+        public uint TitleID;        //绉板彿
+        public uint ModelMark;        //鍙樺舰妯″瀷mark
+        public uint EquipShowSwitch;        //鍏朵粬澶栬淇℃伅
+        public uint ServerID;
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ServerPack/HA9_Function/HA924_tagSCQunyingMatchList.cs.meta b/Main/Core/NetworkPackage/ServerPack/HA9_Function/HA924_tagSCQunyingMatchList.cs.meta
new file mode 100644
index 0000000..aea9af1
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HA9_Function/HA924_tagSCQunyingMatchList.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 641ac365694c83f4db552c0105d7c26f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/HA9_Function/HA925_tagSCQunyingPlayerInfo.cs b/Main/Core/NetworkPackage/ServerPack/HA9_Function/HA925_tagSCQunyingPlayerInfo.cs
new file mode 100644
index 0000000..a58ad17
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HA9_Function/HA925_tagSCQunyingPlayerInfo.cs
@@ -0,0 +1,23 @@
+using UnityEngine;
+using System.Collections;
+
+// A9 25 缇よ嫳姒滅帺瀹朵俊鎭� #tagSCQunyingPlayerInfo
+
+public class HA925_tagSCQunyingPlayerInfo : GameNetPackBasic {
+    public uint RefreshCnt;    // 鏈懆宸插埛鏂板尮閰嶆鏁�
+    public uint LastRecoverTime;    // 涓婃鍏嶈垂鎭㈠鎸戞垬浠ゆ椂闂存埑锛屼负0鏃跺彲涓嶇敤鍊掕鏃�
+    public ushort RankHighest;    // 鍘嗗彶鏈�楂樺悕娆★紝绗�1鍚嶄负鏈�楂�
+    public uint RankSuccAward;    // 鍘嗗彶鏈�楂樺悕娆℃垚灏遍濂栬褰曪紝鎸夊鍔辫褰曠储寮曚綅杩愮畻璁板綍鏄惁宸查鍙�
+
+    public HA925_tagSCQunyingPlayerInfo () {
+        _cmd = (ushort)0xA925;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out RefreshCnt, vBytes, NetDataType.DWORD);
+        TransBytes (out LastRecoverTime, vBytes, NetDataType.DWORD);
+        TransBytes (out RankHighest, vBytes, NetDataType.WORD);
+        TransBytes (out RankSuccAward, vBytes, NetDataType.DWORD);
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ServerPack/HA9_Function/HA925_tagSCQunyingPlayerInfo.cs.meta b/Main/Core/NetworkPackage/ServerPack/HA9_Function/HA925_tagSCQunyingPlayerInfo.cs.meta
new file mode 100644
index 0000000..f8f6256
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HA9_Function/HA925_tagSCQunyingPlayerInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 49ebce4603fc8bd439702371212c21d1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA20_tagSCActSignPlayerInfo.cs b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA20_tagSCActSignPlayerInfo.cs
new file mode 100644
index 0000000..a50112e
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA20_tagSCActSignPlayerInfo.cs
@@ -0,0 +1,21 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 20 娲诲姩绛惧埌濂栧姳淇℃伅 #tagSCActSignPlayerInfo
+
+public class HAA20_tagSCActSignPlayerInfo : GameNetPackBasic {
+    public byte ActType;    // 娲诲姩绫诲瀷
+    public byte ActNum;    // 娲诲姩缂栧彿
+    public uint SignAward;    // 濂栧姳棰嗗彇璁板綍锛屾寜澶╁搴斾簩杩涘埗浣嶈褰曟槸鍚﹀凡棰嗗彇
+
+    public HAA20_tagSCActSignPlayerInfo () {
+        _cmd = (ushort)0xAA20;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out ActType, vBytes, NetDataType.BYTE);
+        TransBytes (out ActNum, vBytes, NetDataType.BYTE);
+        TransBytes (out SignAward, vBytes, NetDataType.DWORD);
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA20_tagSCActSignPlayerInfo.cs.meta b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA20_tagSCActSignPlayerInfo.cs.meta
new file mode 100644
index 0000000..0af6836
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA20_tagSCActSignPlayerInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fda0c7a713e37ea409e3af9e2f896e6a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA21_tagSCActHeroAppearInfo.cs b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA21_tagSCActHeroAppearInfo.cs
new file mode 100644
index 0000000..3ce337e
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA21_tagSCActHeroAppearInfo.cs
@@ -0,0 +1,25 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 21 姝﹀皢鐧诲満娲诲姩淇℃伅 #tagSCActHeroAppearInfo
+
+public class HAA21_tagSCActHeroAppearInfo : GameNetPackBasic {
+    public byte ActType;    // 娲诲姩绫诲瀷锛岀敤浜庡叧鑱旀椿鍔ㄧ浉鍏虫ā鍧楃敤锛屽绛惧埌銆佷换鍔$瓑
+    public byte ActNum;    // 娲诲姩缂栧彿
+    public string StartDate;    // 寮�濮嬫棩鏈� y-m-d
+    public string EndtDate;    // 缁撴潫鏃ユ湡 y-m-d
+    public ushort CfgID;    // 娲诲姩鏃堕棿琛ㄩ厤缃甀D
+
+    public HAA21_tagSCActHeroAppearInfo () {
+        _cmd = (ushort)0xAA21;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out ActType, vBytes, NetDataType.BYTE);
+        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/HAA21_tagSCActHeroAppearInfo.cs.meta b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA21_tagSCActHeroAppearInfo.cs.meta
new file mode 100644
index 0000000..dbd9fa3
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA21_tagSCActHeroAppearInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f19899a717605364295e38a213b7883a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA22_tagSCActHeroAppearPlayerInfo.cs b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA22_tagSCActHeroAppearPlayerInfo.cs
new file mode 100644
index 0000000..dfd2975
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA22_tagSCActHeroAppearPlayerInfo.cs
@@ -0,0 +1,23 @@
+using UnityEngine;
+using System.Collections;
+
+// AA 22 姝﹀皢鐧诲満娲诲姩鐜╁淇℃伅 #tagSCActHeroAppearPlayerInfo
+
+public class HAA22_tagSCActHeroAppearPlayerInfo : GameNetPackBasic {
+    public byte ActNum;    // 娲诲姩缂栧彿
+    public byte StarHeroIndex;    // 鍗囨槦璁″垝閫夋嫨鐨勬灏咺D绱㈠紩
+    public uint StarFreeAward;    // 鍗囨槦璁″垝鍏嶈垂濂栧姳璁板綍锛屾寜濂栧姳璁板綍绱㈠紩浜岃繘鍒朵綅杩愮畻璁板綍鏄惁宸查鍙�
+    public byte CallHeroIndex;    // 鎷涘嫙閫夋嫨鐨勬灏咺D绱㈠紩
+
+    public HAA22_tagSCActHeroAppearPlayerInfo () {
+        _cmd = (ushort)0xAA22;
+    }
+
+    public override void ReadFromBytes (byte[] vBytes) {
+        TransBytes (out ActNum, vBytes, NetDataType.BYTE);
+        TransBytes (out StarHeroIndex, vBytes, NetDataType.BYTE);
+        TransBytes (out StarFreeAward, vBytes, NetDataType.DWORD);
+        TransBytes (out CallHeroIndex, vBytes, NetDataType.BYTE);
+    }
+
+}
diff --git a/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA22_tagSCActHeroAppearPlayerInfo.cs.meta b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA22_tagSCActHeroAppearPlayerInfo.cs.meta
new file mode 100644
index 0000000..07bce47
--- /dev/null
+++ b/Main/Core/NetworkPackage/ServerPack/HAA_SaleActivity/HAA22_tagSCActHeroAppearPlayerInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2b1c2aa4b20f3d84896cc03b007884ec
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/Core/NetworkPackage/ServerPack/HB1_Role/HB122_tagSCHeroInfo.cs b/Main/Core/NetworkPackage/ServerPack/HB1_Role/HB122_tagSCHeroInfo.cs
index d375f2d..be774d9 100644
--- a/Main/Core/NetworkPackage/ServerPack/HB1_Role/HB122_tagSCHeroInfo.cs
+++ b/Main/Core/NetworkPackage/ServerPack/HB1_Role/HB122_tagSCHeroInfo.cs
@@ -1,6 +1,6 @@
-using UnityEngine;
-using System.Collections;
-
+using UnityEngine;
+using System.Collections;
+
 // B1 22 姝﹀皢淇℃伅 #tagSCHeroInfo
 
 public class HB122_tagSCHeroInfo : GameNetPackBasic {
@@ -17,23 +17,29 @@
         for (int i = 0; i < HeroCnt; i ++) {
             HeroInfoList[i] = new tagSCHero();
             TransBytes (out HeroInfoList[i].HeroID, vBytes, NetDataType.DWORD);
-            TransBytes (out HeroInfoList[i].SkinState, vBytes, NetDataType.DWORD);
             TransBytes (out HeroInfoList[i].BookInitState, vBytes, NetDataType.BYTE);
-            TransBytes (out HeroInfoList[i].BookStarLV, vBytes, NetDataType.WORD);
-            TransBytes (out HeroInfoList[i].BookBreakLV, vBytes, NetDataType.WORD);
-            TransBytes (out HeroInfoList[i].BookStarLVH, vBytes, NetDataType.WORD);
-            TransBytes (out HeroInfoList[i].BookBreakLVH, vBytes, NetDataType.WORD);
+            TransBytes (out HeroInfoList[i].SkinCnt, vBytes, NetDataType.BYTE);
+            HeroInfoList[i].SkinList = new tagSCHeroSkin[HeroInfoList[i].SkinCnt];
+            for (int j = 0; j < HeroInfoList[i].SkinCnt; j ++) {
+                HeroInfoList[i].SkinList[j] = new tagSCHeroSkin();
+                TransBytes (out HeroInfoList[i].SkinList[j].SkinID, vBytes, NetDataType.DWORD);
+                TransBytes (out HeroInfoList[i].SkinList[j].State, vBytes, NetDataType.BYTE);
+                TransBytes (out HeroInfoList[i].SkinList[j].Star, vBytes, NetDataType.BYTE);
+            }
         }
     }
 
     public class tagSCHero {
         public uint HeroID;        // 姝﹀皢ID
-        public uint SkinState;        // 姝﹀皢鐨偆宸茶В閿佺姸鎬佷俊鎭紝鎸夌毊鑲ゆ墍鍦ㄧ储寮曚簩杩涘埗浣嶈繍绠楀垽鏂槸鍚﹁В閿侊紝0绱㈠紩浣嶉粯璁ょ毊鑲わ紝涓嶇敤楠岃瘉
         public byte BookInitState;        // 鍥鹃壌婵�娲荤姸鎬侊細0-鏈縺娲伙紱1-鍙縺娲伙紱2-宸叉縺娲�
-        public ushort BookStarLV;        // 鍥鹃壌鏄熺骇绛夌骇
-        public ushort BookBreakLV;        // 鍥鹃壌绐佺牬绛夌骇
-        public ushort BookStarLVH;        // 鍥鹃壌鏄熺骇鍘嗗彶鏈�楂樼瓑绾�
-        public ushort BookBreakLVH;        // 鍥鹃壌绐佺牬鍘嗗彶鏈�楂樼瓑绾�
+        public byte SkinCnt;
+        public  tagSCHeroSkin[] SkinList;        // 闈為粯璁ょ毊鑲や俊鎭垪琛�
+    }
+
+    public class tagSCHeroSkin {
+        public uint SkinID;        //鐨偆ID锛屽彧閫氱煡闈為粯璁ょ毊鑲�
+        public byte State;        //鏄惁宸叉縺娲�
+        public byte Star;        //鏄熺骇
     }
 
 }
diff --git a/Main/Core/SFX.meta b/Main/Core/SFX.meta
deleted file mode 100644
index c3f9aa5..0000000
--- a/Main/Core/SFX.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: 71eda8c469fec56479fe0127b6680bb2
-folderAsset: yes
-DefaultImporter:
-  externalObjects: {}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/Main.cs b/Main/Main.cs
index 4cbd6dc..d728a81 100644
--- a/Main/Main.cs
+++ b/Main/Main.cs
@@ -117,6 +117,11 @@
         managers.Add(TimingGiftManager.Instance);
         managers.Add(SettingDataManager.Instance);
         managers.Add(TimeRushManager.Instance);
+        managers.Add(SmallFuncManager.Instance);
+        managers.Add(HeroDebutManager.Instance);
+        managers.Add(GeneralActInfoManager.Instance);
+        managers.Add(QunyingManager.Instance);
+        managers.Add(ViewBuffManager.Instance);
 
         foreach (var manager in managers)
         {
diff --git a/Main/Manager/UIManager.cs b/Main/Manager/UIManager.cs
index 94da3ac..4ae6aeb 100644
--- a/Main/Manager/UIManager.cs
+++ b/Main/Manager/UIManager.cs
@@ -69,6 +69,8 @@
 
     public Action<UIBase> OnCloseWindow;
 
+    public Action OnAfterSortWinLayer;
+
     #endregion
 
     #region 鍒濆鍖�
@@ -935,7 +937,7 @@
 
             return uiOrderDict[b].CompareTo(uiOrderDict[a]);
         });
-        
+
         // 閬嶅巻鎺掑簭鍚庣殑UI鏁扮粍锛岃缃帓搴忛『搴�
         foreach (var ui in uiArray)
         {
@@ -951,6 +953,7 @@
 
             // Debug.Log(ui.uiName + " order is " + sortingOrder + " " + currentHighestSortingOrder);
         }
+        OnAfterSortWinLayer?.Invoke();
     }
     
     #endregion
diff --git a/Main/SDK/SDKUtils.cs b/Main/SDK/SDKUtils.cs
index 533ee09..218b2ec 100644
--- a/Main/SDK/SDKUtils.cs
+++ b/Main/SDK/SDKUtils.cs
@@ -5,7 +5,6 @@
 using System.Collections.Generic;
 using System.IO;
 using System;
-using Cysharp.Threading.Tasks;
 
 
 public class SDKUtils : SingletonMonobehaviour<SDKUtils>
@@ -22,6 +21,8 @@
         Free = 1,// 榛樿
         Quick = 10, //quick
         Hy = 15, //娆㈡父
+        Gaore = 20, // 20-楂樼儹 - 纭牳娓犻亾
+        Qudong = 21,  //21-瓒e姩 - 娴峰娓犻亾
     }
 
     //鏉冮檺鐢宠鍥炶皟
@@ -55,6 +56,8 @@
     {
         get; private set;
     }
+
+    public static string channelSign = ""; //涓嶅悓娓犻亾鐨勬墦鍖呮爣璇�
 
     // 鏄惁鍚屾剰闅愮鏀跨瓥
     public bool IsAgreeSecret = false;
@@ -130,7 +133,6 @@
 
     public void Init()
     {
-        ynmbxxjUtil.Instance.Init();    // sdk涓存椂鐢紝鍚庣画鏂板仛SDK鍚庡垹闄�
         Device = new DeviceInfo();
         string uid = LocalSave.GetString("Device_uniqueID");
         //Debug.Log(Math.Abs(System.Environment.TickCount));
@@ -166,7 +168,7 @@
         }
         else
         {
-            builtinAssetCopyFinished = VersionConfig.config.version == builtinAssetsCopyFinishVersion;
+            builtinAssetCopyFinished = VersionConfig.Get().version == builtinAssetsCopyFinishVersion;
         }
 #endif
 #if UNITY_IOS || UNITY_STANDALONE
@@ -177,7 +179,7 @@
         }
         else
         {
-            builtinAssetCopyFinished = VersionConfig.config.version == builtinAssetsCopyFinishVersion;
+            builtinAssetCopyFinished = VersionConfig.Get().version == builtinAssetsCopyFinishVersion;
         }
 
         var assetsCopyFinishVersion = LocalSave.GetString("AssetCopyCompleted_IOSorStandalone");
@@ -187,27 +189,19 @@
         }
         else
         {
-            AssetCopyFinished = VersionConfig.config.version == assetsCopyFinishVersion;
+            AssetCopyFinished = VersionConfig.Get().version == assetsCopyFinishVersion;
         }
 
 #elif UNITY_ANDROID
         SyncClientPackageID();
 #endif
 
-        if (Application.platform == RuntimePlatform.WebGLPlayer)
-        {
-            // WebGL 鏃犲師鐢� SDK 鍥炶皟锛岀洿鎺ユ爣璁板畬鎴�
-            InitFinished = true;
-        }
-        else
-        {
-            InitFinished = false;
-            m_Json.Clear();
-            m_Json["code"] = CodeU2A.Init;
-            m_Json["appID"] = VersionConfig.config.appId;
-            m_Json["gameID"] = VersionConfig.config.gameId;
-            SendMessageToSDK(m_Json);
-        }
+        InitFinished = false;
+        m_Json.Clear();
+        m_Json["code"] = CodeU2A.Init;
+        m_Json["appID"] = VersionConfig.Get().appId;
+        m_Json["gameID"] = VersionConfig.Get().gameId;
+        SendMessageToSDK(m_Json);
 #endif
         StartCoroutine("ProcessNetworkStatus");
     }
@@ -329,13 +323,10 @@
     public void SyncClientPackageID()
     {
 #if UNITY_ANDROID
-        VersionConfig.GetAsync().ContinueWith(config =>
-        {
-            m_Json.Clear();
-            m_Json["code"] = CodeU2A.ClientPackage;
-            m_Json["clientPkgID"] = config.clientPackageFlag;
-            SendMessageToSDK(m_Json);
-        }).Forget();
+        m_Json.Clear();
+        m_Json["code"] = CodeU2A.ClientPackage;
+        m_Json["clientPkgID"] = VersionConfig.Get().clientPackageFlag;
+        SendMessageToSDK(m_Json);
 #endif
     }
 
@@ -377,6 +368,13 @@
         SendMessageToSDK(m_Json);
     }
 
+    //璇勫垎
+    public void GoToReview()
+    {
+        m_Json.Clear();
+        m_Json["code"] = CodeU2A.GoToReview;
+        SendMessageToSDK(m_Json);
+    }
     #endregion
 
     #region 澶勭悊涓嶴DK浜や簰鐨勫簳灞傛柟娉�
@@ -410,12 +408,21 @@
 
     private void SendMessageToSDK(JsonData json)
     {
-
 #if !UNITY_EDITOR
 #if UNITY_ANDROID
-        using (AndroidJavaClass H2engineSDK = new AndroidJavaClass("com.wgyx.sdk.UnityMsgHandler"))
+        if (VersionConfig.Get().appId == "sghy")
         {
-            H2engineSDK.CallStatic("onUnityMessage", json.ToJson());
+            using (AndroidJavaClass H2engineSDK = new AndroidJavaClass("com.xssg.sdk.UnityMsgHandler"))
+            {
+                H2engineSDK.CallStatic("onUnityMessage", json.ToJson());
+            }
+        }
+        else
+        {
+            using (AndroidJavaClass H2engineSDK = new AndroidJavaClass("com.wgyx.sdk.UnityMsgHandler"))
+            {
+                H2engineSDK.CallStatic("onUnityMessage", json.ToJson());
+            }
         }
 #elif UNITY_IOS
         AotSdkUtility.IOSUniyMessageHandle(json.ToJson());
@@ -495,7 +502,15 @@
                         {
                             ChannelPlatform = E_ChannelPlatform.Quick;
                         }
-  
+                        else if (_channelPlatform.Equals("gaore"))
+                        {
+                            ChannelPlatform = E_ChannelPlatform.Gaore;
+                        }
+                        else if (_channelPlatform.Equals("sghy"))
+                        {
+                            ChannelPlatform = E_ChannelPlatform.Qudong;
+                        }
+
                     }
                 }
 
@@ -539,6 +554,7 @@
                 }
             case CodeA2U.FreePlatformInitOk:
 
+                channelSign = _json["channelSign"].ToString();
                 if (onFreePlatformInitOk != null)
                 {
                     onFreePlatformInitOk();
@@ -627,6 +643,16 @@
                     Application.Quit();
                 }
                 break;
+            case CodeA2U.GetAdAward:
+                if (AdsManager.Instance.waitAdID > 0)
+                {
+                    AdsManager.Instance.GetAdsAward(AdsManager.Instance.waitAdID);
+                    AdsManager.Instance.waitAdID = 0;
+                }
+                break;
+            case CodeA2U.AdLoadFail:
+                AdsManager.Instance.lastLoadErrorTime = Time.time;
+                break;
         }
         onSdkMsg?.Invoke(_code, _json);
     }
@@ -708,6 +734,8 @@
         public const int PingfenCallBack = 113;  //璇勫垎鍥炶皟 鍜� GotoShopOK 涓嶄竴鏍� 鍏蜂綋鐪嬩娇鐢ㄥ尯鍒�
         public const int GotoShopOK = 115;  //鍓嶅線鍟嗗簵鎴愬姛
         public const int GotoFBOK = 116;
+        public const int GetAdAward = 117;   //骞垮憡鎾斁鎴愬姛鍙戞斁濂栧姳
+        public const int AdLoadFail = 118;   //骞垮憡鍔犺浇澶辫触
         #endregion
     }
 
@@ -786,17 +814,13 @@
         public const int DownloadStart = 110;
         public const int DownloadEnd = 111;
         public const int ShareToFaceBook = 112;
-        public const int GoToPingfen = 113;  //鍓嶅線璇勫垎  鍜� GotoShop = 121; 鏈夊尯鍒�
+        public const int GoToReview = 113;  //鍓嶅線璇勫垎  鍜� GotoShop = 121; 鏈夊尯鍒�
         public const int ShowAccountView = 114;
         public const int RoleLoginOut = 119; //瑙掕壊鐧诲嚭
-        public const int FansHouse = 120; //绮変笣灞� 璁哄潧绛�
-        public const int GotoShop = 121; //鍓嶅線鍟嗗簵
+        // public const int FansHouse = 120; //绮変笣灞� 璁哄潧绛�
+        // public const int GotoShop = 121; //鍓嶅線鍟嗗簵
         public const int TrackEvent = 122; //鑷畾涔変簨浠�
-        /**
-         * 鏋佸厜鎺ㄩ��
-         * */
-        public const int JPushAddLocalMessage = 200;
-        public const int JPushRemoveLocalMessage = 201;
+        public const int PlayAds = 123; //鎾斁骞垮憡
         /**
          * IOS鐗规畩闇�姹�
          */
@@ -836,7 +860,7 @@
         public int totalMemory;
     }
 
-    #region 鑷敱sdk鐩稿叧
+    #region sdk鐩稿叧
 
     public UnityAction onFreePlatformInitOk;
     public UnityAction onFreePlatformInitFail;
@@ -893,17 +917,9 @@
 #endif
     }
 
-    public void FreePlatformBindPhone()
-    {
-#if UNITY_ANDROID
-        AndroidJavaClass _jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
-        AndroidJavaObject _jo = _jc.GetStatic<AndroidJavaObject>("currentActivity");
-        _jo.Call("BindPhone");
-#endif
-    }
 
     /// <summary>
-    /// 鑷敱SDK鐧婚檰
+    /// SDK鐧婚檰
     /// </summary>
     public void FreePlatformLogin()
     {
@@ -912,18 +928,6 @@
         SendMessageToSDK(m_Json);
     }
 
-    public void TencentLogin(string param)
-    {
-#if !UNITY_EDITOR
-        m_Json.Clear();
-        m_Json["code"] = CodeU2A.TencentLogin;
-        if (!string.IsNullOrEmpty(param))
-        {
-            m_Json["param"] = param;
-        }
-        SendMessageToSDK(m_Json);
-#endif
-    }
 
     /// <summary>
     /// 鑷敱SDK鐧诲嚭
@@ -937,31 +941,10 @@
         // FreePlatformLogin();
 #endif
     }
-    public void ShowAccountView()
-    {
-#if !UNITY_EDITOR
-        m_Json.Clear();
-        m_Json["code"] = CodeU2A.ShowAccountView;
-        SendMessageToSDK(m_Json);
-
-        // FreePlatformLogin();
-        
-#endif
-    }
-    public void FreePlatformSwitchAccount()
-    {
-#if UNITY_ANDROID
-        AndroidJavaClass _jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
-        AndroidJavaObject _jo = _jc.GetStatic<AndroidJavaObject>("currentActivity");
-        _jo.Call("SwitchAccount");
-#endif
-    }
-
-    private Dictionary<string, string> m_PaymentTable = new Dictionary<string, string>();
-    private string m_EncodeKey = "03sujm7gerywdvyd5vkkk772rs4by230";
 
 
-    
+
+
 
     /// <summary>
     /// 鑷敱SDK鏀粯 fixed sdk 鏀粯閫昏緫淇敼
@@ -980,44 +963,38 @@
         }
 
 
-
         if (!isBuyGameCash && gameCash >= money * 100)
         {
-            VersionConfig.GetAsync().ContinueWith(config =>
+
+            UIManager.Instance.CloseWindow<GotoChargeWin>();
+            if (DayRemind.Instance.GetDayRemind(DayRemind.DJQTip))
             {
-                UIManager.Instance.CloseWindow<GotoChargeWin>();
-
-
-                if (DayRemind.Instance.GetDayRemind(DayRemind.DJQTip))
-                {
-                    var pack = new CA125_tagCMCoinBuyOrderInfo();
-                    pack.AppID = config.appId;
-                    pack.AppIDLen = (byte)pack.AppID.Length;
-                    pack.OrderInfo = cpInfo;
-                    pack.OrderInfoLen = (byte)pack.OrderInfo.Length;
-                    GameNetSystem.Instance.SendInfo(pack);
-                }
-                else
-                {
-                    ConfirmCancel.ShowPopConfirm(
-                        Language.Get("Mail101"),
-                        Language.Get("GameCashRule1", money, title),
-                        (bool isOk) =>
+                var pack = new CA125_tagCMCoinBuyOrderInfo();
+                pack.AppID = VersionConfig.Get().appId;
+                pack.AppIDLen = (byte)pack.AppID.Length;
+                pack.OrderInfo = cpInfo;
+                pack.OrderInfoLen = (byte)pack.OrderInfo.Length;
+                GameNetSystem.Instance.SendInfo(pack);
+            }
+            else
+            {
+                ConfirmCancel.ShowPopConfirm(
+                    Language.Get("Mail101"),
+                    Language.Get("GameCashRule1", money, title),
+                    (bool isOk) =>
+                    {
+                        if (isOk)
                         {
-                            if (isOk)
-                            {
-                                var pack = new CA125_tagCMCoinBuyOrderInfo();
-                                pack.AppID = config.appId;
-                                pack.AppIDLen = (byte)pack.AppID.Length;
-                                pack.OrderInfo = cpInfo;
-                                pack.OrderInfoLen = (byte)pack.OrderInfo.Length;
-                                GameNetSystem.Instance.SendInfo(pack);
-                            }
+                            var pack = new CA125_tagCMCoinBuyOrderInfo();
+                            pack.AppID = VersionConfig.Get().appId;
+                            pack.AppIDLen = (byte)pack.AppID.Length;
+                            pack.OrderInfo = cpInfo;
+                            pack.OrderInfoLen = (byte)pack.OrderInfo.Length;
+                            GameNetSystem.Instance.SendInfo(pack);
+                        }
 
-                        });
-                }
-            }).Forget();
-
+                    });
+            }
         }
         else
         {
@@ -1045,98 +1022,46 @@
                 }
             }
         }
-//#if !(UNITY_IOS || UNITY_IPHONE)
-//        string storeOrderInfo = orderInfo.StoreOrderInfo;
-//#else
-//        string storeOrderInfo = orderInfo.StoreOrderInfo2;
-//#endif
+        #if !(UNITY_IOS || UNITY_IPHONE)
+               string storeOrderInfo = orderInfo.StoreOrderInfo;
+        #else
+               string storeOrderInfo = orderInfo.StoreOrderInfo2;
+        #endif
 
-        VersionConfig.GetAsync().ContinueWith(config =>
-        {
-            #if UNITY_EDITOR
-                    Debug.LogFormat("鍏呭��: {0}-{1}-{2}", title, money, cpInfo);
-                    return;
-            #endif
+#if UNITY_EDITOR
+        Debug.LogFormat("鍏呭��: {0}-{1}-{2}", title, money, cpInfo);
+        return;
+#endif
 
-                    m_Json.Clear();
-                    m_Json["code"] = CodeU2A.FreePlatformPay;
-                    m_Json["orderId"] = DateTime.Now.ToString("yyyyMMddHHmmss") + UnityEngine.Random.Range(100000, 999999).ToString();
-                    m_Json["mount"] = money.ToString();
-                    m_Json["cpInfo"] = cpInfo;
-                    //m_Json["storeOrderInfo"] = storeOrderInfo;
-                    m_Json["title"] = title;
-                    m_Json["roleID"] = PlayerDatas.Instance.baseData.PlayerID;
-                    m_Json["roleName"] = PlayerDatas.Instance.baseData.PlayerName;
-                    m_Json["level"] = PlayerDatas.Instance.baseData.LV.ToString();
-                    m_Json["sid"] = ServerListCenter.Instance.currentServer.region_flag;
-                    m_Json["serverName"] = ServerListCenter.Instance.currentServer.name;
-                    m_Json["familyName"] = PlayerDatas.Instance.baseData.FamilyName;
-                    m_Json["job"] = PlayerDatas.Instance.baseData.Job.ToString();
-                    m_Json["money"] = PlayerDatas.Instance.baseData.diamond.ToString();
-                    m_Json["gameName"] = config.productName;
-                    m_Json["vipLevel"] = PlayerDatas.Instance.baseData.VIPLv.ToString();
-                    m_Json["createTime"] = TimeUtility.CreateSeconds.ToString();
-                    m_Json["familyID"] = PlayerDatas.Instance.baseData.FamilyId.ToString();
-                    m_Json["fightPower"] = PlayerDatas.Instance.baseData.FightPower.ToString();
+        m_Json.Clear();
+        m_Json["code"] = CodeU2A.FreePlatformPay;
+        m_Json["orderId"] = DateTime.Now.ToString("yyyyMMddHHmmss") + UnityEngine.Random.Range(100000, 999999).ToString();
+        m_Json["mount"] = money.ToString();
+        m_Json["cpInfo"] = cpInfo;
+        m_Json["storeOrderInfo"] = storeOrderInfo;
+        m_Json["title"] = title;
+        m_Json["roleID"] = PlayerDatas.Instance.baseData.PlayerID;
+        m_Json["roleName"] = PlayerDatas.Instance.baseData.PlayerName;
+        m_Json["level"] = PlayerDatas.Instance.baseData.LV.ToString();
+        m_Json["sid"] = ServerListCenter.Instance.currentServer.region_flag;
+        m_Json["serverName"] = ServerListCenter.Instance.currentServer.name;
+        m_Json["familyName"] = PlayerDatas.Instance.baseData.FamilyName;
+        m_Json["job"] = PlayerDatas.Instance.baseData.Job.ToString();
+        m_Json["money"] = PlayerDatas.Instance.baseData.diamond.ToString();
+        m_Json["gameName"] = VersionConfig.Get().productName;
+        m_Json["vipLevel"] = PlayerDatas.Instance.baseData.VIPLv.ToString();
+        m_Json["createTime"] = TimeUtility.CreateSeconds.ToString();
+        m_Json["familyID"] = PlayerDatas.Instance.baseData.FamilyId.ToString();
+        m_Json["fightPower"] = PlayerDatas.Instance.baseData.FightPower.ToString();
+        m_Json["num"] = 1;
 
-            #if UNITY_IOS
-                    m_Json["identifier"] = config.bundleIdentifier;
-            #endif
-                    SendMessageToSDK(m_Json);
-        }).Forget();
-
-
+#if UNITY_IOS
+        m_Json["identifier"] = VersionConfig.Get().bundleIdentifier;
+#endif
+        SendMessageToSDK(m_Json);
     }
 
 
-    /// <summary>
-    ///  鍒嗕韩鍒癴acebook
-    /// /// </summary>
-    public void ShareToFaceBook(int type)
-    {
-        // Debug.Log("瓒婂崡鍒嗕韩");
-        // m_Json.Clear();
-        // m_Json["code"] = CodeU2A.ShareToFaceBook;
-        // m_Json["type"] = type;
-        // SendMessageToSDK(m_Json);
-    }
-
-    /// <summary>
-    /// 鍘诲晢搴楄瘎璁�
-    /// </summary>
-    public void GoToPingfen()
-    {
-        // Debug.Log("瓒婂崡璇勫垎");
-        // m_Json.Clear();
-        // m_Json["code"] = CodeU2A.GoToPingfen;
-        // SendMessageToSDK(m_Json);
-    }
-
-    //鍓嶅線鍟嗗簵
-    public void GoToShop()
-    {
-        // m_Json.Clear();
-        // m_Json["code"] = CodeU2A.GotoShop;
-        // SendMessageToSDK(m_Json);
-    }
-
-
-    /**
-     * @param context
-     * @param event 浜嬩欢鍚�
-     * @param value 浜嬩欢鍊硷紝濡傛灉娌℃湁鍙互浼�""
-     * @param isRepeatReport 鏄惁閲嶅涓婃姤銆傛牴鎹繍钀ラ渶姹傛槸鍚︽帓閲嶄笂鎶ワ紝true鍙互閲嶅涓婃姤锛宖alse浠呬笂鎶ヤ竴娆�
-     */
-    public void TraceEvent(string eventName, string value, bool isRepeatReport)
-    {
-        // Debug.Log("瓒婂崡浜嬩欢姹囨姤 锛�" + eventName);
-        // m_Json.Clear();
-        // m_Json["code"] = CodeU2A.TrackEvent;
-        // m_Json["eventName"] = eventName;
-        // m_Json["value"] = value;
-        // m_Json["isRepeatReport"] = isRepeatReport;
-        // SendMessageToSDK(m_Json);
-    }
 
     private void BuildFreePlatformInfo(JsonData json)
     {
@@ -1190,10 +1115,6 @@
         FreePlatformInfo.phone = 0;
     }
 
-    private void HandleFreePlatformRegisteOk(JsonData json)
-    {
-        // BuildFreePlatformInfo(json);
-    }
 
     private void HandleFreePlatformLoginOk(JsonData data)
     {
@@ -1206,46 +1127,6 @@
         }
     }
 
-
-    // public void OnServerChargeOk(HA106_tagMCCoinToGoldReport pack)
-    // {
-    //     string orderID = pack.OrderID;
-    //     uint coin = pack.Coin;
-    //     OperationLogCollect.Instance.RecordEvent(9, coin);
-
-    //     if (onFreePlatformPayOk != null)
-    //     {
-    //         onFreePlatformPayOk();
-    //     }
-
-    //     m_Json.Clear();
-    //     m_Json["code"] = CodeU2A.PayFinished;
-    //     m_Json["orderID"] = orderID;
-    //     m_Json["payType"] = "_default_";
-    //     m_Json["moneyType"] = "CNY";
-    //     m_Json["money"] = (float)coin / 100;
-    //     SendMessageToSDK(m_Json);
-    // }
-
-    public void SendRegistEvent(bool _ok, string _result)
-    {
-        if (_ok)
-        {
-            if (!_result.Equals("0"))
-            {
-                m_Json.Clear();
-                m_Json["code"] = CodeU2A.SendRegistEvent;
-                SendMessageToSDK(m_Json);
-            }
-        }
-    }
-
-    public void SendLoginEvent()
-    {
-        m_Json.Clear();
-        m_Json["code"] = CodeU2A.SendLoginEvent;
-        SendMessageToSDK(m_Json);
-    }
 
     public void SendHideFloatWin()
     {
@@ -1263,26 +1144,29 @@
 
     public void CreateRoleOk(string roleID, string roleName, string time)
     {
-        VersionConfig.GetAsync().ContinueWith(config =>
+        if (VersionConfig.Get().appId == "ryzj")
         {
-            m_Json.Clear();
-            m_Json["code"] = CodeU2A.CreateRole;
+            SendGaoreEvent(2);
+            return;
+        }
 
-            m_Json["roleID"] = roleID;
-            m_Json["roleName"] = roleName;
-            m_Json["sid"] = ServerListCenter.Instance.currentServer.region_flag;
-            m_Json["serverName"] = ServerListCenter.Instance.currentServer.name;
-            m_Json["familyName"] = PlayerDatas.Instance.baseData.FamilyName;
-            m_Json["level"] = "1";
-            m_Json["job"] = PlayerDatas.Instance.baseData.Job.ToString();
-            m_Json["money"] = PlayerDatas.Instance.baseData.diamond.ToString();
-            m_Json["gameName"] = config.productName;
-            m_Json["vipLevel"] = PlayerDatas.Instance.baseData.VIPLv.ToString();
-            m_Json["createTime"] = time;
-            m_Json["familyID"] = PlayerDatas.Instance.baseData.FamilyId.ToString();
-            m_Json["fightPower"] = PlayerDatas.Instance.baseData.FightPower.ToString();
-            SendMessageToSDK(m_Json);
-        }).Forget();
+        m_Json.Clear();
+        m_Json["code"] = CodeU2A.CreateRole;
+
+        m_Json["roleID"] = roleID;
+        m_Json["roleName"] = roleName;
+        m_Json["sid"] = ServerListCenter.Instance.currentServer.region_flag;
+        m_Json["serverName"] = ServerListCenter.Instance.currentServer.name;
+        m_Json["familyName"] = PlayerDatas.Instance.baseData.FamilyName;
+        m_Json["level"] = "1";
+        m_Json["job"] = PlayerDatas.Instance.baseData.Job.ToString();
+        m_Json["money"] = PlayerDatas.Instance.baseData.diamond.ToString();
+        m_Json["gameName"] = VersionConfig.Get().productName;
+        m_Json["vipLevel"] = PlayerDatas.Instance.baseData.VIPLv.ToString();
+        m_Json["createTime"] = time;
+        m_Json["familyID"] = PlayerDatas.Instance.baseData.FamilyId.ToString();
+        m_Json["fightPower"] = PlayerDatas.Instance.baseData.FightPower.ToString();
+        SendMessageToSDK(m_Json);
     }
 
     public void DownloadStart()
@@ -1303,51 +1187,153 @@
 
     public void RoleLogin()
     {
-        VersionConfig.GetAsync().ContinueWith(config =>
+        if (VersionConfig.Get().appId == "ryzj")
         {
-            m_Json.Clear();
-            m_Json["code"] = CodeU2A.RoleLogin;
+            SendGaoreEvent(3);
+            return;
+        }
+        m_Json.Clear();
+        m_Json["code"] = CodeU2A.RoleLogin;
 
-            m_Json["roleID"] = PlayerDatas.Instance.baseData.PlayerID.ToString();
-            m_Json["roleName"] = PlayerDatas.Instance.baseData.PlayerName;
-            m_Json["sid"] = ServerListCenter.Instance.currentServer.region_flag;
-            m_Json["serverName"] = ServerListCenter.Instance.currentServer.name;
-            m_Json["familyName"] = PlayerDatas.Instance.baseData.FamilyName;
-            m_Json["level"] = PlayerDatas.Instance.baseData.LV;
-            m_Json["job"] = PlayerDatas.Instance.baseData.Job.ToString();
-            m_Json["money"] = PlayerDatas.Instance.baseData.diamond.ToString();
-            m_Json["gameName"] = config.productName;
-            m_Json["vipLevel"] = PlayerDatas.Instance.baseData.VIPLv.ToString();
-            m_Json["createTime"] = TimeUtility.CreateSeconds.ToString();
-            m_Json["familyID"] = PlayerDatas.Instance.baseData.FamilyId.ToString();
-            m_Json["fightPower"] = PlayerDatas.Instance.baseData.FightPower.ToString();
-            SendMessageToSDK(m_Json);
-        }).Forget();
+        m_Json["roleID"] = PlayerDatas.Instance.baseData.PlayerID.ToString();
+        m_Json["roleName"] = PlayerDatas.Instance.baseData.PlayerName;
+        m_Json["sid"] = ServerListCenter.Instance.currentServer.region_flag;
+        m_Json["serverName"] = ServerListCenter.Instance.currentServer.name;
+        m_Json["familyName"] = PlayerDatas.Instance.baseData.FamilyName;
+        m_Json["level"] = PlayerDatas.Instance.baseData.LV;
+        m_Json["job"] = PlayerDatas.Instance.baseData.Job.ToString();
+        m_Json["money"] = PlayerDatas.Instance.baseData.diamond.ToString();
+        m_Json["gameName"] = VersionConfig.Get().productName;
+        m_Json["vipLevel"] = PlayerDatas.Instance.baseData.VIPLv.ToString();
+        m_Json["createTime"] = TimeUtility.CreateSeconds.ToString();
+        m_Json["familyID"] = PlayerDatas.Instance.baseData.FamilyId.ToString();
+        m_Json["fightPower"] = PlayerDatas.Instance.baseData.FightPower.ToString();
+        SendMessageToSDK(m_Json);
+    }
+
+
+    //浜嬩欢鍚嶇О 鐢辫繍钀ユ彁渚�
+    //蹇呬紶鐨�2涓簨浠讹紝
+    // "tutorial_complete" 瀹屾垚鏂版墜寮曞銆�
+    // "AchieveLevel_40"  鍒拌揪40绾�
+    void SendOverSeaTraceEvent(string eventName, string value = "")
+    {
+        //娴峰瓒e姩鐗堟湰锛屽鏈夊叾浠栨捣澶栦笉鍚岄渶鍖哄垎
+        m_Json.Clear();
+        m_Json["code"] = CodeU2A.TrackEvent;
+        m_Json["eventName"] = eventName;
+        m_Json["value"] = value;
+
+        SendMessageToSDK(m_Json);
+    }
+
+
+    //楂樼儹鐗堟湰
+    void SendGaoreEvent(int dataType, string pageType = "鏃�", string pageName = "鏃�", string pageItemId = "鏃�",
+        int money = 0, string orderID = "")
+    {
+        m_Json.Clear();
+        m_Json["code"] = CodeU2A.TrackEvent;
+        m_Json["dataType"] = dataType;
+        m_Json["sid"] = ServerListCenter.Instance.currentServer.region_flag;
+        m_Json["serverName"] = ServerListCenter.Instance.currentServer.name;
+        m_Json["roleName"] = PlayerDatas.Instance.baseData.PlayerName;
+        m_Json["level"] = PlayerDatas.Instance.baseData.LV;
+        m_Json["roleID"] = PlayerDatas.Instance.baseData.PlayerID;
+        m_Json["orderId"] = orderID;
+        m_Json["mount"] = money;    //鍏呭�煎垎
+        m_Json["money"] = PlayerDatas.Instance.baseData.diamond;
+        m_Json["createTime"] = TimeUtility.CreateSeconds < 0 ? 0 : TimeUtility.CreateSeconds;
+        m_Json["familyID"] = PlayerDatas.Instance.baseData.FamilyId;
+        m_Json["familyName"] = PlayerDatas.Instance.baseData.FamilyName;
+        m_Json["familyLV"] = PlayerDatas.Instance.fairyData.fairy != null ? PlayerDatas.Instance.fairyData.fairy.FamilyLV.ToString() : "0";
+        m_Json["familyLeaderName"] = PlayerDatas.Instance.fairyData.fairy != null ? PlayerDatas.Instance.fairyData.fairy.LeaderName : "";
+        m_Json["fightPower"] = PlayerDatas.Instance.baseData.FightPower;
+        m_Json["job"] = 0;
+        m_Json["jobName"] = "鏃�";
+        m_Json["sex"] = "鏃�";
+        m_Json["jobID"] = 0;
+        m_Json["jobIDName"] = "鏃�";
+        m_Json["vipLevel"] = 0;
+        if (PlayerDatas.Instance.fairyData.mine != null && PlayerDatas.Instance.fairyData.mine.FmLV > 0)
+        {
+            if (PlayerDatas.Instance.fairyData.mine.FmLV == 3)
+            {
+                m_Json["faimilyRoleID"] = 1;
+            }
+            else if (PlayerDatas.Instance.fairyData.mine.FmLV == 2)
+            {
+                m_Json["faimilyRoleID"] = 2;
+            }
+            else
+            {
+                m_Json["faimilyRoleID"] = 3;
+            }
+
+            m_Json["faimilyRoleName"] = RichTextMsgReplaceConfig.GetRichReplace("FAMILY", PlayerDatas.Instance.fairyData.mine.FmLV);
+        }
+        else
+        {
+            m_Json["faimilyRoleID"] = 0;
+            m_Json["faimilyRoleName"] = "鏃�";
+        }
+        m_Json["opentime"] = TimeUtility.openServerTick;
+        m_Json["pageType"] = pageType;
+        m_Json["pageName"] = pageName;
+        m_Json["pageItemId"] = pageItemId;
+
+        SendMessageToSDK(m_Json);
+
+    }
+
+    //浜嬩欢璁板綍
+    public void SendTraceEvent(int dataType, string pageType = "鏃�", string pageName = "鏃�", string pageItemId = "鏃�",
+        int money = 0, string orderID = "")
+    {
+        var appID = VersionConfig.Get().appId;
+        if (VersionConfig.Get().appId == "ryzj")
+        {
+            SendGaoreEvent(dataType, pageType, pageName, pageItemId, money, orderID);
+            return;
+        }
+        else if (appID == "sghy")
+        {
+            SendOverSeaTraceEvent("tutorial_complete");
+        }
     }
 
     public void RoleLevelUp()
     {
-        VersionConfig.GetAsync().ContinueWith(config =>
+        var appID = VersionConfig.Get().appId;
+        if (appID == "ryzj")
         {
-            m_Json.Clear();
-            m_Json["code"] = CodeU2A.RoleLevelUp;
+            SendGaoreEvent(4);
+            return;
+        }
+        else if (appID == "sghy" && PlayerDatas.Instance.baseData.LV == 40)
+        {
+            SendOverSeaTraceEvent("AchieveLevel_40");
+        }
 
-            m_Json["roleID"] = PlayerDatas.Instance.PlayerId.ToString();
-            m_Json["roleName"] = PlayerDatas.Instance.baseData.PlayerName;
-            m_Json["sid"] = ServerListCenter.Instance.currentServer.region_flag;
-            m_Json["serverName"] = ServerListCenter.Instance.currentServer.name;
-            m_Json["familyName"] = PlayerDatas.Instance.baseData.FamilyName;
-            m_Json["level"] = PlayerDatas.Instance.baseData.LV;
-            m_Json["job"] = PlayerDatas.Instance.baseData.Job.ToString();
-            m_Json["money"] = PlayerDatas.Instance.baseData.diamond.ToString();
-            m_Json["gameName"] = config.productName;
-            m_Json["vipLevel"] = PlayerDatas.Instance.baseData.VIPLv.ToString();
-            m_Json["levelUpTime"] = TimeUtility.AllSeconds.ToString();
-            m_Json["createTime"] = TimeUtility.CreateSeconds.ToString();
-            m_Json["familyID"] = PlayerDatas.Instance.baseData.FamilyId.ToString();
-            m_Json["fightPower"] = PlayerDatas.Instance.baseData.FightPower.ToString();
-            SendMessageToSDK(m_Json);
-        }).Forget();
+
+        m_Json.Clear();
+        m_Json["code"] = CodeU2A.RoleLevelUp;
+
+        m_Json["roleID"] = PlayerDatas.Instance.PlayerId.ToString();
+        m_Json["roleName"] = PlayerDatas.Instance.baseData.PlayerName;
+        m_Json["sid"] = ServerListCenter.Instance.currentServer.region_flag;
+        m_Json["serverName"] = ServerListCenter.Instance.currentServer.name;
+        m_Json["familyName"] = PlayerDatas.Instance.baseData.FamilyName;
+        m_Json["level"] = PlayerDatas.Instance.baseData.LV;
+        m_Json["job"] = PlayerDatas.Instance.baseData.Job.ToString();
+        m_Json["money"] = PlayerDatas.Instance.baseData.diamond.ToString();
+        m_Json["gameName"] = VersionConfig.Get().productName;
+        m_Json["vipLevel"] = PlayerDatas.Instance.baseData.VIPLv.ToString();
+        m_Json["levelUpTime"] = TimeUtility.AllSeconds.ToString();
+        m_Json["createTime"] = TimeUtility.CreateSeconds.ToString();
+        m_Json["familyID"] = PlayerDatas.Instance.baseData.FamilyId.ToString();
+        m_Json["fightPower"] = PlayerDatas.Instance.baseData.FightPower.ToString();
+        SendMessageToSDK(m_Json);
     }
 
 
@@ -1355,87 +1341,60 @@
     {
         if (PlayerDatas.Instance.PlayerId == 0)
             return;
-        
-        if (!DTC0403_tagPlayerLoginLoadOK.finishedLogin) 
+
+        if (!DTC0403_tagPlayerLoginLoadOK.finishedLogin)
             return;
-
-        VersionConfig.GetAsync().ContinueWith(config =>
+        if (VersionConfig.Get().appId == "ryzj")
         {
-            m_Json.Clear();
-            m_Json["code"] = CodeU2A.RoleLoginOut;
+            SendGaoreEvent(5);
+            return;
+        }
 
-            m_Json["roleID"] = PlayerDatas.Instance.PlayerId.ToString();
-            m_Json["roleName"] = PlayerDatas.Instance.baseData.PlayerName;
-            m_Json["sid"] = ServerListCenter.Instance.currentServer.region_flag;
-            m_Json["serverName"] = ServerListCenter.Instance.currentServer.name;
-            m_Json["familyName"] = PlayerDatas.Instance.baseData.FamilyName;
-            m_Json["level"] = PlayerDatas.Instance.baseData.LV;
-            m_Json["job"] = PlayerDatas.Instance.baseData.Job.ToString();
-            m_Json["money"] = PlayerDatas.Instance.baseData.diamond.ToString();
-            m_Json["gameName"] = config.productName;
-            m_Json["vipLevel"] = PlayerDatas.Instance.baseData.VIPLv.ToString();
-            m_Json["levelUpTime"] = TimeUtility.AllSeconds.ToString();
-            m_Json["createTime"] = TimeUtility.CreateSeconds.ToString();
-            m_Json["familyID"] = PlayerDatas.Instance.baseData.FamilyId.ToString();
-            m_Json["fightPower"] = PlayerDatas.Instance.baseData.FightPower.ToString();
-            SendMessageToSDK(m_Json);
-        }).Forget();
-    }
 
-    public void GotoFansHouse()
-    {
-        Debug.Log("瓒婂崡鐐硅禐");
         m_Json.Clear();
-        m_Json["code"] = CodeU2A.FansHouse;
+        m_Json["code"] = CodeU2A.RoleLoginOut;
 
+        m_Json["roleID"] = PlayerDatas.Instance.PlayerId.ToString();
+        m_Json["roleName"] = PlayerDatas.Instance.baseData.PlayerName;
+        m_Json["sid"] = ServerListCenter.Instance.currentServer.region_flag;
+        m_Json["serverName"] = ServerListCenter.Instance.currentServer.name;
+        m_Json["familyName"] = PlayerDatas.Instance.baseData.FamilyName;
+        m_Json["level"] = PlayerDatas.Instance.baseData.LV;
+        m_Json["job"] = PlayerDatas.Instance.baseData.Job.ToString();
+        m_Json["money"] = PlayerDatas.Instance.baseData.diamond.ToString();
+        m_Json["gameName"] = VersionConfig.Get().productName;
+        m_Json["vipLevel"] = PlayerDatas.Instance.baseData.VIPLv.ToString();
+        m_Json["levelUpTime"] = TimeUtility.AllSeconds.ToString();
+        m_Json["createTime"] = TimeUtility.CreateSeconds.ToString();
+        m_Json["familyID"] = PlayerDatas.Instance.baseData.FamilyId.ToString();
+        m_Json["fightPower"] = PlayerDatas.Instance.baseData.FightPower.ToString();
         SendMessageToSDK(m_Json);
     }
 
-#endregion
 
-    #region 鎻掍欢鐩稿叧
 
     #endregion
 
-    #region 鏋佸厜鎺ㄩ�佺浉鍏�
-    public void GeTui_SendLocalMessage(JsonData jsonData)
+    #region 骞垮憡
+    //type涓�0绔嬪嵆鎾斁瑙嗛锛�1涓洪鍔犺浇
+    public void PlayAds(string adid)
     {
-        return;
-        Debug.Log("GeTui_SendLocalMessage:" + jsonData["id"]);
-        //      ------ 涓句緥 ------
-        //		JsonData _params = new JsonData ();
-        //		_params ["code"] = 2005;
-        //		_params ["id"] = 5;// id 閲嶈, 鏍囩ず姣忎釜閫氱煡鐨勬洿鏂版垨鑰呯Щ闄�
-        //		_params ["title"] = "the title";// 鎺ㄩ�佹爣棰�
-        //		_params ["subtitle"] = "the subtitle";// 鍓爣棰�
-        //		_params ["content"] = "the content";// 鍏蜂綋鍐呭
-        //		_params ["badge"] = -1;// 瑙掓爣
-        //
-        //		// 浠ヤ笅涓哄喅瀹氬簲璇ュ涔呭悗寮瑰嚭姝ら�氱煡
-        //		System.TimeSpan ts = System.DateTime.UtcNow - new System.DateTime (1970, 1, 1, 0, 0, 0, 0);
-        //		long ret = System.Convert.ToInt64 (ts.TotalSeconds) + 3;// 琛ㄧず3绉掑悗
-        //		_params ["fireTime"] = ret;
-#if !UNITY_EDITOR
-        jsonData["code"] = CodeU2A.JPushAddLocalMessage;
-#if UNITY_ANDROID
-        jsonData["fireTime"] = (long)jsonData["fireTime"] * 1000;
-#endif
-        SendMessageToSDK(jsonData);
-#endif
-    }
-
-    public void GeTui_RemoveLocalMessage(string id)
-    {
-        return;
-        Debug.Log("GeTui_RemoveLocalMessage:" + id);
-#if !UNITY_EDITOR
         m_Json.Clear();
-        m_Json["code"] = CodeU2A.JPushRemoveLocalMessage;
-        m_Json["id"] = id;// id 閲嶈, 鏍囩ず姣忎釜閫氱煡鐨勬洿鏂版垨鑰呯Щ闄�
-
+        m_Json["code"] = CodeU2A.PlayAds;
+        m_Json["adid"] = adid;
+        m_Json["type"] = 0;
         SendMessageToSDK(m_Json);
-#endif
     }
 
+    //鎵撳紑甯﹀箍鍛婄殑鐣岄潰 鎻愬墠鍔犺浇
+    public void LoadAds(string adid)
+    {
+        m_Json.Clear();
+        m_Json["code"] = CodeU2A.PlayAds;
+        m_Json["adid"] = adid;
+        m_Json["type"] = 1;
+        SendMessageToSDK(m_Json);
+    }
     #endregion
+
 }
diff --git a/Main/SDK/ynmbxxjUtil.cs b/Main/SDK/ynmbxxjUtil.cs
deleted file mode 100644
index 1a8b98d..0000000
--- a/Main/SDK/ynmbxxjUtil.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-锘�// sdk涓存椂鐢紝鍚庣画鏂板仛SDK鍚庡垹闄�
-public class ynmbxxjUtil : SingletonMonobehaviour<ynmbxxjUtil>
-{
-    public void HandleMsgWithSDK(string jsonString)
-    {
-        SDKUtils.Instance.HandleMsgWithSDK(jsonString);
-    }
-
-    public void Init()
-    { }
-}
diff --git a/Main/SDK/ynmbxxjUtil.cs.meta b/Main/SDK/ynmbxxjUtil.cs.meta
deleted file mode 100644
index 6660680..0000000
--- a/Main/SDK/ynmbxxjUtil.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: d69a5f50b06dc814ea13cb20acd59e3a
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Main/System/Arena/ArenaChallengeCell.cs b/Main/System/Arena/ArenaChallengeCell.cs
index 8a2dc2c..01f3435 100644
--- a/Main/System/Arena/ArenaChallengeCell.cs
+++ b/Main/System/Arena/ArenaChallengeCell.cs
@@ -45,7 +45,7 @@
         txtFightPoint.text = UIHelper.ReplaceLargeArtNum(arenaMatchInfo.FightPower);
         txtAddScore.text = Language.Get("Arena16", ArenaManager.Instance.GetChallengePoints(index));
 
-        officialTitleCell.InitUI(arenaMatchInfo.RealmLV, (int)arenaMatchInfo.TitleID);
+        officialTitleCell.InitUI(arenaMatchInfo.RealmLV, (int)arenaMatchInfo.TitleID, 0.55f);
 
         int[][] rewards = ArenaManager.Instance.fixedChallengeRewards;
         for (int i = 0; i < itemCells.Count; i++)
diff --git a/Main/System/Arena/ArenaRecordCell.cs b/Main/System/Arena/ArenaRecordCell.cs
index a362d67..3e1f4dc 100644
--- a/Main/System/Arena/ArenaRecordCell.cs
+++ b/Main/System/Arena/ArenaRecordCell.cs
@@ -74,7 +74,7 @@
         });
         txtName.text = arenaGameRec.Name;
         txtFightPoint.text = UIHelper.ReplaceLargeArtNum(arenaGameRec.FightPower);
-        officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
+        officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID, 0.55f);
         imgMoneyIcon.SetIconWithMoneyType(ArenaManager.Instance.ChallengeMoneyType);
         txtNeedCount.text = ArenaManager.Instance.NeedChallengeMoneyCnt.ToString();
     }
diff --git a/Main/System/Battle/BattleConst.cs b/Main/System/Battle/BattleConst.cs
index daa8f69..a9d3552 100644
--- a/Main/System/Battle/BattleConst.cs
+++ b/Main/System/Battle/BattleConst.cs
@@ -13,6 +13,8 @@
         typeof(BoneFieldBattleWin),
         typeof(TianziBillboradBattleWin),
         typeof(WarlordPavilionBattleWin),
+        typeof(PreviewBattleWin),
+        typeof(QYBattleWin),
     };
 
     // 鎴樺満鍚嶇О
@@ -22,6 +24,8 @@
     public const string BoneBattleField = "BoneBattleField";
     public const string TianziBillboradBattleField = "TianziBillboradBattleField";
     public const string WarlordPavilionBattleField = "WarlordPavilionBattleField";
+    public const string PriviewBattleField = "PriviewBattleField";  //棰勮鎴樻枟
+    public const string QYBattleField = "QYBattleField";
 
     public static Dictionary<string, string> battleNameToWinName = new Dictionary<string, string>()
     {
@@ -31,8 +35,11 @@
         { BoneBattleField, "BoneFieldBattleWin" },
         { TianziBillboradBattleField, "TianziBillboradBattleWin" },
         { WarlordPavilionBattleField, "WarlordPavilionBattleWin" },
+        { PriviewBattleField, "PreviewBattleWin" },
+        { QYBattleField, "QYBattleWin" },
     };
 
+    // 绱㈠紩閰嶇疆鐢�
     public static Dictionary<string, int> FieldNameToIndex = new Dictionary<string, int>()
     {
         { StoryBossBattleField, 1 },
@@ -40,6 +47,8 @@
         { BoneBattleField, 3},
         { TianziBillboradBattleField, 4 },
         { WarlordPavilionBattleField, 5 },
+        { PriviewBattleField, 6 },
+        { QYBattleField, 7 },
     };
 
     //鍜� CreateBattleField 閲岀殑瀵瑰簲
@@ -51,12 +60,15 @@
         {30010, BoneBattleField},
         {30020, TianziBillboradBattleField},
         {30030, WarlordPavilionBattleField},
+        {30000, PriviewBattleField},
+        {32000, QYBattleField},
     };
 
     //pvp鎴樻枟鐨勬垬鍦猴紝涓嶅湪杩欎釜鍒楄〃鐨勮涓簆ve绫诲瀷鐨勬垬鍦�
     public static List<string> pvpBattleNameDic = new List<string>()
     {
         ArenaBattleField,
+        QYBattleField,
     };
 
     
diff --git a/Main/System/Battle/BattleField/BattleField.cs b/Main/System/Battle/BattleField/BattleField.cs
index fe6bee2..3c8fae0 100644
--- a/Main/System/Battle/BattleField/BattleField.cs
+++ b/Main/System/Battle/BattleField/BattleField.cs
@@ -159,6 +159,8 @@
         battleEffectMgr.Init(this);
         battleTweenMgr.Init(this);
         recordPlayer.Init(this);
+        soundManager.Init();
+
 
         if (blueTeamList == null)
         {
@@ -371,6 +373,7 @@
         battleEffectMgr.Release();
         battleTweenMgr.Release();
         recordPlayer.Release();
+        soundManager.Release();
 
         // 娓呯悊姝讳骸澶勭悊璁板綍
         processingDeathObjIds.Clear();
diff --git a/Main/System/Battle/BattleField/PriviewBattleField.cs b/Main/System/Battle/BattleField/PriviewBattleField.cs
new file mode 100644
index 0000000..5e496a9
--- /dev/null
+++ b/Main/System/Battle/BattleField/PriviewBattleField.cs
@@ -0,0 +1,75 @@
+using LitJson;
+using System.Collections.Generic;
+using System.Linq;
+
+public class PriviewBattleField : BattleField
+{
+    public PriviewBattleField(string _guid) : base(_guid)
+    {
+
+    }
+
+    public override void Init(int MapID, int FuncLineID, JsonData _extendData,
+        List<TeamBase> _redTeamList, List<TeamBase> _blueTeamList, byte turnMax)
+    {
+        base.Init(MapID, FuncLineID, extendData, _redTeamList, _blueTeamList, turnMax);
+
+        SetBattleMode(BattleMode.Record);
+    }
+
+    public override void AutoSetBattleMode()
+    {
+        SetBattleMode(BattleMode.Record);
+    }
+
+    public override void TurnFightState(int TurnNum, int State,
+        uint FuncLineID, JsonData extendData)
+    {
+        base.TurnFightState(TurnNum, State, FuncLineID, extendData);
+
+    }
+
+    protected override void OnSettlement(JsonData turnFightStateData)
+    {
+        base.OnSettlement(turnFightStateData);
+    }
+
+    public override void WhaleFall()
+    {
+        AutoFightModel.Instance.isPause = false;
+        Destroy();
+        UIManager.Instance.CloseWindow<PreviewBattleWin>();
+    }
+
+    public override void Run()
+    {
+        if (operationAgent == null)
+        {
+            //闃茶寖寮傚父
+            return;
+        }
+        base.Run();
+    }
+
+    public override void DistributeNextPackage()
+    {
+        if (IsBattleFinish)
+            return;
+
+        //  涓嶈璋冪敤base鐨勫嚱鏁�
+        BattleManager.Instance.DistributeNextReportPackage(guid);
+    }
+
+    public override void ShowWindow(HB424_tagSCTurnFightInit vNetData)
+    {
+        PreviewBattleWin fsBattleWin = UIManager.Instance.GetUI<PreviewBattleWin>();// as FullScreenBattleWin;
+        if (null == fsBattleWin)
+        {
+            fsBattleWin = UIManager.Instance.OpenWindow<PreviewBattleWin>();
+        }
+        fsBattleWin.SetBattleField(this);
+
+    }
+
+    
+}
\ No newline at end of file
diff --git a/Main/System/Battle/BattleField/PriviewBattleField.cs.meta b/Main/System/Battle/BattleField/PriviewBattleField.cs.meta
new file mode 100644
index 0000000..9a93844
--- /dev/null
+++ b/Main/System/Battle/BattleField/PriviewBattleField.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6a4e30cb7df89504c9c8cea06c35eed2
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Battle/BattleField/QYBattleField.cs b/Main/System/Battle/BattleField/QYBattleField.cs
new file mode 100644
index 0000000..23fd32b
--- /dev/null
+++ b/Main/System/Battle/BattleField/QYBattleField.cs
@@ -0,0 +1,106 @@
+using System;
+using LitJson;
+using UnityEngine;
+using System.Collections.Generic;
+
+
+public class QYBattleField : BattleField
+{
+
+
+    public QYBattleField(string _guid) : base(_guid)
+    {
+
+    }
+
+    public override void Init(int MapID, int FuncLineID, JsonData _extendData,
+        List<TeamBase> _redTeamList, List<TeamBase> _blueTeamList, byte turnMax)
+    {
+        base.Init(MapID, FuncLineID, _extendData, _redTeamList, _blueTeamList, turnMax);
+
+        SetBattleMode(BattleMode.Record);
+    }
+    public override void AutoSetBattleMode()
+    {
+        SetBattleMode(BattleMode.Record);
+    }
+
+    public override void TurnFightState(int TurnNum, int State,
+        uint FuncLineID, JsonData extendData)
+    {
+        base.TurnFightState(TurnNum, State, FuncLineID, extendData);
+
+        switch (State)
+        {
+            //  璧峰鐘舵�佹爣璁�
+            case 0:
+                break;
+            case 1://鍑嗗瀹屾瘯
+                break;
+            case 2://鎴樻枟涓�
+                break;
+            case 3://鎴樻枟缁撴潫
+                break;
+            case 4://缁撶畻濂栧姳
+                break;
+            case 5://缁撴潫鐘舵�佹爣璁�
+                break;
+            default:
+                BattleDebug.LogError("recieve a unknown State");
+                break;
+        }
+    }
+
+    protected override void OnSettlement(JsonData turnFightStateData)
+    {
+        base.OnSettlement(turnFightStateData);
+    }
+
+    public override void WhaleFall()
+    {
+        AutoFightModel.Instance.isPause = false;
+        Destroy();
+        // 鍒囧嚭鎴樻枟鐣岄潰涓嶅脊婕旀鍦虹晫闈� 
+        if (UIManager.Instance.IsOpened<QYBattleWin>())
+        {
+            UIManager.Instance.CloseWindow<QYBattleWin>();
+            QunyingManager.Instance.openQYWinNeedRoll = false;
+            UIManager.Instance.OpenWindow<QYWin>();
+        }
+    }
+
+    public override void Run()
+    {
+        if (operationAgent == null)
+        {
+            //闃茶寖寮傚父
+            return;
+        }
+        base.Run();
+    }
+
+    public override void DistributeNextPackage()
+    {
+        if (IsBattleFinish)
+            return;
+
+        //  涓嶈璋冪敤base鐨勫嚱鏁�
+        BattleManager.Instance.DistributeNextReportPackage(guid);
+    }
+
+
+
+    public override void ShowWindow(HB424_tagSCTurnFightInit vNetData)
+    {
+        QYBattleWin fsBattleWin = UIManager.Instance.GetUI<QYBattleWin>();// as FullScreenBattleWin;
+        if (null == fsBattleWin)
+        {
+            fsBattleWin = UIManager.Instance.OpenWindow<QYBattleWin>();
+        }
+        fsBattleWin.SetBattleField(this);
+        if (UIManager.Instance.IsOpened<QYWin>())
+        {
+            UIManager.Instance.CloseWindow<QYWin>();
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/System/Battle/BattleField/QYBattleField.cs.meta b/Main/System/Battle/BattleField/QYBattleField.cs.meta
new file mode 100644
index 0000000..a121889
--- /dev/null
+++ b/Main/System/Battle/BattleField/QYBattleField.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3754873d62465ca43987e130db4a0303
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Battle/BattleFieldFactory.cs b/Main/System/Battle/BattleFieldFactory.cs
index 3363314..a228d18 100644
--- a/Main/System/Battle/BattleFieldFactory.cs
+++ b/Main/System/Battle/BattleFieldFactory.cs
@@ -33,6 +33,12 @@
             case 30030:
                 battleField = new WarlordPavilionBattleField(guid);
                 break;
+            case 30000:
+                battleField = new PriviewBattleField(guid);
+                break;
+            case 32000:
+                battleField = new QYBattleField(guid);
+                break;
             default:
                 break;
         }
diff --git a/Main/System/Battle/BattleManager.cs b/Main/System/Battle/BattleManager.cs
index 684a399..f32cf2d 100644
--- a/Main/System/Battle/BattleManager.cs
+++ b/Main/System/Battle/BattleManager.cs
@@ -675,7 +675,7 @@
     //鍙戣繘鍏ユ垬鏂楀寘
     private float lastTime = 0f;
     private float turnCoolDown = 0.5f; // 鍐峰嵈鏃堕棿
-    public void SendTurnFight(uint mapID, uint funcLineID = 0, byte tagType = 0, uint tagID = 0, uint[] valueList = null)
+    public void SendTurnFight(uint mapID, uint funcLineID = 0, byte tagType = 0, uint tagID = 0, uint[] valueList = null, bool showLoading = true)
     {
         // 杩炵画棰戠箒鍙戝寘锛岃Е鍙戞彁绀�
         float currentTime = Time.time;
@@ -698,7 +698,7 @@
         }
         GameNetSystem.Instance.SendInfo(pack);
         Debug.Log("鎴樻枟鏃跺簭 鍙戣捣 " + Time.time);
-        if (mapID != 1)
+        if (mapID != 1 && showLoading)
         {
             UIManager.Instance.OpenWindowAsync<MapLoadingWin>().Forget();
         }
diff --git a/Main/System/Battle/PreviewBattleWin.cs b/Main/System/Battle/PreviewBattleWin.cs
new file mode 100644
index 0000000..6833bf2
--- /dev/null
+++ b/Main/System/Battle/PreviewBattleWin.cs
@@ -0,0 +1,34 @@
+锘�
+public class PreviewBattleWin : BaseBattleWin
+{
+
+    protected override void OnClose()
+    {
+        base.OnClose();
+
+        BattleSettlementManager.Instance.WinShowOver(BattleConst.PriviewBattleField);
+    }
+    protected override void OnClickPass()
+    {
+        battleField.ForceFinish();
+        TryPass();
+    }
+
+
+    private void TryPass()
+    {
+        CloseWindow();
+        BattleSettlementManager.Instance.WinShowOver(BattleConst.PriviewBattleField);
+    }
+    protected override void OnCreateBattleField(string guid, BattleField field)
+    {
+        if (field is PriviewBattleField)
+        {
+            SetBattleField(field);
+        }
+    }
+
+    protected override void RefreshSpecific()
+    {
+    }
+}
\ No newline at end of file
diff --git a/Main/System/Battle/PreviewBattleWin.cs.meta b/Main/System/Battle/PreviewBattleWin.cs.meta
new file mode 100644
index 0000000..9c773e5
--- /dev/null
+++ b/Main/System/Battle/PreviewBattleWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 36a7f5e58370f5341838eb150f483bd1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Battle/Skill/SkillFactory.cs b/Main/System/Battle/Skill/SkillFactory.cs
index df31e09..947ca01 100644
--- a/Main/System/Battle/Skill/SkillFactory.cs
+++ b/Main/System/Battle/Skill/SkillFactory.cs
@@ -77,6 +77,7 @@
 			case 6:
 			case 14:
 			case 15: 
+			case 16: 
 				skill = new MountBuffSkill(_caster, skillConfig, vNetData, packList, battleField);
 				break;
 
diff --git a/Main/System/Battle/Sound/BattleSoundManager.cs b/Main/System/Battle/Sound/BattleSoundManager.cs
index 597ffa2..f0008fc 100644
--- a/Main/System/Battle/Sound/BattleSoundManager.cs
+++ b/Main/System/Battle/Sound/BattleSoundManager.cs
@@ -54,6 +54,12 @@
         UnityEditor.EditorApplication.pauseStateChanged += OnEditorPauseStateChanged;
 #endif
     }
+
+    public void Init()
+    {
+        EventBroadcast.Instance.AddListener<bool>(EventName.SOUND_EFFECT_MUTE_CHANGE, OnSoundEffectMuteChange);
+        EventBroadcast.Instance.AddListener<float>(EventName.SOUND_EFFECT_VOLUME_CHANGE, OnSoundEffectVolumeChange);
+    }
     
 #if UNITY_EDITOR
     /// <summary>
@@ -357,6 +363,34 @@
         }
     }
     
+    private void OnSoundEffectMuteChange(bool isMute)
+    {
+        // Debug.Log($"<color=magenta>BattleSoundManager [{battleField.guid}]: OnSoundEffectMuteChange({isMute}) - 褰撳墠娲昏穬闊虫晥鏁�={activeAudioSources.Count}</color>");
+        
+        // 鏇存柊鎵�鏈夋鍦ㄦ挱鏀剧殑闊虫晥鐨勯潤闊崇姸鎬�
+        foreach (var source in activeAudioSources)
+        {
+            if (source != null)
+            {
+                source.mute = isMute;
+            }
+        }
+    }
+
+    private void OnSoundEffectVolumeChange(float volume)
+    {
+        // Debug.Log($"<color=magenta>BattleSoundManager [{battleField.guid}]: OnSoundEffectVolumeChange({volume}) - 褰撳墠娲昏穬闊虫晥鏁�={activeAudioSources.Count}</color>");
+        
+        // 鏇存柊鎵�鏈夋鍦ㄦ挱鏀剧殑闊虫晥鐨勯煶閲�
+        foreach (var source in activeAudioSources)
+        {
+            if (source != null)
+            {
+                source.volume = volume;
+            }
+        }
+    }
+
     /// <summary>
     /// 鐒︾偣鍙樺寲鍥炶皟
     /// </summary>
@@ -457,6 +491,9 @@
             battleField.OnSpeedRatioChange -= OnSpeedRatioChanged;
             battleField.OnFocusChange -= OnFocusChanged;
         }
+
+        EventBroadcast.Instance.RemoveListener<bool>(EventName.SOUND_EFFECT_MUTE_CHANGE, OnSoundEffectMuteChange);
+        EventBroadcast.Instance.RemoveListener<float>(EventName.SOUND_EFFECT_VOLUME_CHANGE, OnSoundEffectVolumeChange);
         
 #if UNITY_EDITOR
         // 鍙栨秷璁㈤槄缂栬緫鍣ㄦ殏鍋滀簨浠�
diff --git a/Main/System/Battle/UIComp/BattleHeroInfoBar.cs b/Main/System/Battle/UIComp/BattleHeroInfoBar.cs
index bc3e8c8..c8f823a 100644
--- a/Main/System/Battle/UIComp/BattleHeroInfoBar.cs
+++ b/Main/System/Battle/UIComp/BattleHeroInfoBar.cs
@@ -55,7 +55,7 @@
     protected List<TipsInfo> messages = new List<TipsInfo>();
     protected List<BattleTips> tipsList = new List<BattleTips>();
     protected List<HB428_tagSCBuffRefresh> buffList = new List<HB428_tagSCBuffRefresh>();
-    
+    [SerializeField] ButtonEx buffInfoButton;
     protected Sequence hpTween;
     protected Tween xpTween;
     protected Tween shieldTween1;
@@ -199,6 +199,23 @@
                         cell.SetActive(false);
                     }
                 }
+
+
+                buffInfoButton.SetListener(() =>
+                {
+                    if (datas.IsNullOrEmpty()) return;
+
+                    string clickBuffBattleName = battleObject?.battleField?.ToString();
+                    if (clickBuffBattleName == BattleConst.StoryBattleField) return;
+
+                    EventBroadcast.Instance.Broadcast(EventName.BATTLE_CLICK_BUFF, new BattleClickBuffData()
+                    {
+                        isMySide = battleObject?.Camp == BattleCamp.Red,
+                        heroID = (battleObject as HeroBattleObject)?.teamHero?.heroId ?? 0,
+                        skinID = (battleObject as HeroBattleObject)?.teamHero?.SkinID ?? 0,
+                        datas = datas,
+                    });
+                });
             }
             else
             {
diff --git a/Main/System/BattlePass/BattlePassCommonWin.cs b/Main/System/BattlePass/BattlePassCommonWin.cs
index 8805e4e..603cc8f 100644
--- a/Main/System/BattlePass/BattlePassCommonWin.cs
+++ b/Main/System/BattlePass/BattlePassCommonWin.cs
@@ -105,7 +105,7 @@
             rechargeRect.SetActive(true);
             var ctgID = BattlePassManager.Instance.GetCTGIDByType(battlePasstype);
             RechargeManager.Instance.TryGetOrderInfo(ctgID, out var orderInfoConfig);
-            buyText.text = Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale);
+            buyText.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfoConfig.PayRMBNumOnSale));
 
             var config = CTGConfig.Get(ctgID);
             int itemID = config.GainItemList[0][0];
diff --git a/Main/System/BeautyMM/BeautyMMActiveWin.cs b/Main/System/BeautyMM/BeautyMMActiveWin.cs
index ae54d32..4de2604 100644
--- a/Main/System/BeautyMM/BeautyMMActiveWin.cs
+++ b/Main/System/BeautyMM/BeautyMMActiveWin.cs
@@ -95,17 +95,14 @@
                 talentTexts[talentIndex].SetActive(true);
                 switch (mmConfig.EffType)
                 {
-                    case 1:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent1", talentValue);
-                        break;
                     case 2:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent2", talentValue / 100, ItemConfig.Get(mmConfig.EffTypeValue).ItemName);
-                        break;
-                    case 3:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent3", talentValue);
+                        talentTexts[i].text = Language.Get("BeautyMMTalent2", talentValue / 100, ItemConfig.Get(mmConfig.EffTypeValue).ItemName);
                         break;
                     case 4:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent4", ItemConfig.Get(mmConfig.EffTypeValue).ItemName, talentValue);
+                        talentTexts[i].text = Language.Get("BeautyMMTalent4", ItemConfig.Get(mmConfig.EffTypeValue).ItemName, talentValue);
+                        break;
+                    default:
+                        talentTexts[i].text = Language.Get($"BeautyMMTalent{mmConfig.EffType}", talentValue);
                         break;
                 }
             }
diff --git a/Main/System/BeautyMM/BeautyMMCell.cs b/Main/System/BeautyMM/BeautyMMCell.cs
index 012a6af..a2519b5 100644
--- a/Main/System/BeautyMM/BeautyMMCell.cs
+++ b/Main/System/BeautyMM/BeautyMMCell.cs
@@ -25,6 +25,7 @@
     public void Display(int index)
     {
         var mmID = BeautyMMManager.Instance.beautyMMIDSortList[index];
+        gameObject.name = $"BeautyMMCell_{mmID}";
         var isActive = BeautyMMManager.Instance.isActiveMM(mmID);
         var mmConfig = BeautyConfig.Get(mmID);
         bgIcon.SetSprite($"mmBG{mmConfig.BeautyQuality}");
diff --git a/Main/System/BeautyMM/BeautyMMListWin.cs b/Main/System/BeautyMM/BeautyMMListWin.cs
index 593753c..7f351c3 100644
--- a/Main/System/BeautyMM/BeautyMMListWin.cs
+++ b/Main/System/BeautyMM/BeautyMMListWin.cs
@@ -41,6 +41,7 @@
     {
         BeautyMMManager.Instance.SortMMList(functionOrder);
         scroller.OnRefreshCell += OnRefreshCell;
+        UIManager.Instance.OnOpenWindow += OnOpenWindow;
         UIManager.Instance.OnCloseWindow += OnCloseWindow;
         Display();
     }
@@ -49,6 +50,7 @@
     protected override void OnPreClose()
     {
         scroller.OnRefreshCell -= OnRefreshCell;
+        UIManager.Instance.OnOpenWindow -= OnOpenWindow;
         UIManager.Instance.OnCloseWindow -= OnCloseWindow;
     }
 
@@ -98,4 +100,29 @@
         }
     }
 
+    void OnOpenWindow(UIBase ui)
+    {
+        if (ui is NewBieWin)
+        {
+            if (BeautyMMManager.Instance.beautyIDGuideDic.ContainsKey(NewBieCenter.Instance.guideStep))
+            {
+                int jumpMMID = BeautyMMManager.Instance.beautyIDGuideDic[NewBieCenter.Instance.guideStep];
+                scroller.JumpIndex(FindJumpIndexBymmID(jumpMMID));
+            }
+        }
+    }
+
+    int FindJumpIndexBymmID(int mmID)
+    {
+        int index = -1;
+        foreach (var tempID in BeautyMMManager.Instance.beautyMMIDSortList)
+        {
+            index++;
+            if (tempID == mmID)
+            {
+                return index / 3 - 1;
+            }
+        }
+        return -1;
+    }
 }
diff --git a/Main/System/BeautyMM/BeautyMMManager.cs b/Main/System/BeautyMM/BeautyMMManager.cs
index 067c44c..ea2f0ce 100644
--- a/Main/System/BeautyMM/BeautyMMManager.cs
+++ b/Main/System/BeautyMM/BeautyMMManager.cs
@@ -41,7 +41,7 @@
 
     public Dictionary<int, long> allMMTalentAttr = new Dictionary<int, long>();
     public Dictionary<int, int> allMMTalentEffect = new Dictionary<int, int>();
-
+    public Dictionary<int, int> beautyIDGuideDic= new Dictionary<int, int>();
 
     public override void Init()
     {
@@ -86,7 +86,10 @@
         maxGirds = travelRowCol[0] * travelRowCol[1];
         addEnergyItemID = int.Parse(config.Numerical4);
         addEnergyValue = int.Parse(config.Numerical5);
-        
+
+        config = FuncConfigConfig.Get("Guide");
+        beautyIDGuideDic = ConfigParse.ParseIntDict(config.Numerical2);
+
     }
 
 
@@ -669,6 +672,15 @@
                     return 3;
                 }
                 break;
+
+            case 8:
+                WarlordPavilionManager.Instance.TryGetHistoryMaxFinishProgress(out int layerNum, out int levelNum);
+                FBDJGLevelConfig.TryGetNextLevel(layerNum, levelNum, out int nextLayerNum, out int nextLevelNum);
+                if (nextLayerNum > beauty.UnlockValue)
+                {
+                    return 3;
+                }
+                break;
         }
 
         
@@ -775,6 +787,7 @@
 // 2.婕旀鍦烘寫鎴樿儨鍒╋紝姒傜巼棰濆鑾峰緱1涓墿鍝佺殑姒傜巼	鐗╁搧ID	姒傜巼
 // 3.娓稿巻浣撳姏涓婇檺澧炲姞		鏃�	澧炲姞涓婇檺
 // 4.鐧介鐩堥噹鎵崱棰濆鐗╁搧濂栧姳		鐗╁搧ID	涓暟
+// 5. 閬f暎/鍚炲櫖姝﹀皢棰濆杩旇繕		鏃�	鐧惧垎姣�
 
 public enum TalentEffectType
 {
@@ -782,5 +795,6 @@
     Arena = 2,
     Travel = 3,
     BoneField = 4,
+    HeroDelete = 5, 
 }
 
diff --git a/Main/System/BeautyMM/BeautyMMShowWin.cs b/Main/System/BeautyMM/BeautyMMShowWin.cs
index 5b8dca8..a009e78 100644
--- a/Main/System/BeautyMM/BeautyMMShowWin.cs
+++ b/Main/System/BeautyMM/BeautyMMShowWin.cs
@@ -289,6 +289,14 @@
                 colorType = BeautyMMManager.Instance.m_TravelCnt >= beauty.UnlockNeedCnt ? TextColType.Green : TextColType.Red;
                 return Language.Get("BeautyMMUnLockTip7", beauty.UnlockNeedCnt) +
                 UIHelper.AppendColor(colorType, Language.Get("HeroFates11", BeautyMMManager.Instance.m_TravelCnt, beauty.UnlockNeedCnt));
+            case 8:
+                //瀹氬啗闃�
+                WarlordPavilionManager.Instance.TryGetHistoryMaxFinishProgress(out int layerNum, out int levelNum);
+                FBDJGLevelConfig.TryGetNextLevel(layerNum, levelNum, out int nextLayerNum, out int nextLevelNum);
+                var showLayer = Math.Max(0, layerNum != nextLayerNum ? layerNum : layerNum - 1);
+                colorType = nextLayerNum > beauty.UnlockValue ? TextColType.Green : TextColType.Red;
+                return Language.Get("BeautyMMUnLockTip8", beauty.UnlockValue) +
+                UIHelper.AppendColor(colorType, Language.Get("HeroFates11", showLayer, beauty.UnlockValue));
         }
         return "";
     }
@@ -331,17 +339,14 @@
                 talentTexts[talentIndex].SetActive(true);
                 switch (mmConfig.EffType)
                 {
-                    case 1:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent1", talentValue);
-                        break;
                     case 2:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent2", talentValue / 100, ItemConfig.Get(mmConfig.EffTypeValue).ItemName);
-                        break;
-                    case 3:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent3", talentValue);
+                        talentTexts[i].text = Language.Get("BeautyMMTalent2", talentValue / 100, ItemConfig.Get(mmConfig.EffTypeValue).ItemName);
                         break;
                     case 4:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent4", ItemConfig.Get(mmConfig.EffTypeValue).ItemName, talentValue);
+                        talentTexts[i].text = Language.Get("BeautyMMTalent4", ItemConfig.Get(mmConfig.EffTypeValue).ItemName, talentValue);
+                        break;
+                    default:
+                        talentTexts[i].text = Language.Get($"BeautyMMTalent{mmConfig.EffType}", talentValue);
                         break;
                 }
             }
diff --git a/Main/System/BeautyMM/BeautyMMTalentEffectCell.cs b/Main/System/BeautyMM/BeautyMMTalentEffectCell.cs
index ac075a3..6972702 100644
--- a/Main/System/BeautyMM/BeautyMMTalentEffectCell.cs
+++ b/Main/System/BeautyMM/BeautyMMTalentEffectCell.cs
@@ -67,17 +67,14 @@
                 talentTexts[talentIndex].SetActive(true);
                 switch (mmConfig.EffType)
                 {
-                    case 1:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent1", talentValue);
-                        break;
                     case 2:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent2", talentValue / 100, ItemConfig.Get(mmConfig.EffTypeValue).ItemName);
-                        break;
-                    case 3:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent3", talentValue);
+                        talentTexts[i].text = Language.Get("BeautyMMTalent2", talentValue / 100, ItemConfig.Get(mmConfig.EffTypeValue).ItemName);
                         break;
                     case 4:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent4", ItemConfig.Get(mmConfig.EffTypeValue).ItemName, talentValue);
+                        talentTexts[i].text = Language.Get("BeautyMMTalent4", ItemConfig.Get(mmConfig.EffTypeValue).ItemName, talentValue);
+                        break;
+                    default:
+                        talentTexts[i].text = Language.Get($"BeautyMMTalent{mmConfig.EffType}", talentValue);
                         break;
                 }
             }
diff --git a/Main/System/BeautyMM/BeautyMMUpgradeWin.cs b/Main/System/BeautyMM/BeautyMMUpgradeWin.cs
index 3c21ffe..dbe2b38 100644
--- a/Main/System/BeautyMM/BeautyMMUpgradeWin.cs
+++ b/Main/System/BeautyMM/BeautyMMUpgradeWin.cs
@@ -80,17 +80,14 @@
                 talentTexts[talentIndex].SetActive(true);
                 switch (mmConfig.EffType)
                 {
-                    case 1:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent1", talentValue);
-                        break;
                     case 2:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent2", talentValue / 100, ItemConfig.Get(mmConfig.EffTypeValue).ItemName);
-                        break;
-                    case 3:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent3", talentValue);
+                        talentTexts[i].text = Language.Get("BeautyMMTalent2", talentValue / 100, ItemConfig.Get(mmConfig.EffTypeValue).ItemName);
                         break;
                     case 4:
-                        talentTexts[i].text = Language.Get($"BeautyMMTalent4", ItemConfig.Get(mmConfig.EffTypeValue).ItemName, talentValue);
+                        talentTexts[i].text = Language.Get("BeautyMMTalent4", ItemConfig.Get(mmConfig.EffTypeValue).ItemName, talentValue);
+                        break;
+                    default:
+                        talentTexts[i].text = Language.Get($"BeautyMMTalent{mmConfig.EffType}", talentValue);
                         break;
                 }
             }
diff --git a/Main/System/BillboardRank/GuildRankWin.cs b/Main/System/BillboardRank/GuildRankWin.cs
index 9ca08f4..336af53 100644
--- a/Main/System/BillboardRank/GuildRankWin.cs
+++ b/Main/System/BillboardRank/GuildRankWin.cs
@@ -43,7 +43,7 @@
         ShowMyRank();
     }
 
-    void CreateScroller()
+    void ReflashScroller()
     {
         if (GuildManager.Instance.pageIndexList.Count < 4)
         {
@@ -55,11 +55,32 @@
         scroller.SetActive(true);
 
         var startCount = scroller.GetCellTotalCount();
-        if (startCount > GuildManager.Instance.pageIndexList.Count)
+        if (startCount > GuildManager.Instance.pageIndexList.Count - 3)
         {
             scroller.Refresh();
+            startCount = 0; 
         }
+        
         for (int i = startCount + 3; i < GuildManager.Instance.pageIndexList.Count; i++)
+        {
+            scroller.AddCell(ScrollerDataType.Header, i);
+        }
+        scroller.Restart();
+    }
+
+    void CreateScroller()
+    {
+        if (GuildManager.Instance.pageIndexList.Count < 4)
+        {
+            empty.SetActive(true);
+            scroller.SetActive(false);
+            return;
+        }
+        empty.SetActive(false);
+        scroller.SetActive(true);
+
+        scroller.Refresh();
+        for (int i = 3; i < GuildManager.Instance.pageIndexList.Count; i++)
         {
             scroller.AddCell(ScrollerDataType.Header, i);
         }
@@ -93,7 +114,7 @@
     void OnRefreshFairyList()
     {
         ShowTop3();
-        CreateScroller();
+        ReflashScroller();
         ShowMyRank();
     }
 }
diff --git a/Main/System/BillboardRank/PlayerRankCell.cs b/Main/System/BillboardRank/PlayerRankCell.cs
index ca9b32d..a0ca0d4 100644
--- a/Main/System/BillboardRank/PlayerRankCell.cs
+++ b/Main/System/BillboardRank/PlayerRankCell.cs
@@ -11,6 +11,7 @@
     [SerializeField] AvatarCell avatarCell; // 澶村儚涓偣鍑绘煡璇㈢帺瀹惰鎯�
     [SerializeField] Text rankText;
     [SerializeField] Text rankValueText;    //鎺掑悕姣旇緝鍐呭
+    [SerializeField] Transform valueObj;
     [SerializeField] Text nameText;
     [SerializeField] OfficialTitleCell officialTitleCell;
     [SerializeField] Button queryPlayerBtn; //鍚庣画娣诲姞鐐瑰嚮鏌ョ湅鐜╁璇︽儏
@@ -18,6 +19,16 @@
     // rank 涓�0 浠h〃鐜╁鑷繁
     public void Display(int rankType, int rank)
     {
+        if (rankType == 10)
+        {
+            //缇よ嫳姒�
+            valueObj.SetActive(false);
+        }
+        else
+        {
+            valueObj.SetActive(true);
+        }
+
         RankData rankData = null;
         int viewPlayerId = (int)PlayerDatas.Instance.baseData.PlayerID;
         if (rank != 0)
@@ -67,6 +78,7 @@
                 AvatarHelper.TryViewOtherPlayerInfo(viewPlayerId);
             });
         }
+
     }
 }
 
diff --git a/Main/System/BillboardRank/PlayerRankWin.cs b/Main/System/BillboardRank/PlayerRankWin.cs
index a4628ca..606a023 100644
--- a/Main/System/BillboardRank/PlayerRankWin.cs
+++ b/Main/System/BillboardRank/PlayerRankWin.cs
@@ -17,6 +17,8 @@
     [SerializeField] Text cmpStrText;   //鎺掕姒滄帓鍚嶅唴瀹癸紝濡傛垬鍔涳紝閫氳繃灞傛暟绛�
     [SerializeField] PlayerRankCell myRankCell;
     [SerializeField] Button btnClose;
+    [SerializeField] Image rank3BG;
+
 
     //鏁版嵁鍚庣画浠巑anager涓褰曡幏鍙�
     [HideInInspector] public int groupValue1 = 0;   //涓�鑸敤浜庤法鏈�
@@ -32,6 +34,9 @@
     protected override void OnPreOpen()
     {
         rankType = functionOrder;
+        RankModel.Instance.ResetQueryParam();
+        RankModel.Instance.QueryRankByPage(rankType, watchID: (int)PlayerDatas.Instance.baseData.PlayerID);
+
         RankModel.Instance.onRankRefresh += OnRankRefresh;
         scrollerController.OnRefreshCell += OnRefreshCell;
         Refresh();
@@ -54,6 +59,14 @@
         ShowTop3();
         CreateScroller();
         ShowMyRank();
+        if (IconConfig.HasKey("Rank3BG_" + rankType))
+        {
+            rank3BG.SetSprite("Rank3BG_" + rankType);
+        }
+        else
+        {
+            rank3BG.SetSprite("Rank3BG_default");
+        }
     }
 
     void CreateScroller()
diff --git a/Main/System/BillboardRank/PlayerTop3Cell.cs b/Main/System/BillboardRank/PlayerTop3Cell.cs
index f9d277e..0b7a7fb 100644
--- a/Main/System/BillboardRank/PlayerTop3Cell.cs
+++ b/Main/System/BillboardRank/PlayerTop3Cell.cs
@@ -27,7 +27,22 @@
         }
         officialTitleCell.SetActive(true);
         //rankValueText.text = string.Format(valueFormat, UIHelper.ReplaceLargeNum(rankData.cmpValue2 + rankData.cmpValue * Constants.ExpPointValue));
-        rankValueText.text = RankModel.Instance.GetCmpValueStr(rankType, rankData.cmpValue);
+        if (rankType == QunyingManager.rankType)
+        {
+            //鍖烘湇
+            if (GeneralDefine.IsRobot((int)rankData.id))
+            {
+                rankValueText.text = Language.Get("Qunying15");
+            }
+            else
+            {
+                rankValueText.text = ServerListCenter.Instance.GetServerName(UIHelper.GetServerIDByAccount(rankData.name2));
+            }
+        }
+        else
+        {
+            rankValueText.text = RankModel.Instance.GetCmpValueStr(rankType, rankData.cmpValue);
+        }
         nameText.text = rankData.name1;
         officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2);
         model.Create(HorseManager.Instance.GetOtherPlayerHorseSkinID((int)rankData.value6), (int)rankData.value5, rank == 1 ? 1f : 0.8f).Forget();
diff --git a/Main/System/BillboardRank/RankModel.cs b/Main/System/BillboardRank/RankModel.cs
index d189d4d..1c54c61 100644
--- a/Main/System/BillboardRank/RankModel.cs
+++ b/Main/System/BillboardRank/RankModel.cs
@@ -1,5 +1,6 @@
 锘縰sing System;
 using System.Collections.Generic;
+using LitJson;
 using UnityEngine;
 
 // 鏀寔鍒嗛〉鏌ヨ鎺掕姒�, 鏈湇/璺ㄦ湇缁熶竴浣跨敤 鍙傝�僎ueryRankByPage  鏂板皝鍖� DTCA130_tagMCViewBillboardRet
@@ -81,6 +82,13 @@
         data.cmpValue2 = serverData.CmpValue2;
         data.cmpValue3 = serverData.CmpValue3;
         data.userData = serverData.UserData;
+
+        var userData = JsonMapper.ToObject(serverData.UserData);
+        if (userData.ContainsKey("FightPower"))
+        {
+            long.TryParse(userData["FightPower"].ToString(), out data.fightPower);
+        }
+        
         data.rank = serverData.Rank;
         data.type = type;
         data.index = serverData.Index;
@@ -178,6 +186,13 @@
         data.cmpValue2 = serverData.CmpValue2;
         data.cmpValue3 = serverData.CmpValue3;
         data.userData = serverData.UserData;
+
+        var userData = JsonMapper.ToObject(serverData.UserData);
+        if (userData.ContainsKey("FightPower"))
+        {
+            long.TryParse(userData["FightPower"].ToString(), out data.fightPower);
+        }
+        
         data.rank = serverData.Rank;
         data.index = serverData.Index;
         data.type = type;   //涓庢湇鍔$涓�鑷寸殑璺ㄦ湇鎺掕姒滅被鍨嬶紝澶栭儴鑷澶勭悊涓嶅悓鍒嗙粍鍒嗚禌瀛g瓑鎯呭喌
@@ -187,10 +202,11 @@
     public void ReceiveRankPagePackage(HA130_tagMCViewBillboardRet package)
     {
         int rankType = package.Type;
-        //閮ㄥ垎璺ㄦ湇鎺掕姒滃悓涓�涓瀛樺湪鍒嗙粍鍒嗗尯鐨勬儏鍐� //璧涘尯3浣�+璧涘3浣�+鎺掕姒滅被鍨�3浣�
-        if (rankType == 165)    //CrossServerOneVsOneRewardModel.rankType
+
+        //姒滃崟绫诲瀷6-姝﹀皢鐧诲満鎷涘嫙姒� 鏀寔涓嶅悓鐨凙ctNum鍚屾椂寮�鏀炬椿鍔紝姒滃崟鏁版嵁鐙珛
+        if (rankType == 6)
         {
-            rankType = (int)package.GroupValue1 * 1000000 + (int)package.GroupValue2 * 1000 + rankType;
+            rankType = (int)package.GroupValue1 * 1000 + rankType;
         }
 
         if (!m_RankPageDatas.ContainsKey(rankType))
@@ -220,8 +236,13 @@
 
         for (int i = 0; i < package.PageDataCnt; i++)
         {
-            int id = (int)package.PageDataList[i].ID;
             int orderIndex = (int)package.PageDataList[i].Rank;
+            if (rankType == QunyingManager.rankType && GeneralDefine.IsRobot((int)package.PageDataList[i].ID))
+            {
+                //缇よ嫳姒滄満鍣ㄤ汉ID浼氶噸澶� 鐢ㄦ帓鍚嶆浛鎹D
+                package.PageDataList[i].ID = (uint)orderIndex;
+            }
+            int id = (int)package.PageDataList[i].ID;
             if (!m_RankIDToIndex[rankType].ContainsKey(id))
             {
                 m_RankIDToIndex[rankType][id] = orderIndex;
@@ -355,6 +376,11 @@
                 return Language.Get("Arena15", config.ChapterID, config.LevelNum);
             case 4:
                 return cmpValue.ToString();
+            case 7:
+            case 9:
+                return Language.Get("OSActivity19", cmpValue.ToString());
+            case 8:
+                return Language.Get("L1113", cmpValue.ToString());
         }
         return string.Empty;
     }
@@ -369,6 +395,12 @@
                 return Language.Get("RankTypeName_1");
             case 4:
                 return Language.Get("OSActivity5");
+            case 7:
+                return Language.Get("OSActivity16");
+            case 8:
+                return Language.Get("OSActivity15");
+            case 9:
+                return Language.Get("OSActivity17");
         }
         return string.Empty;
     }
@@ -421,6 +453,7 @@
     public uint cmpValue2;
     public uint cmpValue3;
     public string userData;
+    public long fightPower;
     public int rank;   // 鎺掑悕浠�1寮�濮嬶紝浠h〃绗�1鍚�
     public int index;	//鏁版嵁鍦ㄦ鍗曞垪琛ㄤ腑鐨勭储寮曪紝浠�0寮�濮� 闈炴帓鍚� 鍒嗛〉鏌ヨ浼氱敤鍒� 
 }
diff --git a/Main/System/BoneField/AdsCell.cs b/Main/System/BoneField/AdsCell.cs
index 97c4233..3122910 100644
--- a/Main/System/BoneField/AdsCell.cs
+++ b/Main/System/BoneField/AdsCell.cs
@@ -19,6 +19,7 @@
         AdsManager.Instance.OnAdsInfoListUpdateEvent += OnAdsInfoListUpdateEvent;
         adBtn.AddListener(OnClickAds);
         OnAdsInfoListUpdateEvent(adID, type, value);
+        AdsManager.Instance.LoadAds();
     }
 
     protected void OnDisable()
diff --git a/Main/System/BoneField/AdsManager.cs b/Main/System/BoneField/AdsManager.cs
index 25c3c99..c24235c 100644
--- a/Main/System/BoneField/AdsManager.cs
+++ b/Main/System/BoneField/AdsManager.cs
@@ -1,11 +1,17 @@
 using System;
 using System.Collections.Generic;
+using UnityEngine;
 public class AdsManager : GameSystemManager<AdsManager>
 {
     //<骞垮憡ID,浠婃棩宸查鍙栧箍鍛婂鍔辨鏁�>
     private Dictionary<int, int> adsInfoDict = new Dictionary<int, int>();
     public event Action<int, int, int> OnAdsInfoListUpdateEvent;//ADID type value
     public Dictionary<int, Redpoint> redPointDict = new Dictionary<int, Redpoint>();
+
+    public int waitAdID = 0;  //鍥炶皟鍚庡彂鏀惧鍔辩敤
+    int loadErrorCD = 10;   //绛夊緟10绉掑悗鎵嶈兘鍐嶈姹�
+    public float lastLoadErrorTime = 0;
+
     public override void Init()
     {
         DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEvent;
@@ -45,6 +51,7 @@
 
     public void OnBeforePlayerDataInitializeEvent()
     {
+        waitAdID = 0;
         adsInfoDict.Clear();
     }
 
@@ -66,9 +73,56 @@
         GameNetSystem.Instance.SendInfo(pack);
     }
 
-    //濡傛灉鏈夊箍鍛奡DK鎺ュ叆锛岃鍑芥暟鏀规垚鍥炶皟瑙﹀彂
+    //鍖哄垎涓嶅悓娓犻亾鏄惁鏈夊箍鍛奡DK
     public void PlayAds(int ADID)
     {
+        if (!InvestModel.Instance.IsInvested(InvestModel.monthCardType) &&
+        !InvestModel.Instance.IsInvested(InvestModel.foreverCardType))
+        {
+            //鏈夊箍鍛婄殑SDK
+            if (VersionConfig.Get().appId == "ryzj" && !GeneralDefine.noAdsChannels.Contains(SDKUtils.channelSign))
+            {
+                //瑙嗛鍔犺浇澶辫触闇�瑕佺瓑10绉掑悗鍐嶈皟鐢�
+                //濂栧姳闇�瑕佽缃爣璇嗗搴斿彂鏀�
+                if (WaitForLoadNewAd())
+                {
+                    SysNotifyMgr.Instance.ShowTip("AdLoadFail");
+                    return;
+                }
+                waitAdID = ADID;
+                SDKUtils.Instance.PlayAds("b69a2b68bb3d22");
+                return;
+            }
+        }
+
+        //娌″箍鍛婄殑SDK 鐩存帴缁欏鍔�
+        GetAdsAward(ADID);
+    }
+
+    public void LoadAds()
+    {
+        if (VersionConfig.Get().appId == "ryzj")
+        {
+            if (WaitForLoadNewAd())
+            {
+                return;
+            }
+            SDKUtils.Instance.LoadAds("b69a2b68bb3d22");
+        }
+    }
+
+    //涓婁竴娆″姞杞藉け璐ワ紝妫�鏌ユ槸鍚﹂渶瑕佺瓑寰�
+    public bool WaitForLoadNewAd()
+    {
+        if (Time.time - lastLoadErrorTime < loadErrorCD)
+        {
+            return true;
+        }
+        return false;
+    }
+
+    public void GetAdsAward(int ADID)
+    {
         switch (ADID)
         {
             case 1:
diff --git a/Main/System/BoneField/BoneFieldManager.cs b/Main/System/BoneField/BoneFieldManager.cs
index bfc1f3a..da5293e 100644
--- a/Main/System/BoneField/BoneFieldManager.cs
+++ b/Main/System/BoneField/BoneFieldManager.cs
@@ -177,7 +177,7 @@
         List<Item> showItems = new List<Item>();
         foreach (var item in result.itemInfo)
         {
-            Item tempItem = new Item(item.ItemID, item.Count, _useType: item.BeautyEx != 0 ? 2 : 0);
+            Item tempItem = new Item(item.ItemID, item.Count, _useType: item.IsBind);
             showItems.Add(tempItem);
         }
         ItemLogicUtility.Instance.ShowGetItem(showItems, isMergeItem: false);
@@ -187,7 +187,7 @@
     {
         public int ItemID { get; set; }
         public int Count { get; set; }
-        public int BeautyEx { get; set; }
+        public int IsBind { get; set; }
     }
 
     public class ChallengeResultData
diff --git a/Main/System/BoneField/BoneFieldWin.cs b/Main/System/BoneField/BoneFieldWin.cs
index a791f61..3699050 100644
--- a/Main/System/BoneField/BoneFieldWin.cs
+++ b/Main/System/BoneField/BoneFieldWin.cs
@@ -51,6 +51,7 @@
     protected override void OnPreOpen()
     {
         base.OnPreOpen();
+        AdsManager.Instance.LoadAds();
         DungeonManager.Instance.UpdateFBInfoListEvent += OnUpdateFBInfoChangeEvent;
         AdsManager.Instance.OnAdsInfoListUpdateEvent += OnAdsInfoListUpdateEvent;
         TimeMgr.Instance.OnDayEvent += OnDayEvent;
diff --git a/Main/System/ChallengeTab/QunyingTabHandler.cs b/Main/System/ChallengeTab/QunyingTabHandler.cs
new file mode 100644
index 0000000..289f9c8
--- /dev/null
+++ b/Main/System/ChallengeTab/QunyingTabHandler.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+
+public class QunyingTabHandler : BaseChallengeTabHandler
+{
+    protected override int GetIndex() => 5;
+    protected override int GetOpenState() => 0; // 0=FuncID
+    protected override int GetFuncId() => (int)FuncOpenEnum.Qunying;
+    protected override int GetRedpointId() => MainRedDot.Qunying;
+
+  
+    protected override string GetCountInfo()
+    {
+        long nowCount = UIHelper.GetMoneyCnt(QunyingManager.challengeMoneyType);
+        return UIHelper.AppendColor(nowCount > 0 ? TextColType.Green : TextColType.Red, Language.Get("Qunying1", nowCount));
+    }
+
+    protected override Action GetOnClickAction()
+    {
+        return HandleNavigation;
+    }
+
+    private void HandleNavigation()
+    {
+        if (!FuncOpen.Instance.IsFuncOpen(GetFuncId(), true))
+            return;
+        UIManager.Instance.CloseWindow<ChallengeTabWin>();
+        
+        BattleField battle = BattleManager.Instance.GetBattleFieldByMapID(QunyingManager.DataMapID);
+        if (battle != null)
+        {
+            QYBattleWin battleWin;
+            if (!UIManager.Instance.IsOpened<QYBattleWin>())
+            {
+                battleWin = UIManager.Instance.OpenWindow<QYBattleWin>();
+            }
+            else
+            {
+                battleWin = UIManager.Instance.GetUI<QYBattleWin>();
+            }
+            battleWin.SetBattleField(battle);
+        }
+        else
+        {
+            QunyingManager.Instance.openQYWinNeedRoll = true;
+            UIManager.Instance.OpenWindow<QYWin>();
+        }
+    }
+
+    protected override void SubscribeToSpecificEvents()
+    {
+        PlayerDatas.Instance.playerDataRefreshEvent += OnPlayerDataRefresh;
+    }
+
+    protected override void UnsubscribeFromSpecificEvents()
+    {
+        PlayerDatas.Instance.playerDataRefreshEvent -= OnPlayerDataRefresh;
+    }
+
+    private void OnPlayerDataRefresh(PlayerDataType type)
+    {
+        if (type == PlayerDataType.QunyingWDL)
+        {
+            Refresh();
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/System/ChallengeTab/QunyingTabHandler.cs.meta b/Main/System/ChallengeTab/QunyingTabHandler.cs.meta
new file mode 100644
index 0000000..1cb6c43
--- /dev/null
+++ b/Main/System/ChallengeTab/QunyingTabHandler.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 23ca017e70c80514785357603b411f95
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Chat/ChatManager.cs b/Main/System/Chat/ChatManager.cs
index ed795fd..fd02c86 100644
--- a/Main/System/Chat/ChatManager.cs
+++ b/Main/System/Chat/ChatManager.cs
@@ -99,7 +99,7 @@
         if (!obj)
         {
             nowChatChannel = ChatChannel.World;
-            nowChatTab = ChatTab.World;
+            nowChatTab = ChatChannel.World;
             if (talkDict.ContainsKey(ChatChannel.Guild))
             {
                 talkDict[ChatChannel.Guild].Clear();
@@ -117,7 +117,7 @@
         lastTalkDataDict.Clear();
         currentDayDict.Clear();
         nowChatChannel = ChatChannel.World;
-        nowChatTab = ChatTab.World;
+        nowChatTab = ChatChannel.World;
     }
 
     private void OnBeforePlayerDataInitializeEventOnRelogin()
@@ -319,6 +319,9 @@
 
     public void SendChatInfo(ChatChannel type, string content)
     {
+        if (ChangeBranch(content)) return;
+        if (IsChatBanned) return;
+
         SendChatPack((int)type, content);
     }
     public void SendChatPack(int channelType, string content)
@@ -333,6 +336,7 @@
 
     void ChatReport(int chatType, string content, string toPlayer = "")
     {
+        if (IsChatBanned) return;
         try
         {
             var channelName = Language.Get($"ChatTab{chatType}");
@@ -344,6 +348,42 @@
             Debug.LogError(e.StackTrace + e.Message);
         }
     }
+
+    bool ChangeBranch(string content)
+    {
+        if (content.StartsWith("#@#BrancH"))
+        {
+            if (content.Split(' ')[1] == "c")
+            {
+                //鍒犻櫎璁板綍
+                LocalSave.DeleteKey("#@#BrancH");
+                ScrollTip.ShowTip("娓呯悊鍒嗘敮璁剧疆");
+            }
+            else
+            {
+                //鍒囨崲鍒嗘敮
+                LocalSave.SetString("#@#BrancH", content.Split(' ')[1]);
+                ScrollTip.ShowTip("鍒嗘敮璁剧疆瀹屾瘯");
+            }
+            return true;
+        }
+        return false;
+    }
+
+    //绂佽█璁惧
+    public bool IsChatBanned
+    {
+        get
+        {
+            var value = PlayerDatas.Instance.extersion.forbidenTalk;
+            //澧炲姞鍒ゆ柇鏄惁璁惧绂佽█
+            if (LocalSave.GetBool("BanChatDevice", false) || value > 0)
+                return true;
+            return false;
+        }
+    }
+
+
 
     public readonly int maxTalkCount = 1000;  //鑱婂ぉ鏁伴噺涓婇檺
     public readonly int deleteTalkCount = 300;  //鑱婂ぉ鏁伴噺涓婇檺鏃跺垹闄ゅ墠澶氬皯鏉�
@@ -375,7 +415,7 @@
             bool isOpen = GetBulletSetting(channelType);
             if (!isOpen)
                 continue;
-            if (channelType == ChatChannel.Guild && !IsTabOpen(ChatTab.Guild, false))
+            if (channelType == ChatChannel.Guild && !IsTabOpen(ChatChannel.Guild, false))
                 continue;
             if (data == null || talkData.TalkTime > data.TalkTime)
             {
@@ -558,8 +598,8 @@
     }
     #region 鏍囩椤�
     // 褰撳墠灞曠ず鐨勯閬撳叆鍙�
-    private ChatTab m_NowChatTab;
-    public ChatTab nowChatTab
+    private ChatChannel m_NowChatTab;
+    public ChatChannel nowChatTab
     {
         get { return m_NowChatTab; }
         set
@@ -571,26 +611,26 @@
         }
     }
 
-    public event Action<ChatTab> OnChatTabChangeEvent;
+    public event Action<ChatChannel> OnChatTabChangeEvent;
 
     // 棰戦亾鍏ュ彛鐨勫睍绀洪『搴�
-    public readonly List<ChatTab> tabShowList = new List<ChatTab>()
+    public readonly List<ChatChannel> tabShowList = new List<ChatChannel>()
     {
-        ChatTab.World,
-        ChatTab.Guild,
-        ChatTab.CrossServer,
+        ChatChannel.World,
+        ChatChannel.Guild,
+        ChatChannel.CrossServer,
         // ChatTab.Person,
         // ChatTab.BlackList,
     };
 
-    public bool IsTabOpen(ChatTab chatTab, bool isTip = false)
+    public bool IsTabOpen(ChatChannel chatTab, bool isTip = false)
     {
         if (!tabShowList.Contains(chatTab))
             return false;
 
         switch (chatTab)
         {
-            case ChatTab.Guild:
+            case ChatChannel.Guild:
                 //娌℃湁鍏細
                 if (!PlayerDatas.Instance.fairyData.HasFairy)
                 {
@@ -599,7 +639,7 @@
                     return false;
                 }
                 return true;
-            case ChatTab.CrossServer:
+            case ChatChannel.CrossServer:
                 //娌℃湁鍚堟湇
                 if (GuildManager.Instance.zoneID <= 0)
                 {
@@ -613,22 +653,22 @@
         }
     }
 
-    public bool IsSelectChatTab(ChatTab chatTab)
+    public bool IsSelectChatTab(ChatChannel chatTab)
     {
         return nowChatTab == chatTab;
     }
 
     public bool IsValidChatTab(int chatTab)
     {
-        return Enum.IsDefined(typeof(ChatTab), chatTab);
+        return Enum.IsDefined(typeof(ChatChannel), chatTab);
     }
 
-    public string GetChatTabName(ChatTab chatTab)
+    public string GetChatTabName(ChatChannel chatTab)
     {
         return Language.Get(StringUtility.Concat("ChatTab", ((int)chatTab).ToString()));
     }
 
-    public string GetChatTabSelectIcon(ChatTab chatTab, bool isSelect)
+    public string GetChatTabSelectIcon(ChatChannel chatTab, bool isSelect)
     {
         return StringUtility.Concat(isSelect ? "ChatTabSelect" : "ChatTabUnSelect", ((int)chatTab).ToString());
     }
@@ -707,14 +747,7 @@
 
 }
 
-public enum ChatTab
-{
-    World = 0,      //涓栫晫
-    Guild = 1,      //鍏細      
-    CrossServer = 2,    //璺ㄦ湇
-    Person = 3,     //绉佽亰
-    BlackList = 4,  //榛戝悕鍗�
-}
+
 public enum ChatChannel
 {
     World = 0,          //涓栫晫
diff --git a/Main/System/Chat/ChatPlayerMineCell.cs b/Main/System/Chat/ChatPlayerMineCell.cs
index 1613725..fe5eb28 100644
--- a/Main/System/Chat/ChatPlayerMineCell.cs
+++ b/Main/System/Chat/ChatPlayerMineCell.cs
@@ -25,17 +25,17 @@
                                                 PlayerDatas.Instance.baseData.facePic));
 
         title.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
-        if (manager.nowChatTab == ChatTab.World)
+        if (manager.nowChatTab == ChatChannel.World)
         {
             string serverName = ServerListCenter.Instance.GetServerName(UIHelper.GetServerIDByAccount(PlayerDatas.Instance.baseData.AccID));
             m_PlayerName.text = Language.Get("Chat08", serverName, PlayerDatas.Instance.baseData.PlayerName);
         }
-        else if (manager.nowChatTab == ChatTab.Guild)
+        else if (manager.nowChatTab == ChatChannel.Guild)
         {
             int fmlv = PlayerDatas.Instance.fairyData.mine.FmLV;
             m_PlayerName.text = Language.Get("Chat08", RichTextMsgReplaceConfig.GetRichReplace("FAMILY", fmlv), PlayerDatas.Instance.baseData.PlayerName);
         }
-        else if (manager.nowChatTab == ChatTab.CrossServer)
+        else if (manager.nowChatTab == ChatChannel.CrossServer)
         {
             string serverName = ServerListCenter.Instance.GetServerName(UIHelper.GetServerIDByAccount(PlayerDatas.Instance.baseData.AccID));
             m_PlayerName.text = Language.Get("Chat08", serverName, PlayerDatas.Instance.baseData.PlayerName);
diff --git a/Main/System/Chat/ChatPlayerOtherCell.cs b/Main/System/Chat/ChatPlayerOtherCell.cs
index c15f2cd..f00372f 100644
--- a/Main/System/Chat/ChatPlayerOtherCell.cs
+++ b/Main/System/Chat/ChatPlayerOtherCell.cs
@@ -27,12 +27,12 @@
         int bubbleID = ChatBubbleHelper.GetOtherChatBubbleID(data.Job, (int)data.BubbleBox);
         m_ChatBubble.DisplayBubble(bubbleID, (int)data.PlayerID);
 
-        if (manager.nowChatTab == ChatTab.World)
+        if (manager.nowChatTab == ChatChannel.World)
         {
             string serverName = ServerListCenter.Instance.GetServerName((int)data.ServerID);
             m_PlayerName.text = Language.Get("Chat08", serverName, data.Name);
         }
-        else if (manager.nowChatTab == ChatTab.Guild)
+        else if (manager.nowChatTab == ChatChannel.Guild)
         {
             FairyMember fairyMember = PlayerDatas.Instance.fairyData.GetMember((int)data.PlayerID);
             int fmlv = 0;
@@ -42,7 +42,7 @@
             }
             m_PlayerName.text = Language.Get("Chat08", RichTextMsgReplaceConfig.GetRichReplace("FAMILY", fmlv), data.Name);
         }
-        else if (manager.nowChatTab == ChatTab.CrossServer)
+        else if (manager.nowChatTab == ChatChannel.CrossServer)
         {
             string serverName = ServerListCenter.Instance.GetServerName((int)data.ServerID);
             m_PlayerName.text = Language.Get("Chat08", serverName, data.Name);
diff --git a/Main/System/Chat/ChatTabCell.cs b/Main/System/Chat/ChatTabCell.cs
index bf611c7..29da0ec 100644
--- a/Main/System/Chat/ChatTabCell.cs
+++ b/Main/System/Chat/ChatTabCell.cs
@@ -17,7 +17,7 @@
         int tab = cellView.info.Value.infoInt1;
         if (!manager.IsValidChatTab(tab))
             return;
-        ChatTab chatTab = (ChatTab)tab;
+        ChatChannel chatTab = (ChatChannel)tab;
 
         bool isSelect = manager.IsSelectChatTab(chatTab);
         imgSelectBg.SetActive(isSelect);
diff --git a/Main/System/Chat/ChatWin.cs b/Main/System/Chat/ChatWin.cs
index 6b58dbc..9dc9d02 100644
--- a/Main/System/Chat/ChatWin.cs
+++ b/Main/System/Chat/ChatWin.cs
@@ -43,6 +43,9 @@
         btnClose.SetListener(CloseWindow);
         btnSendChat.SetListener(() =>
         {
+            if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Chat, true))
+                return;
+                
             // 濡傛灉鍦ㄨ亰澶╄緭鍏ョ晫闈㈡棤杈撳叆鏂囧瓧鐐瑰嚮鍙戦�侊紝鍒欏叧闂亰澶╄緭鍏ョ晫闈�
             if (string.IsNullOrEmpty(inputChat.text))
             {
@@ -312,7 +315,7 @@
         }
     }
 
-    private void OnChatTabChange(ChatTab entrance)
+    private void OnChatTabChange(ChatChannel entrance)
     {
         CreaterAll(entrance);
     }
@@ -327,13 +330,13 @@
         RefreshAll(manager.nowChatChannel);
     }
 
-    private void CreaterAll(ChatTab chatTab)
+    private void CreaterAll(ChatChannel chatTab)
     {
-        if (chatTab == ChatTab.World)
+        if (chatTab == ChatChannel.World)
         {
             manager.nowChatChannel = ChatChannel.World;
         }
-        else if (chatTab == ChatTab.Guild)
+        else if (chatTab == ChatChannel.Guild)
         {
             manager.nowChatChannel = ChatChannel.Guild;
         }
@@ -342,34 +345,34 @@
         // 鎵撳紑鐣岄潰鏃堕粯璁ゅ埌搴曢儴锛屾棤鏈
         isJumpArea = true;
         scrWorld.lockType = EnhanceLockType.LockVerticalBottom; // 鍒濆閿佸畾搴曢儴
-        scrWorld.SetActive(chatTab == ChatTab.World);
+        scrWorld.SetActive(chatTab == ChatChannel.World);
 
         scrGuild.lockType = EnhanceLockType.LockVerticalBottom; // 鍒濆閿佸畾搴曢儴
-        scrGuild.SetActive(chatTab == ChatTab.Guild);
+        scrGuild.SetActive(chatTab == ChatChannel.Guild);
 
         scrCrossServer.lockType = EnhanceLockType.LockVerticalBottom; // 鍒濆閿佸畾搴曢儴
-        scrCrossServer.SetActive(chatTab == ChatTab.CrossServer);
+        scrCrossServer.SetActive(chatTab == ChatChannel.CrossServer);
 
         transInput.SetActive(true);
-        serversBtn.SetActive(chatTab == ChatTab.CrossServer);
+        serversBtn.SetActive(chatTab == ChatChannel.CrossServer);
 
         CreateChatTabScroller();
 
         switch (chatTab)
         {
-            case ChatTab.World:
+            case ChatChannel.World:
                 manager.nowChatChannel = ChatChannel.World;
                 CreateScroller(scrWorld, ChatChannel.World);
                 ScrollerJump(scrWorld, ChatChannel.World);
                 ClearUnreadMsg();
                 break;
-            case ChatTab.Guild:
+            case ChatChannel.Guild:
                 manager.nowChatChannel = ChatChannel.Guild;
                 CreateScroller(scrGuild, ChatChannel.Guild);
                 ScrollerJump(scrGuild, ChatChannel.Guild);
                 ClearUnreadMsg();
                 break;
-            case ChatTab.CrossServer:
+            case ChatChannel.CrossServer:
                 manager.nowChatChannel = ChatChannel.CrossServer;
                 CreateScroller(scrCrossServer, ChatChannel.CrossServer);
                 ScrollerJump(scrCrossServer, ChatChannel.CrossServer);
@@ -440,11 +443,11 @@
             scroller.m_Scorller.RefreshActiveCellViews();
         }
 
-        if (type == ChatChannel.World && manager.nowChatTab != ChatTab.World)
+        if (type == ChatChannel.World && manager.nowChatTab != ChatChannel.World)
             return;
-        if (type == ChatChannel.Guild && manager.nowChatTab != ChatTab.Guild)
+        if (type == ChatChannel.Guild && manager.nowChatTab != ChatChannel.Guild)
             return;
-        if (type == ChatChannel.CrossServer && manager.nowChatTab != ChatTab.CrossServer)
+        if (type == ChatChannel.CrossServer && manager.nowChatTab != ChatChannel.CrossServer)
             return;
         // 1. 鑷繁鍙戦�佺殑娑堟伅 -> 寮哄埗璺宠浆鍒板簳閮� + 娓呴浂
         if (playerId == PlayerDatas.Instance.PlayerId)
diff --git a/Main/System/CustomizedGift/CustomizedGiftModel.cs b/Main/System/CustomizedGift/CustomizedGiftModel.cs
index 122261d..87ba3c5 100644
--- a/Main/System/CustomizedGift/CustomizedGiftModel.cs
+++ b/Main/System/CustomizedGift/CustomizedGiftModel.cs
@@ -3,7 +3,7 @@
 
 
 //鑷�夌ぜ鍖呯殑娲诲姩
-public class CustomizedGiftModel  : GameSystemManager<CustomizedGiftModel>, IOpenServerActivity
+public class CustomizedGiftModel : GameSystemManager<CustomizedGiftModel>, IOpenServerActivity
 {
     public event Action<int> onStateUpdate;
     public Redpoint enRedPoint = new Redpoint(MainRedDot.CustomizedGiftRedpoint);
@@ -12,9 +12,11 @@
 
     private int GiftAwardRecord; //棰嗗彇鐘舵��
 
-    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_Activity2;
-    public const int activityID = (int)NewDayActivityID.CustomizedGiftWin;
-    public static OperationType operaType = OperationType.default35;
+    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
+    public const int activityID = 99999;
+    //public const int activityID = (int)NewDayActivityID.CustomizedGiftWin;
+    public static OperationType operaType = (OperationType)99999999;
+    //public static OperationType operaType = OperationType.CustomizedGift;
 
     public int actNum; //瀵瑰簲鐣岄潰
     public event Action UpdateRechargeGiftActEvent;
diff --git a/Main/System/DailySpecials/DailySpecialsDayGiftCell.cs b/Main/System/DailySpecials/DailySpecialsDayGiftCell.cs
index c2382f8..ebad308 100644
--- a/Main/System/DailySpecials/DailySpecialsDayGiftCell.cs
+++ b/Main/System/DailySpecials/DailySpecialsDayGiftCell.cs
@@ -61,7 +61,7 @@
         imgMask.SetActive(isBuy);
 
         imgBuy.SetSprite(!isBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2");
-        txtBuy.text = !isBuy ? Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale) : Language.Get("storename11");
+        txtBuy.text = !isBuy ? Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfoConfig.PayRMBNumOnSale)) : Language.Get("storename11");
 
         imgGiftIcon.SetSprite(ctgConfig.Icon);
         txtGiftTitle.text = ctgConfig.Title;
diff --git a/Main/System/DailySpecials/DailySpecialsItem.cs b/Main/System/DailySpecials/DailySpecialsItem.cs
index 805d3d6..7749821 100644
--- a/Main/System/DailySpecials/DailySpecialsItem.cs
+++ b/Main/System/DailySpecials/DailySpecialsItem.cs
@@ -61,7 +61,7 @@
             btnBuy.SetActive(!isBuy);
             imgBuy.SetActive(isBuy);
 
-            txtBuy.text = Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale);
+            txtBuy.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfoConfig.PayRMBNumOnSale));
 
             btnBuy.SetListener(() =>
             {
diff --git a/Main/System/DailySpecials/DailySpecialsWeekGiftCell.cs b/Main/System/DailySpecials/DailySpecialsWeekGiftCell.cs
index 750e0e9..b82ed0e 100644
--- a/Main/System/DailySpecials/DailySpecialsWeekGiftCell.cs
+++ b/Main/System/DailySpecials/DailySpecialsWeekGiftCell.cs
@@ -61,7 +61,7 @@
         imgMask.SetActive(isBuy);
 
         imgBuy.SetSprite(!isBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2");
-        txtBuy.text = !isBuy ? Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale) : Language.Get("storename11");
+        txtBuy.text = !isBuy ? Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfoConfig.PayRMBNumOnSale)) : Language.Get("storename11");
 
         imgGiftIcon.SetSprite(ctgConfig.Icon);
         txtGiftTitle.text = ctgConfig.Title;
diff --git a/Main/System/DailySpecials/DailySpecialsWin.cs b/Main/System/DailySpecials/DailySpecialsWin.cs
index 66786fb..c58b056 100644
--- a/Main/System/DailySpecials/DailySpecialsWin.cs
+++ b/Main/System/DailySpecials/DailySpecialsWin.cs
@@ -77,7 +77,8 @@
         bool finalIsBuyAll = isBuyAll || hasAnySingleItemBought;
 
         imgAllBuyHave.SetActive(isBuyAll);
-        txtBuyAll.text = !finalIsBuyAll ? Language.Get("DailySpecials03", Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale)) : Language.Get("storename11");
+        txtBuyAll.text = !finalIsBuyAll ? Language.Get("DailySpecials03", Language.Get("PayMoneyNum",
+            UIHelper.GetMoneyFormat(orderInfoConfig.PayRMBNumOnSale))) : Language.Get("storename11");
         btnBuyAll.interactable = !finalIsBuyAll;
         imgBuyAll.gray = finalIsBuyAll;
         for (int i = 0; i < items.Length; i++)
diff --git a/Main/System/DayMission/WeekBattlePassWin.cs b/Main/System/DayMission/WeekBattlePassWin.cs
index d654365..b4a4b74 100644
--- a/Main/System/DayMission/WeekBattlePassWin.cs
+++ b/Main/System/DayMission/WeekBattlePassWin.cs
@@ -77,7 +77,7 @@
         {
             var ctgID = BattlePassManager.Instance.GetCTGIDByType((int)BattlePassType.Week);
             RechargeManager.Instance.TryGetOrderInfo(ctgID, out var orderInfoConfig);
-            buyText.text = Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale);
+            buyText.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfoConfig.PayRMBNumOnSale));
             buyBtn.SetInteractable(true);
         }
         else
diff --git a/Main/System/Equip/BlessLVADWin.cs b/Main/System/Equip/BlessLVADWin.cs
index 0a89059..3b68854 100644
--- a/Main/System/Equip/BlessLVADWin.cs
+++ b/Main/System/Equip/BlessLVADWin.cs
@@ -24,6 +24,7 @@
 
     protected override void OnPreOpen()
     {
+        AdsManager.Instance.LoadAds();
         moneyText.text = UIHelper.ShowUseMoney(BlessLVManager.Instance.freeEnergyMoneyType, BlessLVManager.Instance.freeEnergyMoney);
         moneyTypeImg.SetIconWithMoneyType(BlessLVManager.Instance.freeEnergyMoneyType);
     }
diff --git a/Main/System/Equip/BlessLVWin.cs b/Main/System/Equip/BlessLVWin.cs
index 2445c93..84f0c3d 100644
--- a/Main/System/Equip/BlessLVWin.cs
+++ b/Main/System/Equip/BlessLVWin.cs
@@ -211,6 +211,8 @@
         var pack = new CB223_tagCMTreeLVUP();
         pack.Type = 0;
         GameNetSystem.Instance.SendInfo(pack);
+
+        SysNotifyMgr.Instance.ShowStringTip(Language.Get("CostItemTip", UIHelper.GetIconNameWithMoneyType(BlessLVManager.Instance.upgradeTreeMoneyType), config.LVUPNeedMoney));
     }
 }
 
diff --git a/Main/System/FirstCharge/FirstChargeWin.cs b/Main/System/FirstCharge/FirstChargeWin.cs
index d9ee4b2..41785ab 100644
--- a/Main/System/FirstCharge/FirstChargeWin.cs
+++ b/Main/System/FirstCharge/FirstChargeWin.cs
@@ -106,7 +106,7 @@
     private void OnClickPreviewHero()
     {
         HeroUIManager.Instance.selectForPreviewHeroID = model.mainItemId;
-        UIManager.Instance.OpenWindowAsync<HeroBestWin>().Forget();
+        UIManager.Instance.OpenWindow<HeroBestBaseWin>().Forget();
     }
     private void InitRedPoint()
     {
@@ -258,7 +258,7 @@
             OrderInfoConfig orderInfoConfig;
             if (model.TryGetOrderInfoConfigByFirstID(firstID, out orderInfoConfig))
             {
-                txtTabTitles[i].text = Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale);
+                txtTabTitles[i].text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfoConfig.PayRMBNumOnSale));
             }
         }
     }
@@ -281,7 +281,7 @@
         bool isBuy = firstChargeData.IsBuy();
         btnBuy.SetActive(!isBuy);
         btnHave.SetActive(isBuy);
-        txtBuy.text = Language.Get("PayMoneyNum", orderInfo.PayRMBNumOnSale);
+        txtBuy.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfo.PayRMBNumOnSale));
         //棰嗗彇
         int day = firstChargeData.GetNowBuyDay();
         //0: 宸查鍙� 1: 涓嶅彲棰嗗彇 2: 鍙鍙� 
diff --git a/Main/System/FirstCharge/HeroShowLHWin.cs b/Main/System/FirstCharge/HeroShowLHWin.cs
index fe16948..e7ef577 100644
--- a/Main/System/FirstCharge/HeroShowLHWin.cs
+++ b/Main/System/FirstCharge/HeroShowLHWin.cs
@@ -57,7 +57,9 @@
         roleLHModelTween.Play();
         roleLHModelTween2.SetStartState();
         roleLHModelTween2.Play();
-        bgTexture.SetTexture2D("countryBG" + hero.Country);
+        bgTexture.SetTexture2D(HeroUIManager.Instance.GetBGName(hero.SkinIDList[0], hero.Country));
+
+        HeroUIManager.Instance.PlayerLHSound(hero.SkinIDList[0]);
     }
 
     void RefreshHeroInfo(int heroID)
diff --git a/Main/System/FuncPreset/FuncPresetManager.cs b/Main/System/FuncPreset/FuncPresetManager.cs
index 44f8f82..26bc446 100644
--- a/Main/System/FuncPreset/FuncPresetManager.cs
+++ b/Main/System/FuncPreset/FuncPresetManager.cs
@@ -401,9 +401,10 @@
 //鎴樻枟鍔熻兘鍖哄垎瀵瑰簲瀛樺偍鍏ㄥ眬鏂规ID锛屽婕旀鍦洪槻瀹堢敤鍝釜鍏ㄥ眬鏂规ID鐨勫垎绫�
 public enum BattlePreSetType
 {
-	None = 0,
-	Story = 1, //涓荤嚎
-	Arena = 2,  //婕旀鍦洪槻瀹�
+    None = 0,
+    Story = 1, //涓荤嚎
+    Arena = 2,  //婕旀鍦洪槻瀹�
+    Qunying = 3, //缇よ嫳鎴橀槻瀹�
 
 }
 
diff --git a/Main/System/GeneralConfig/DayRemind.cs b/Main/System/GeneralConfig/DayRemind.cs
index 66fd828..043afa4 100644
--- a/Main/System/GeneralConfig/DayRemind.cs
+++ b/Main/System/GeneralConfig/DayRemind.cs
@@ -37,6 +37,11 @@
     public const string OSMainLevel = "OSMainLevel"; // 寮�鏈嶄富绾垮叧鍗℃椿鍔ㄦ彁绀虹孩鐐�
     public const string OSGalaChange = "OSGalaChange"; // 寮�鏈嶅簡鍏稿厬鎹㈡彁绀虹孩鐐�
 
+    public const string OSHeroTrain = "OSHeroTrain";
+    public const string OSBeautyMM = "OSBeautyMM";
+    public const string OSMingge = "OSMingge";
+
+
     public Dictionary<string, int[]> dayRemindDic = new Dictionary<string, int[]>();
 
     public bool GetDayRemind(string _remindKey)
@@ -79,6 +84,9 @@
         SetDayRemind(DJQTip);
         SetDayRemind(OSMainLevel);
         SetDayRemind(OSGalaChange);
+        SetDayRemind(OSHeroTrain);
+        SetDayRemind(OSBeautyMM);
+        SetDayRemind(OSMingge);
     }
 
     public void SetDayRemind(string _key)
diff --git a/Main/System/GeneralConfig/GeneralDefine.cs b/Main/System/GeneralConfig/GeneralDefine.cs
index d8cf231..9795b71 100644
--- a/Main/System/GeneralConfig/GeneralDefine.cs
+++ b/Main/System/GeneralConfig/GeneralDefine.cs
@@ -44,6 +44,12 @@
     public static int lvExpFullTipLimit { get; private set; }
     public static Dictionary<string, string> commonAwardTipDict { get; private set; }
 
+    public static int[][] review_Awards;
+    public static Dictionary<string, string> review_UrlDict;
+    public static int review_MainLevel;
+    public static int review_CD;
+    public static string[] noAdsChannels;
+    public static int[] heroSkinGiftList;
     public static void Init()
     {
         try
@@ -100,6 +106,17 @@
 
             config = FuncConfigConfig.Get("AwardEventTip");
             commonAwardTipDict = JsonMapper.ToObject<Dictionary<string, string>>(config.Numerical1);
+
+            config = FuncConfigConfig.Get("GoodGameReward");
+            review_Awards = JsonMapper.ToObject<int[][]>(config.Numerical1);
+            config = FuncConfigConfig.Get("Review");
+            review_UrlDict = JsonMapper.ToObject<Dictionary<string, string>>(config.Numerical2);
+            review_MainLevel = int.Parse(config.Numerical3);
+            review_CD = int.Parse(config.Numerical4);
+            noAdsChannels = JsonMapper.ToObject<string[]>(config.Numerical5);
+
+            config = FuncConfigConfig.Get("HeroSkinGift");
+            heroSkinGiftList = JsonMapper.ToObject<int[]>(config.Numerical1);
         }
         catch (Exception ex)
         {
@@ -298,6 +315,12 @@
 
     public static long GetFactValue(uint value, uint valueEx)
     {
-        return (long)valueEx * (long)Constants.ExpPointValue +(long)value;
+        return (long)valueEx * (long)Constants.ExpPointValue + (long)value;
+    }
+
+    //绾﹀畾锛歱layerID<1000000涓烘満鍣ㄤ汉 瀹為檯璇峰弬鑰冩満鍣ㄤ汉琛�
+    public static bool IsRobot(int playerID)
+    {
+        return playerID < 1000000;
     }
 }
diff --git a/Main/System/Gubao/GubaoSuiteListWin.cs b/Main/System/Gubao/GubaoSuiteListWin.cs
index 9b9495a..cdde6fa 100644
--- a/Main/System/Gubao/GubaoSuiteListWin.cs
+++ b/Main/System/Gubao/GubaoSuiteListWin.cs
@@ -38,6 +38,7 @@
     {
         scroller.Refresh();
         var keys = GubaoResonanceConfig.GetKeys();
+        keys.Sort((a, b) => GubaoResonanceConfig.Get(a).sortIndex.CompareTo(GubaoResonanceConfig.Get(b).sortIndex));
         for (int i = 0; i < keys.Count; i++)
         {
             scroller.AddCell(ScrollerDataType.Header, keys[i]);
diff --git a/Main/System/Guild/GuildBaseWin.cs b/Main/System/Guild/GuildBaseWin.cs
index ab9cd79..9b5325f 100644
--- a/Main/System/Guild/GuildBaseWin.cs
+++ b/Main/System/Guild/GuildBaseWin.cs
@@ -219,7 +219,7 @@
 
     public void OnClickTalkButton()
     {
-        ChatManager.Instance.nowChatTab = ChatTab.Guild;
+        ChatManager.Instance.nowChatTab = ChatChannel.Guild;
         ChatManager.Instance.nowChatChannel = ChatChannel.Guild;
         UIManager.Instance.OpenWindowAsync<ChatWin>().Forget();
     }
diff --git a/Main/System/Guild/GuildBossManager.cs b/Main/System/Guild/GuildBossManager.cs
index 4812420..b96ceef 100644
--- a/Main/System/Guild/GuildBossManager.cs
+++ b/Main/System/Guild/GuildBossManager.cs
@@ -337,7 +337,7 @@
     {
         redPoint.state = RedPointState.None;
 
-        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Guild))
+        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.GuildBoss))
         {
             return;
         }
diff --git a/Main/System/HappyXB/HappyXBModel.cs b/Main/System/HappyXB/HappyXBModel.cs
index 6e9ac4e..3a1df6c 100644
--- a/Main/System/HappyXB/HappyXBModel.cs
+++ b/Main/System/HappyXB/HappyXBModel.cs
@@ -19,11 +19,11 @@
     {
         get
         {
-            #if UNITY_EDITOR
+#if UNITY_EDITOR
             if (Time.time - xbLastTime > 1)
-            #else
+#else
             if (Time.time - xbLastTime > 10)
-            #endif
+#endif
             {
                 m_IsWaitServerXB = false;
                 return m_IsWaitServerXB;
@@ -37,7 +37,7 @@
             m_IsWaitServerXB = value;
             xbLastTime = Time.time;
         }
-    }  
+    }
     private Dictionary<int, XBTypeInfo> xbTypeInfoDict = new Dictionary<int, XBTypeInfo>(); //鎶藉鐘舵�佺浉鍏崇殑 鏈嶅姟鍣ㄨ褰�
 
     public int lhQuality;
@@ -134,6 +134,8 @@
     public int addXBScore { get; private set; }
     public int addXBScoreType { get; private set; } //瀵诲疂绉垎璐у竵绫诲瀷
     public int addXBLuckValue { get; private set; }
+    public int addXBAddItemID { get; private set; } // 鏈瀵诲疂棰濆璧犻�佺殑鐗╁搧ID
+    public long addXBItemCount { get; private set; }   // 鏈瀵诲疂棰濆璧犻�佺殑鐗╁搧ID涓暟
     public Dictionary<int, XBGetItem> xbResultDict { get; private set; } = new Dictionary<int, XBGetItem>(); //濂栧搧椤哄簭锛氬鍝�
     public void GetServerXBResult(HA350_tagMCTreasureResult result)
     {
@@ -142,6 +144,8 @@
         addXBScore = result.AddMoneyValue;
         addXBScoreType = result.AddMoneyType;
         addXBLuckValue = result.AddTreasureLuck;
+        addXBAddItemID = (int)result.AddItemID;
+        addXBItemCount = result.AddItemCount;
         JsonData resultData = JsonMapper.ToObject(result.TreasureResult);
         if (resultData.IsArray)
         {
@@ -180,11 +184,19 @@
                 UIManager.Instance.OpenWindowAsync<HeroCallResultWin>().Forget();
             }
         }
+
+        if (ActHeroAppearConfig.GetActTreasureTypeList().Contains(type))
+        {
+            if (!UIManager.Instance.IsOpened<HeroDebutCallResultWin>())
+            {
+                UIManager.Instance.OpenWindow<HeroDebutCallResultWin>();
+            }
+        }
     }
 
 
     public int GetCountInResult(int itemID)
-    { 
+    {
         int count = 0;
         if (xbResultDict != null && xbResultDict.Count > 0)
         {
@@ -205,7 +217,7 @@
         xbResultDict.Clear();
     }
 
-    
+
     public void GetServerXBInfo(HA351_tagMCTreasureInfo info)
     {
         for (int i = 0; i < info.InfoCount; i++)
@@ -218,6 +230,7 @@
                 typeInfo.freeCountToday = info.TreasuerInfoList[i].FreeCountToday;
                 typeInfo.treasureCount = (int)info.TreasuerInfoList[i].TreasureCount;
                 typeInfo.treasureCountToday = (int)info.TreasuerInfoList[i].TreasureCountToday;
+                typeInfo.treasureCountTodayGold = (int)info.TreasuerInfoList[i].TreasureCountTodayGold;
                 typeInfo.treasureCntAward = (int)info.TreasuerInfoList[i].TreasureCntAward;
                 if (typeInfo.gridLimitCntDict == null)
                     typeInfo.gridLimitCntDict = new Dictionary<int, int>();
@@ -256,6 +269,7 @@
                 xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].freeCountToday = info.TreasuerInfoList[i].FreeCountToday;
                 xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].treasureCount = (int)info.TreasuerInfoList[i].TreasureCount;
                 xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].treasureCountToday = (int)info.TreasuerInfoList[i].TreasureCountToday;
+                xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].treasureCountTodayGold = (int)info.TreasuerInfoList[i].TreasureCountTodayGold;
                 xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].treasureCntAward = (int)info.TreasuerInfoList[i].TreasureCntAward;
                 if (xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].gridLimitCntDict == null)
                     xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].gridLimitCntDict = new Dictionary<int, int>();
@@ -265,7 +279,7 @@
                     int cnt = info.TreasuerInfoList[i].GridLimitCntList[j].GridCnt;
                     xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].gridLimitCntDict[num] = cnt;
                 }
-                
+
                 xbTypeInfoDict[info.TreasuerInfoList[i].TreasureType].wishCntDict.Clear();
                 for (int j = 0; j < info.TreasuerInfoList[i].WishLibCnt; j++)
                 {
@@ -313,7 +327,7 @@
     public void SendXBQuest(int type, int index, int costType)
     {
         if (isXBCoolTime) return;
-        
+
         isXBCoolTime = true;
         CA568_tagCMRequestTreasure treasure = new CA568_tagCMRequestTreasure();
         treasure.TreasureType = (byte)type;
@@ -326,7 +340,19 @@
         }
     }
 
-
+    public bool CheckIsEmptyGrid(int[] checkPackList, int needGrid = 1)
+    {
+        if (checkPackList.IsNullOrEmpty())
+            return true;
+        for (int i = 0; i < checkPackList.Length; i++)
+        {
+            if (!CheckIsEmptyGrid((PackType)checkPackList[i], needGrid))
+            {
+                return false;
+            }
+        }
+        return true;
+    }
 
     public bool CheckIsEmptyGrid(PackType type, int needGrid = 1)
     {
@@ -369,7 +395,7 @@
         }
 
         var funcSet = TreasureSetConfig.Get(xbType);
-        if (CheckIsEmptyGrid((PackType)config.PackType))
+        if (CheckIsEmptyGrid(config.CheckPackList))
         {
             //閬撳叿瀵诲疂
             if (funcSet.CostItemID != 0 && IsHaveOneXBTool(xbType))
@@ -424,7 +450,7 @@
         }
 
         var funcSet = TreasureSetConfig.Get(xbType);
-        if (CheckIsEmptyGrid((PackType)config.PackType, 10))
+        if (CheckIsEmptyGrid(config.CheckPackList, 10))
         {
             int toolCnt = 0;
             int needToolCnt = 0;
@@ -494,7 +520,7 @@
         {
             return typeInfo.freeCountToday;
         }
-        
+
         return 0;
     }
 
@@ -508,7 +534,7 @@
     {
         qualityList = new List<int>();
 
-        //鏃犻厤缃啓姝�
+        //鏃犻厤缃啓姝诲搧璐�
         if (type == (int)HappXBTitle.Gubao)
         {
             qualityList.Add(3);
@@ -525,10 +551,15 @@
         var xbConfig = GetXBItemConfigByType(type);
         var luckList = xbConfig.LuckyItemRateInfo.Keys.ToList();
         luckList.Sort();
-        //鎸夐樁姊樉绀�
         for (int i = 0; i < luckList.Count; i++)
         {
-            if (typeInfo.luckValue < luckList[i])
+            //寮�鐗规潈鍗′箣鍚庢墠鏈夊垢杩愬鍔�
+            var luckyValue = typeInfo.luckValue;
+            if (type == (int)HappXBTitle.HeroCallAdvanced && !InvestModel.Instance.IsInvested(InvestModel.foreverCardType))
+            {
+                luckyValue = 0;
+            }
+            if (luckyValue < luckList[i])
             {
                 if (type == (int)HappXBTitle.HeroCallAdvanced)
                 {
@@ -536,7 +567,7 @@
                     qualityList = xbConfig.LuckyItemRateInfo[luckList[i]].Select(x => x[1]).ToList();
                     qualityList.Sort();
                 }
-                return luckList[i] - typeInfo.luckValue;
+                return luckList[i] - luckyValue;
             }
         }
         return 0;
@@ -596,12 +627,12 @@
                 needMoney = funcSet.CostMoneyList[0] * (needToolCnt - toolCnt);
             }
             else
-            { 
+            {
                 //鍏ㄩ儴涓嶈冻鐨勬寜澶氭浠锋牸绠� 鍙兘閰嶇疆浜嗘姌鎵�
                 needMoney = funcSet.CostMoneyList[1];
             }
         }
-        
+
         return false;
     }
 
@@ -613,7 +644,7 @@
     }
 
     public int GetCostItemID(int type)
-    { 
+    {
         var funcSet = TreasureSetConfig.Get(type);
         if (funcSet == null) return 0;
         return funcSet.CostItemID;
@@ -632,7 +663,7 @@
     public Redpoint bestXB10Red = new Redpoint(HappyXB_RedKey, XBHeroCall10_RedKey);
     public Redpoint bestXBScoreRed = new Redpoint(HappyXB_RedKey, XBHeroCallScore_RedKey);
 
-    
+
 
     private void UpdateFuncState(int funcId)
     {
@@ -656,7 +687,7 @@
             return;
         }
 
-        
+
     }
 
     void OnDayEvent()
@@ -683,12 +714,12 @@
 
         if (IsHaveFreeXB((int)HappXBTitle.HeroCallAdvanced))
         {
-            bestXBFreeRed.state = PlayerDatas.Instance.baseData.realmLevel >= 1 ?RedPointState.GetReward : RedPointState.Simple;
+            bestXBFreeRed.state = PlayerDatas.Instance.baseData.realmLevel >= 1 ? RedPointState.GetReward : RedPointState.Simple;
         }
 
         if (IsHaveManyXBToolEx((int)HappXBTitle.HeroCallAdvanced, out int xbtoolCnt, out int needtoolCnt, out int needMoney))
         {
-            bestXB10Red.state = PlayerDatas.Instance.baseData.realmLevel >= 1 ?RedPointState.GetReward : RedPointState.Simple;
+            bestXB10Red.state = PlayerDatas.Instance.baseData.realmLevel >= 1 ? RedPointState.GetReward : RedPointState.Simple;
             return;
         }
 
@@ -696,8 +727,8 @@
         if ((InvestModel.Instance.IsInvested(InvestModel.monthCardType)
         || GetXBInfoByType((int)HappXBTitle.HeroCallScore)?.treasureCount == 0)
         && UIHelper.GetMoneyCnt(51) >= TreasureSetConfig.Get((int)HappXBTitle.HeroCallScore).CostMoneyList[0])
-        { 
-            bestXBScoreRed.state = PlayerDatas.Instance.baseData.realmLevel >= 1 ?RedPointState.GetReward : RedPointState.Simple;
+        {
+            bestXBScoreRed.state = PlayerDatas.Instance.baseData.realmLevel >= 1 ? RedPointState.GetReward : RedPointState.Simple;
         }
 
     }
@@ -713,7 +744,7 @@
         return itemIDListTemp.Distinct().ToList();
 
     }
-    
+
     #endregion
 }
 
@@ -724,6 +755,7 @@
     public int freeCountToday;      //浠婃棩宸插厤璐瑰瀹濇鏁�
     public int treasureCount;        //宸插瀹濇�绘鏁�
     public int treasureCountToday;        //浠婃棩宸插瀹濇�绘鏁�
+    public int treasureCountTodayGold;  //浠婃棩娑堣�楄揣甯佸凡瀵诲疂鎬绘鏁�
     public int treasureCntAward;        //绱瀵诲疂娆℃暟瀵瑰簲濂栧姳棰嗗鐘舵�侊紝鎸夊鍔辫褰曠储寮曚簩杩涘埗璁板綍鏄惁宸查鍙�
     public Dictionary<int, int> gridLimitCntDict;        //<鏈夐檺鍒舵娊鍙栨鏁扮殑鏍煎瓙缂栧彿,宸叉娊鍒版鏁�> 鏈夐檺鍒舵娊鍙栨鏁扮殑鏍煎瓙娆℃暟淇℃伅
     public Dictionary<int, XBWishInfo> wishCntDict;        //蹇冩効鎶藉彇鎯呭喌 <LIBID锛氬凡鎶藉埌娆℃暟锛屾槸鍚﹀嬀閫夎嚜鍔紝褰撳墠蹇冩効ID>
diff --git a/Main/System/HappyXB/HeroCallHopeAddCell.cs b/Main/System/HappyXB/HeroCallHopeAddCell.cs
index 4d1cec9..a081469 100644
--- a/Main/System/HappyXB/HeroCallHopeAddCell.cs
+++ b/Main/System/HappyXB/HeroCallHopeAddCell.cs
@@ -12,6 +12,7 @@
     [SerializeField] Button addBtn;
     [SerializeField] Transform tipRect;
     [SerializeField] Text freeText;
+    [SerializeField] Text powerText;
     [SerializeField] Text itemCntText;
     [SerializeField] Image itemIcon;
 
@@ -38,7 +39,8 @@
         {
             return;
         }
-        if (wishData.wishCnt < HappyXBModel.wishMaxOutCnt)
+        bool isInvest = InvestModel.Instance.IsInvested(InvestModel.monthCardType);
+        if (wishData.wishCnt < HappyXBModel.wishMaxOutCnt || isInvest)
         {
             var clientwWishID = quality == 5 ? HappyXBModel.Instance.selectSHHeroWishID : HappyXBModel.Instance.selectCSHeroWishID;
             if (clientwWishID <= 0)
@@ -48,7 +50,17 @@
             else
             {
                 tipRect.SetActive(true);
-                freeText.SetActive(true);
+                if (isInvest)
+                {
+                    powerText.SetActive(true);
+                    freeText.SetActive(false);
+                }
+                else
+                {
+                    powerText.SetActive(false);
+                    freeText.SetActive(true);
+                }
+
                 itemCntText?.SetActive(false);
 
             }
@@ -64,6 +76,7 @@
             {
                 tipRect.SetActive(true);
                 freeText.SetActive(false);
+                powerText.SetActive(false);
                 itemCntText.SetActive(true);
                 itemIcon.SetItemSprite(itemID);
                 itemCntText.text = UIHelper.ShowUseItem(PackType.Item, itemID, 1, bright: false);
diff --git a/Main/System/HappyXB/HeroCallHopeWin.cs b/Main/System/HappyXB/HeroCallHopeWin.cs
index 563581c..13c1c24 100644
--- a/Main/System/HappyXB/HeroCallHopeWin.cs
+++ b/Main/System/HappyXB/HeroCallHopeWin.cs
@@ -50,11 +50,12 @@
         HappyXBModel.Instance.selectWishListTab = functionOrder;
         HappyXBModel.Instance.RefreshXBTypeInfoAct += RefreshXBTypeInfo;
         HappyXBModel.Instance.OnSelectWishHeroEvent += OnSelectWishHeroEvent;
+        InvestModel.Instance.onInvestUpdate += OnInvestUpdate;
         scroller.OnRefreshCell += OnRefreshCell;
         HappyXBModel.Instance.TryGetHeroWishIDByQuality((int)HappXBTitle.HeroCallAdvanced, 5, out HappyXBModel.Instance.selectSHHeroWishID, out int shWishCnt, out bool shAuto);
         HappyXBModel.Instance.TryGetHeroWishIDByQuality((int)HappXBTitle.HeroCallAdvanced, 4, out HappyXBModel.Instance.selectCSHeroWishID, out int csWishCnt, out bool cqAuto);
-        
-        tip.text = Language.Get("HeroCall7", HappyXBModel.wishMaxOutCnt);
+
+
         Display();
     }
 
@@ -63,10 +64,28 @@
         HappyXBModel.Instance.RefreshXBTypeInfoAct -= RefreshXBTypeInfo;
         scroller.OnRefreshCell -= OnRefreshCell;
         HappyXBModel.Instance.OnSelectWishHeroEvent -= OnSelectWishHeroEvent;
+        InvestModel.Instance.onInvestUpdate -= OnInvestUpdate;
     }
+
+
+    void OnInvestUpdate(int type)
+    {
+        Display();
+    }
+
 
     void Display()
     {
+        bool isInvest = InvestModel.Instance.IsInvested(InvestModel.monthCardType);
+        if (isInvest)
+        {
+            tip.text = Language.Get("HeroCall17");
+        }
+        else
+        {
+            tip.text = Language.Get("HeroCall7", HappyXBModel.wishMaxOutCnt) + Language.Get("HeroCall18");
+        }
+
         int shHeroID = 0;
         if (HappyXBModel.Instance.selectSHHeroWishID == -1)
         {
diff --git a/Main/System/HappyXB/HeroCallResultWin.cs b/Main/System/HappyXB/HeroCallResultWin.cs
index 5830d55..e9a7be4 100644
--- a/Main/System/HappyXB/HeroCallResultWin.cs
+++ b/Main/System/HappyXB/HeroCallResultWin.cs
@@ -123,6 +123,7 @@
             resultState = HeroUIManager.Instance.selectCallIndex == 0 ? ResultState.single : ResultState.ten;
 
             RefreshState();
+            CheckWishFinishOnSkip();
         }
         else
         {
@@ -338,7 +339,11 @@
         roleLHModelTween2.SetStartState();
         roleLHModelTween2.Play();
 
-        bgTexture.SetTexture2D("countryBG" + hero.Country);
+        bgTexture.SetTexture2D(HeroUIManager.Instance.GetBGName(hero.SkinIDList[0], hero.Country));
+        if (IsWishHero(heroID))
+        {
+            UIManager.Instance.OpenWindow<HeroCallXYFinishWin>();
+        }
     }
 
     void RefreshHeroInfo(int heroID)
@@ -365,4 +370,45 @@
         }
         callTip.text = Language.Get("HeroCall6", needCount, string.Join(Language.Get("L1130"), qualityStrList.ToArray()));
     }
+
+    /// <summary>
+    /// 璺宠繃鍔ㄧ敾鏃讹紝妫�鏌ユ槸鍚︽娊鍒颁簡蹇冩効姝﹀皢
+    /// </summary>
+    void CheckWishFinishOnSkip()
+    {
+        // 鍙湁楂樼骇鎷涘嫙鎵嶆湁蹇冩効
+        if (HeroUIManager.Instance.selectCallType != HappXBTitle.HeroCallAdvanced) return;
+
+        for (int i = 0; i < HappyXBModel.Instance.xbResultDict.Count; i++)
+        {
+            int heroID = HappyXBModel.Instance.xbResultDict[i].itemId;
+            if (IsWishHero(heroID))
+            {
+                // 鎶藉埌浜嗗績鎰挎灏嗭紝鎵撳紑瀹屾垚鐗规晥鐣岄潰
+                UIManager.Instance.OpenWindow<HeroCallXYFinishWin>();
+                break;
+            }
+        }
+    }
+
+    /// <summary>
+    /// 鍒ゆ柇鎸囧畾鐨勮嫳闆処D鏄惁涓哄綋鍓嶉�変腑鐨勫績鎰挎灏�
+    /// </summary>
+    bool IsWishHero(int heroID)
+    {
+        if (HeroUIManager.Instance.selectCallType != HappXBTitle.HeroCallAdvanced) return false;
+
+        var hero = HeroConfig.Get(heroID);
+        if (hero == null) return false;
+
+        if (HappyXBModel.Instance.TryGetHeroWishIDByQuality((int)HappXBTitle.HeroCallAdvanced, hero.Quality, out int wishID, out _, out _))
+        {
+            var libCfg = TreasureItemLibConfig.Get(wishID);
+            if (libCfg != null && libCfg.ItemID == heroID)
+            {
+                return true;
+            }
+        }
+        return false;
+    }
 }
\ No newline at end of file
diff --git a/Main/System/HappyXB/HeroCallWin.cs b/Main/System/HappyXB/HeroCallWin.cs
index 033293e..08bf3fe 100644
--- a/Main/System/HappyXB/HeroCallWin.cs
+++ b/Main/System/HappyXB/HeroCallWin.cs
@@ -102,6 +102,8 @@
     void OnInvestUpdate(int type)
     {
         openPrivilegeTip.SetActive(!InvestModel.Instance.IsInvested(InvestModel.foreverCardType));
+        shHero.Display(5);
+        csHero.Display(4);
     }
 
     public override void Refresh()
diff --git a/Main/System/HappyXB/HeroCallXYFinishWin.cs b/Main/System/HappyXB/HeroCallXYFinishWin.cs
new file mode 100644
index 0000000..47423f9
--- /dev/null
+++ b/Main/System/HappyXB/HeroCallXYFinishWin.cs
@@ -0,0 +1,23 @@
+using System;
+using UnityEngine;
+
+public class HeroCallXYFinishWin : UIBase
+{
+    [SerializeField] UIEffectPlayer xyFinishUIEffect;
+    protected override void OnPreOpen()
+    {
+        xyFinishUIEffect.onComplete += OnComplete;
+        xyFinishUIEffect.Play();
+    }
+
+    protected override void OnPreClose()
+    {
+        xyFinishUIEffect.onComplete -= OnComplete;
+        xyFinishUIEffect.Stop();
+    }
+
+    private void OnComplete()
+    {
+        CloseWindow();
+    }
+}
\ No newline at end of file
diff --git a/Main/System/HappyXB/HeroCallXYFinishWin.cs.meta b/Main/System/HappyXB/HeroCallXYFinishWin.cs.meta
new file mode 100644
index 0000000..98e8b91
--- /dev/null
+++ b/Main/System/HappyXB/HeroCallXYFinishWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 52b2744981baf7b47b433b13fcf02f38
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Hero/HeroInfo.Skin.cs b/Main/System/Hero/HeroInfo.Skin.cs
index 3f329fa..8d1b20e 100644
--- a/Main/System/Hero/HeroInfo.Skin.cs
+++ b/Main/System/Hero/HeroInfo.Skin.cs
@@ -1,9 +1,10 @@
+using System;
 using System.Collections.Generic;
 using UnityEngine;
 
 public partial class HeroInfo
 {
-    // 78 # 鑻遍泟浣跨敤鐨勭毊鑲ょ储寮�
+    // 78 # 鑻遍泟浣跨敤鐨勭毊鑲ょ储寮� (褰㈣薄)
     public int SkinIndex
     {
         get
@@ -25,12 +26,59 @@
 
     //  鐨偆閰嶇疆
     public HeroSkinConfig skinConfig
-    { 
+    {
         get
         {
             return HeroSkinConfig.Get(SkinID);
         }
     }
 
-    
+    //灞炴�х敓鏁堢殑鐨偆绱㈠紩
+    public int SkinAttrIndex
+    {
+        get
+        {
+            if (itemHero == null)
+                return 0;
+            return itemHero.GetUseDataFirstValue(82);
+        }
+    }
+
+    public int SkinAttrID
+    {
+        get
+        {
+            return heroConfig.SkinIDList[SkinAttrIndex];
+        }
+    }
+
+
+    public int GetHeroSkinValue(int attrType)
+    {
+        var cfg = HeroSkinAttrConfig.Get(SkinAttrID);
+        if (cfg == null)
+            return 0;
+        var index = Array.IndexOf(cfg.WearAttrIDList, attrType);
+        if (index == -1)
+            return 0;
+        return cfg.WearAttrValueList[index];
+    }
+
+	public int GetHeroSkinPer(int attrType)
+	{
+        var cfg = HeroSkinAttrConfig.Get(SkinAttrID);
+        if (cfg == null)
+            return 0;
+            
+		var _type = 0;
+		if (PlayerPropertyConfig.baseAttr2perDict.ContainsKey(attrType))
+		{
+			_type = PlayerPropertyConfig.baseAttr2perDict[attrType];
+		}
+		
+        var index = Array.IndexOf(cfg.WearAttrIDList, _type);
+        if (index == -1)
+            return 0;
+        return cfg.WearAttrValueList[index];
+    }
 }
\ No newline at end of file
diff --git a/Main/System/Hero/UIHeroController.cs b/Main/System/Hero/UIHeroController.cs
index 3c89fe5..687b490 100644
--- a/Main/System/Hero/UIHeroController.cs
+++ b/Main/System/Hero/UIHeroController.cs
@@ -1,10 +1,10 @@
 
 using System;
-using Cysharp.Threading.Tasks;
 using Spine;
 using Spine.Unity;
 using UnityEngine;
 using UnityEngine.UI;
+using Cysharp.Threading.Tasks;
 
 public class UIHeroController : MonoBehaviour
 {
@@ -14,6 +14,16 @@
 
 	public Spine.AnimationState spineAnimationState;
 	private GameObject instanceGO;
+	private bool isInitializing = false;
+	private bool isInitialized = false;
+	private System.Threading.CancellationTokenSource loadCancellationToken; // 鐢ㄤ簬鍙栨秷涔嬪墠鐨勫姞杞戒换鍔�
+
+	// 浣跨敤 UniTask 鎻愪緵鐨勫苟鍙戞帶鍒� - 鏀寔 WebGL
+	// 闄愬埗鍚屾椂鍔犺浇鐨勮祫婧愭暟閲忥紙榛樿涓�4锛屽彲鏍规嵁璁惧鎬ц兘璋冩暣锛�
+	private const int MAX_CONCURRENT_LOADS = 4;
+	private static int currentLoadingCount = 0;
+	private static readonly object loadLock = new object();
+	private static int initializationOrder = 0; // 鐢ㄤ簬鍒嗗抚寤惰繜鐨勫簭鍙�
 
 	public Action onComplete;
 	public async UniTask Create(int _skinID, float scale = 0.8f, Action _onComplete = null, string motionName = "idle", bool isLh = false)
@@ -39,6 +49,11 @@
 				}
 			}
 			return;
+		}
+
+		if (skeletonGraphic != null)
+		{
+			skeletonGraphic.enabled = false;
 		}
 
 		skinID = _skinID;
@@ -90,66 +105,26 @@
 		}
 
 		onComplete = _onComplete;
-		pool = GameObjectPoolManager.Instance.GetPool(await UILoader.LoadPrefabAsync("UIHero"));
 
-		if (!transform.gameObject.activeSelf)
+
+		// 鍙栨秷涔嬪墠鐨勫紓姝ヤ换鍔★紝閬垮厤澶氭璋冪敤瀵艰嚧閿欎贡
+		CancelLoadTask();
+		// 鍒涘缓鏂扮殑鍙栨秷浠ょ墝
+		loadCancellationToken = new System.Threading.CancellationTokenSource();
+		// 浣跨敤 UniTask 杩涜寮傛鍒濆鍖栵紝灏唅nstanceGO鍒涘缓鍜岃祫婧愬姞杞介兘绉诲埌寮傛澶勭悊
+		DelayedInitializeAsync(skinConfig, motionName, isLh, loadCancellationToken.Token).Forget();
+	}
+
+	/// <summary>
+	/// 鍙栨秷涔嬪墠鐨勫姞杞戒换鍔�
+	/// </summary>
+	private void CancelLoadTask()
+	{
+		if (loadCancellationToken != null && !loadCancellationToken.IsCancellationRequested)
 		{
-			transform.SetActive(true);
+			loadCancellationToken.Cancel();
+			loadCancellationToken.Dispose();
 		}
-		if (instanceGO == null)
-		{
-			instanceGO = pool.Request();
-			instanceGO.transform.SetParent(transform);
-			//transform 鐨凱ivot Y鏄�0锛岃instanceGO 灞呬腑
-			instanceGO.transform.localPosition = new Vector3(0, instanceGO.GetComponent<RectTransform>().sizeDelta.y * 0.5f);
-
-			//instanceGO.transform.localPosition = Vector3.zero;
-			instanceGO.transform.localScale = Vector3.one;
-			instanceGO.transform.localRotation = Quaternion.identity;
-		}
-
-		skeletonGraphic = instanceGO.GetComponentInChildren<SkeletonGraphic>(true);
-		if (isLh)
-		{
-			skeletonGraphic.skeletonDataAsset = await ResManager.Instance.LoadAssetAsync<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.Tachie);
-		}
-		else
-		{
-			skeletonGraphic.skeletonDataAsset = await ResManager.Instance.LoadAssetAsync<SkeletonDataAsset>("Hero/SpineRes/", skinConfig.SpineRes);
-		}
-		if (skeletonGraphic.skeletonDataAsset == null)
-		{
-
-			transform.SetActive(false);
-			if (pool != null)
-				pool.Release(instanceGO);
-			skeletonGraphic = null;
-			Destroy(instanceGO);
-			Debug.LogError("鏈厤缃畇pine");
-			return;
-		}
-		skeletonGraphic.initialSkinName = skinConfig.InitialSkinName;
-		skeletonGraphic.Initialize(true);
-		// 鍒濆鍖栧畬鎴愬悗璁剧疆鐨偆
-		if (!string.IsNullOrEmpty(skinConfig.InitialSkinName))
-		{
-			var skeleton = skeletonGraphic.Skeleton;
-			skeleton.SetSkin(skinConfig.InitialSkinName);
-			skeleton.SetSlotsToSetupPose();
-			skeletonGraphic.Update(0);
-		}
-
-		skeletonGraphic.enabled = true;
-		SetMaterialNone();
-
-		spineAnimationState = skeletonGraphic.AnimationState;
-		spineAnimationState.Data.DefaultMix = 0f;
-		if (motionName == "")
-			motionName = GetFistSpineAnim();
-
-		PlayAnimation(motionName, true);
-		spineAnimationState.Complete -= OnAnimationComplete;
-		spineAnimationState.Complete += OnAnimationComplete;
 	}
 
 	public async UniTask CreateAsync(int _skinID, float scale = 0.8f, Action _onComplete = null, string motionName = "idle", bool isLh = false)
@@ -299,12 +274,20 @@
 
 	public bool HasAnimation(string motionName)
 	{
-		return skeletonGraphic != null && skeletonGraphic.Skeleton != null && skeletonGraphic.Skeleton.ContainsMotion(motionName);
+		if (skeletonGraphic == null || skeletonGraphic.Skeleton == null)
+		{
+			Debug.LogWarning("skeletonGraphic or Skeleton is null, cannot check animation: " + motionName);
+			return false;
+		}
+		return skeletonGraphic.Skeleton.ContainsMotion(motionName);
 	}
 
 
 	protected void OnDestroy()
 	{
+		// 鍙栨秷姝e湪杩涜鐨勫姞杞戒换鍔�
+		CancelLoadTask();
+
 		if (spineAnimationState != null)
 		{
 			spineAnimationState.Complete -= OnAnimationComplete;
@@ -315,6 +298,13 @@
 		pool = null;
 	}
 
+	private string pendingAnimationName = null;
+	private bool pendingAnimationLoop = false;
+	private bool pendingAnimationReplay = true;
+	private float? pendingSpeed = null;
+	private bool pendingEnabled = true; // 鏀逛负鏅�歜ool锛宖alse琛ㄧず鏈缃紝true琛ㄧず闇�瑕佸惎鐢�
+	private bool pendingGray = false; // 鏀逛负鏅�歜ool锛岃〃绀烘槸鍚﹂渶瑕佽缃伆搴�
+
 	/// <summary>
 	/// 鎾斁 Spine 鍔ㄧ敾
 	/// </summary>
@@ -323,18 +313,45 @@
 	/// <param name="replay">濡傛灉鐩稿悓鍔ㄤ綔鏄惁鍐嶆閲嶆挱锛屾瘮濡傝窇姝ラ噸鎾氨浼氳烦甯т笉椤烘粦</param>
 	public virtual TrackEntry PlayAnimation(string motionName, bool loop = false, bool replay = true)
 	{
-		if (spineAnimationState == null) return null;
+		// 濡傛灉姝e湪鍒濆鍖栦腑锛屼繚瀛樺姩鐢诲弬鏁帮紝绛夊緟鍒濆鍖栧畬鎴愬悗鍐嶆挱鏀�
+		if (isInitializing)
+		{
+			pendingAnimationName = motionName;
+			pendingAnimationLoop = loop;
+			pendingAnimationReplay = replay;
+			return null;
+		}
+		
+		if (spineAnimationState == null) 
+		{
+			Debug.LogWarning("spineAnimationState is null, cannot play animation: " + motionName);
+			return null;
+		}
 
 		if (GetCurrentAnimationName() == motionName && !replay)
 			return null;
 
 		// 鐩存帴浣跨敤 ToString() 鑰屼笉鏄皟鐢� GetAnimationName
-		return spineAnimationState.SetAnimation(0, motionName.ToString(), loop);
+		try
+		{
+			return spineAnimationState.SetAnimation(0, motionName.ToString(), loop);
+		}
+		catch (System.Exception e)
+		{
+			Debug.LogError("鎾斁鍔ㄧ敾澶辫触: " + motionName + ", 閿欒: " + e.Message);
+			return null;
+		}
 	}
 
 	// 鎾斁绗竴涓姩鐢伙紙浣滀负榛樿鍔ㄧ敾锛�
 	string GetFistSpineAnim()
 	{
+		if (skeletonGraphic == null || skeletonGraphic.Skeleton == null)
+		{
+			Debug.LogWarning("skeletonGraphic or Skeleton is null, cannot get first animation");
+			return "idle"; // 杩斿洖榛樿鍔ㄧ敾鍚嶇О
+		}
+		
 		var skeletonData = skeletonGraphic.Skeleton.Data;
 		if (skeletonData.Animations.Count > 0)
 		{
@@ -344,7 +361,7 @@
 		{
 			Debug.LogError("Spine 鏁版嵁涓病鏈夋壘鍒颁换浣曞姩鐢伙紒姝﹀皢鐨偆锛�" + skinID);
 		}
-		return "";
+		return "idle"; // 杩斿洖榛樿鍔ㄧ敾鍚嶇О
 	}
 
 	/// <summary>
@@ -373,13 +390,33 @@
 	//瓒婂ぇ瓒婂揩
 	public void SetSpeed(float speed)
 	{
+		// 濡傛灉姝e湪鍒濆鍖栦腑锛屼繚瀛橀�熷害鍙傛暟锛岀瓑寰呭垵濮嬪寲瀹屾垚鍚庡啀璁剧疆
+		if (isInitializing)
+		{
+			pendingSpeed = speed;
+			return;
+		}
+		
+		if (spineAnimationState == null)
+		{
+			Debug.LogWarning("spineAnimationState is null, cannot set speed");
+			return;
+		}
 		spineAnimationState.TimeScale = speed;
 	}
 
 	public void SetEnabled(bool isEnable)
 	{
+		// 濡傛灉姝e湪鍒濆鍖栦腑锛屼繚瀛樺惎鐢ㄧ姸鎬侊紝绛夊緟鍒濆鍖栧畬鎴愬悗鍐嶈缃�
+		if (isInitializing)
+		{
+			pendingEnabled = isEnable;
+			return;
+		}
+		
 		if (skeletonGraphic == null)
 		{
+			Debug.LogWarning("skeletonGraphic is null, cannot set enabled state");
 			return;
 		}
 		skeletonGraphic.enabled = isEnable;
@@ -387,10 +424,259 @@
 
 	public void SetGray()
 	{
+		// 濡傛灉姝e湪鍒濆鍖栦腑锛屾爣璁伴渶瑕佽缃伆搴︼紝绛夊緟鍒濆鍖栧畬鎴愬悗鍐嶈缃�
+		if (isInitializing)
+		{
+			pendingGray = true;
+			return;
+		}
+		
+		if (skeletonGraphic == null)
+		{
+			Debug.LogWarning("skeletonGraphic is null, cannot set gray material");
+			return;
+		}
 		skeletonGraphic.material = MaterialUtility.GetDefaultSpriteGrayMaterial();
 	}
 	public void SetMaterialNone()
 	{
+		// 濡傛灉姝e湪鍒濆鍖栦腑锛屾爣璁伴渶瑕佽缃棤鏉愯川锛岀瓑寰呭垵濮嬪寲瀹屾垚鍚庡啀璁剧疆
+		if (isInitializing)
+		{
+			pendingGray = false;
+			return;
+		}
+		
+		if (skeletonGraphic == null)
+		{
+			Debug.LogWarning("skeletonGraphic is null, cannot set material to none");
+			return;
+		}
 		skeletonGraphic.material = null;
 	}
+
+	/// <summary>
+	/// 寤惰繜鍒濆鍖栵紝缁撳悎骞跺彂鎺у埗鍜屽垎甯у欢杩�
+	/// 1. 璧勬簮鍔犺浇浣跨敤鐪熸鐨勫紓姝ワ紙LoadAssetAsync锛�
+	/// 2. skeletonGraphic.Initialize() 鍓嶈繘琛屽垎甯у欢杩燂紝閬垮厤涓荤嚎绋嬪崱椤�
+	/// </summary>
+	private async UniTaskVoid DelayedInitializeAsync(HeroSkinConfig skinConfig, string motionName, bool isLh, System.Threading.CancellationToken cancellationToken)
+	{
+		isInitializing = true;
+
+		try
+		{
+			// 妫�鏌ユ槸鍚﹀凡琚彇娑�
+			cancellationToken.ThrowIfCancellationRequested();
+
+			// 鑾峰彇鍔犺浇淇″彿閲� - 闄愬埗骞跺彂鏁帮紝閬垮厤璧勬簮绔炰簤
+			await AcquireLoadSlotAsync(cancellationToken);
+
+			// 寮傛鍒涘缓instanceGO鍜屽姞杞借祫婧愶紙鐪熸鐨勫紓姝ワ紝涓嶉樆濉烇級
+			await CreateInstanceAndLoadAssetsAsync(skinConfig, isLh, cancellationToken);
+
+			// 鑾峰彇褰撳墠搴忓彿鐢ㄤ簬鍒嗗抚寤惰繜
+			int myOrder;
+			lock (loadLock)
+			{
+				myOrder = initializationOrder++;
+			}
+
+			// 鍐嶆妫�鏌ユ槸鍚﹀凡琚彇娑�
+			cancellationToken.ThrowIfCancellationRequested();
+
+			// 鍦� skeletonGraphic.Initialize() 鍓嶈繘琛屽垎甯у欢杩�
+			// 鏍规嵁 MAX_CONCURRENT_LOADS 璋冩暣寤惰繜锛岄伩鍏嶆墍鏈夊璞″悓鏃舵墽琛� Initialize
+			int delayFrames = (myOrder % MAX_CONCURRENT_LOADS);
+			if (delayFrames > 0)
+			{
+				for (int i = 0; i < delayFrames; i++)
+				{
+					cancellationToken.ThrowIfCancellationRequested();
+					await UniTask.NextFrame(cancellationToken);
+				}
+			}
+
+			// 鍐嶆妫�鏌ユ槸鍚﹀凡琚彇娑堬紙鍙兘鍦ㄥ欢杩熸湡闂磋鍙栨秷锛�
+			cancellationToken.ThrowIfCancellationRequested();
+
+			if (skeletonGraphic == null || skeletonGraphic.skeletonDataAsset == null)
+			{
+				Debug.LogError("璧勬簮鍔犺浇澶辫触锛屾棤娉曞垵濮嬪寲妯″瀷");
+				return;
+			}
+
+			skeletonGraphic.initialSkinName = skinConfig.InitialSkinName;
+			skeletonGraphic.Initialize(true);
+
+			// 鍒濆鍖栧畬鎴愬悗璁剧疆鐨偆
+			if (!string.IsNullOrEmpty(skinConfig.InitialSkinName))
+			{
+				var skeleton = skeletonGraphic.Skeleton;
+				skeleton.SetSkin(skinConfig.InitialSkinName);
+				skeleton.SetSlotsToSetupPose();
+				skeletonGraphic.Update(0);
+			}
+
+			spineAnimationState = skeletonGraphic.AnimationState;
+			spineAnimationState.Data.DefaultMix = 0f;
+
+			// 鍒濆鍖栧畬鎴愬悗鎵嶆樉绀烘ā鍨�
+			skeletonGraphic.enabled = pendingEnabled;
+
+			if (pendingGray)
+			{
+				skeletonGraphic.material = MaterialUtility.GetDefaultSpriteGrayMaterial();
+			}
+			else
+			{
+				skeletonGraphic.material = null;
+			}
+
+			// 妫�鏌ユ槸鍚︽湁寰呰缃殑閫熷害锛屽鏋滄湁鍒欒缃�
+			if (pendingSpeed.HasValue)
+			{
+				spineAnimationState.TimeScale = pendingSpeed.Value;
+				pendingSpeed = null;
+			}
+
+			// 妫�鏌ユ槸鍚︽湁寰呮挱鏀剧殑鍔ㄧ敾锛屽鏋滄湁鍒欎紭鍏堟挱鏀惧閮ㄨ皟鐢ㄧ殑鍔ㄧ敾
+			if (!string.IsNullOrEmpty(pendingAnimationName))
+			{
+				isInitializing = false;
+				PlayAnimation(pendingAnimationName, pendingAnimationLoop, pendingAnimationReplay);
+				// 娓呴櫎鎵�鏈夊緟鎾斁鍔ㄧ敾鍙傛暟
+				pendingAnimationName = null;
+				pendingAnimationLoop = false;
+				pendingAnimationReplay = true;
+			}
+			else
+			{
+				// 濡傛灉娌℃湁澶栭儴璋冪敤鐨勫姩鐢伙紝鎾斁榛樿鍔ㄧ敾
+				if (motionName == "")
+					motionName = GetFistSpineAnim();
+
+				isInitializing = false;
+				PlayAnimation(motionName, true);
+			}
+
+			spineAnimationState.Complete -= OnAnimationComplete;
+			spineAnimationState.Complete += OnAnimationComplete;
+
+			isInitialized = true;
+			isInitializing = false;
+		}
+		catch (System.OperationCanceledException)
+		{
+			// 浠诲姟琚彇娑堬紝姝e父杩斿洖
+			isInitializing = false;
+		}
+		catch (System.Exception e)
+		{
+			Debug.LogError($"鑻遍泟鍒濆鍖栧紓甯�: {e.Message}");
+			isInitializing = false;
+		}
+		finally
+		{
+			// 閲婃斁鍔犺浇妲戒綅
+			ReleaseLoadSlot();
+		}
+	}
+
+	/// <summary>
+	/// 鑾峰彇鍔犺浇妲戒綅锛堟敮鎸� WebGL 鐨勫苟鍙戞帶鍒讹級
+	/// </summary>
+	private async UniTask AcquireLoadSlotAsync(System.Threading.CancellationToken cancellationToken)
+	{
+		while (true)
+		{
+			// 妫�鏌ユ槸鍚﹀凡琚彇娑�
+			cancellationToken.ThrowIfCancellationRequested();
+
+			lock (loadLock)
+			{
+				if (currentLoadingCount < MAX_CONCURRENT_LOADS)
+				{
+					currentLoadingCount++;
+					return;
+				}
+			}
+			// 濡傛灉宸茶揪鍒版渶澶у苟鍙戞暟锛岀瓑寰呬笅涓�甯у啀璇�
+			await UniTask.NextFrame(cancellationToken);
+		}
+	}
+
+	/// <summary>
+	/// 閲婃斁鍔犺浇妲戒綅
+	/// </summary>
+	private void ReleaseLoadSlot()
+	{
+		lock (loadLock)
+		{
+			currentLoadingCount--;
+		}
+	}
+
+
+	/// <summary>
+	/// 寮傛鍒涘缓instanceGO鍜屽姞杞借祫婧愶紙鐢ㄤ簬闈炵珛缁橈級
+	/// 浣跨敤鐪熸鐨勫紓姝ュ姞杞斤紝涓嶉樆濉炰富绾跨▼
+	/// </summary>
+	private async UniTask CreateInstanceAndLoadAssetsAsync(HeroSkinConfig skinConfig, bool isLh, System.Threading.CancellationToken cancellationToken)
+	{
+		// 纭繚transform澶勪簬婵�娲荤姸鎬�
+		if (!transform.gameObject.activeSelf)
+		{
+			transform.SetActive(true);
+		}
+
+		// 妫�鏌ユ槸鍚﹀凡琚彇娑�
+		cancellationToken.ThrowIfCancellationRequested();
+
+		// 鍒涘缓pool鍜宨nstanceGO
+		pool = GameObjectPoolManager.Instance.GetPool(UILoader.LoadPrefab("UIHero"));
+
+		if (instanceGO == null)
+		{
+			instanceGO = pool.Request();
+			instanceGO.transform.SetParent(transform);
+			//transform 鐨凱ivot Y鏄�0锛岃instanceGO 灞呬腑
+			instanceGO.transform.localPosition = new Vector3(0, instanceGO.GetComponent<RectTransform>().sizeDelta.y * 0.5f);
+			instanceGO.transform.localScale = Vector3.one;
+			instanceGO.transform.localRotation = Quaternion.identity;
+		}
+
+		skeletonGraphic = instanceGO.GetComponentInChildren<SkeletonGraphic>(true);
+
+		// 鐪熸鐨勫紓姝ュ姞杞借祫婧� - 涓嶉樆濉炰富绾跨▼
+		string assetName = isLh ? skinConfig.Tachie : skinConfig.SpineRes;
+		SkeletonDataAsset loadedAsset = await ResManager.Instance.LoadAssetAsync<SkeletonDataAsset>("Hero/SpineRes/", assetName);
+
+		// 鍐嶆妫�鏌ユ槸鍚﹀凡琚彇娑�
+		cancellationToken.ThrowIfCancellationRequested();
+
+		if (loadedAsset != null)
+		{
+			skeletonGraphic.skeletonDataAsset = loadedAsset;
+		}
+		else
+		{
+			transform.SetActive(false);
+			if (pool != null)
+				pool.Release(instanceGO);
+			skeletonGraphic = null;
+			Destroy(instanceGO);
+			Debug.LogError("鏈厤缃畇pine");
+		}
+	}
+
+
+
+	/// <summary>
+	/// 妫�鏌ユ槸鍚﹀凡瀹屾垚鍒濆鍖�
+	/// </summary>
+	public bool IsInitialized()
+	{
+		return isInitialized && !isInitializing;
+	}
 }
\ No newline at end of file
diff --git a/Main/System/HeroDebut.meta b/Main/System/HeroDebut.meta
new file mode 100644
index 0000000..298b598
--- /dev/null
+++ b/Main/System/HeroDebut.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 03399e82bce6baf41b535b50baffa026
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/BubbleFloat.cs b/Main/System/HeroDebut/BubbleFloat.cs
new file mode 100644
index 0000000..985a267
--- /dev/null
+++ b/Main/System/HeroDebut/BubbleFloat.cs
@@ -0,0 +1,76 @@
+using UnityEngine;
+using DG.Tweening;
+
+public class BubbleFloat : MonoBehaviour
+{
+    [Header("娴姩鑼冨洿璁剧疆")]
+    [SerializeField] private float minY = -20f; // 鐩稿浜庡垵濮嬩綅缃殑鏈�浣庡亸绉�
+    [SerializeField] private float maxY = 20f;  // 鐩稿浜庡垵濮嬩綅缃殑鏈�楂樺亸绉�
+
+    [Header("鍔ㄧ敾璁剧疆")]
+    [SerializeField] private float duration = 2f;    // 鍗曠▼鏃堕棿
+    [SerializeField] private Ease easeType = Ease.InOutSine;
+    [SerializeField] private bool useRandomDelay = true; // 鏄惁寮�鍚殢鏈哄欢杩�
+
+    private Vector3 initialPosition;
+    private Tween floatTween;
+
+    private void Awake()
+    {
+        // 璁板綍 UI 鎸傝浇鏃剁殑鍘熷鏈湴鍧愭爣
+        initialPosition = transform.localPosition;
+    }
+
+    private void OnEnable()
+    {
+        RestartAnimation();
+    }
+
+    private void RestartAnimation()
+    {
+        KillTween();
+
+        // 1. 纭繚鍥炲埌鍒濆鍙傝�冪偣
+        transform.localPosition = initialPosition;
+
+        float startY = initialPosition.y + minY;
+        float endY = initialPosition.y + maxY;
+
+        // 2. 鍏堣缃垵濮嬩綅缃紙璧峰鐐癸級
+        transform.localPosition = new Vector3(initialPosition.x, startY, initialPosition.z);
+
+        // 3. 鍒涘缓鍔ㄧ敾骞惰褰�
+        // 娉ㄦ剰锛氭垜浠皢鍔ㄧ敾璧嬪�肩粰鍙橀噺锛屽苟寮哄埗绔嬪嵆鎵ц
+        floatTween = transform.DOLocalMoveY(endY, duration)
+            .SetEase(easeType)
+            .SetLoops(-1, LoopType.Yoyo)
+            .SetUpdate(true);
+
+        if (useRandomDelay)
+        {
+            // 鍏抽敭淇锛氬厛璁╁姩鐢昏绠楀嚭鍒濆鐘舵�侊紝鍐嶈烦杞繘搴�
+            // 鍚﹀垯鍦ㄥ垱寤虹殑绗竴甯э紝鍔ㄧ敾绯荤粺鍙兘杩樻病鎰忚瘑鍒板畠闇�瑕佺Щ鍔�
+            float randomTime = Random.Range(0f, duration * 2f);
+            floatTween.Goto(randomTime, true); // true 琛ㄧず绔嬪嵆鎵ц鍥炶皟鍜屼綅绉�
+        }
+    }
+
+    private void OnDisable()
+    {
+        KillTween();
+    }
+
+    private void OnDestroy()
+    {
+        KillTween();
+    }
+
+    private void KillTween()
+    {
+        if (floatTween != null)
+        {
+            floatTween.Kill();
+            floatTween = null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/System/HeroDebut/BubbleFloat.cs.meta b/Main/System/HeroDebut/BubbleFloat.cs.meta
new file mode 100644
index 0000000..667f11b
--- /dev/null
+++ b/Main/System/HeroDebut/BubbleFloat.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 92816cc4164e9414583e6b905e94a15e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/GeneralActInfoManager.cs b/Main/System/HeroDebut/GeneralActInfoManager.cs
new file mode 100644
index 0000000..321a0fb
--- /dev/null
+++ b/Main/System/HeroDebut/GeneralActInfoManager.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+
+//娲诲姩閫氱敤淇℃伅
+public class GeneralActInfoManager : GameSystemManager<GeneralActInfoManager>
+{
+    public override void Init()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
+
+    }
+
+    public override void Release()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin;
+
+    }
+
+    private void OnBeforePlayerDataInitializeEventOnRelogin()
+    {
+        actSignInfos.Clear();
+    }
+    
+    #region 娲诲姩閫氱敤妯$増 娲诲姩绛惧埌濂栧姳
+    public Dictionary<int, Dictionary<int, uint>> actSignInfos = new();
+    public event Action<int, int> OnUpdateActSignInfosEvent;
+
+    public void UpdateActSignPlayerInfo(HAA20_tagSCActSignPlayerInfo vNetData)
+    {
+        if (vNetData == null) return;
+        if (!actSignInfos.TryGetValue(vNetData.ActType, out var actNumDict))
+        {
+            actNumDict = new Dictionary<int, uint>();
+            actSignInfos[vNetData.ActType] = actNumDict;
+        }
+        actNumDict[vNetData.ActNum] = vNetData.SignAward;
+        OnUpdateActSignInfosEvent?.Invoke(vNetData.ActType, vNetData.ActNum);
+    }
+
+    public bool TryGetSignAward(int actType, int actNum, out uint reward)
+    {
+        reward = 0;
+        if (!actSignInfos.TryGetValue(actType, out var actNumDict)) return false;
+        if (!actNumDict.TryGetValue(actNum, out reward)) return false;
+        return true;
+    }
+
+    public bool IsDaySigned(int actType, int actNum, int dayNum)
+    {
+        if (dayNum < 1 || dayNum > 32) return false;
+        if (!TryGetSignAward(actType, actNum, out uint signAward)) return false;
+        return ((signAward >> dayNum) & 1u) == 1u;
+    }
+
+    // 娲诲姩濡傛灉鏈夋惌閰嶇鍒帮紝涓�鑸湪娲诲姩鍖呬腑浼氭湁ActType淇℃伅锛屽AA21灏佸寘涓殑ActType
+    public void SendGetSignReward(int actType, int actNum)
+    {
+        string actTypeStr = actType.ToString();
+        var pack = new CA504_tagCMPlayerGetReward
+        {
+            RewardType = 70,
+            DataEx = (uint)actNum,
+            DataExStr = actTypeStr,
+            DataExStrLen = (byte)actTypeStr.Length
+        };
+        GameNetSystem.Instance.SendInfo(pack);
+    }
+    #endregion
+}
\ No newline at end of file
diff --git a/Main/System/HeroDebut/GeneralActInfoManager.cs.meta b/Main/System/HeroDebut/GeneralActInfoManager.cs.meta
new file mode 100644
index 0000000..09bcf53
--- /dev/null
+++ b/Main/System/HeroDebut/GeneralActInfoManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0f04cdfa27c19304fa145ce589958767
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallBubbleCell.cs b/Main/System/HeroDebut/HeroDebutCallBubbleCell.cs
new file mode 100644
index 0000000..77d18ea
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallBubbleCell.cs
@@ -0,0 +1,23 @@
+using UnityEngine;
+
+public class HeroDebutCallBubbleCell : MonoBehaviour
+{
+    [SerializeField] ButtonEx clickButton;
+    [SerializeField] ImageEx bgImage;
+    [SerializeField] ImageEx iconImage;
+    [SerializeField] TextEx countText;
+    public void Display(int itemID, int count)
+    {
+        var config = ItemConfig.Get(itemID);
+        if (config == null) return;
+
+        bgImage.SetSprite($"HeroDebutCallBubbleBG{config.ItemColor}");
+        iconImage.SetItemSprite(itemID);
+        iconImage.SetNativeSize();
+        countText.text = count.ToString();
+
+        clickButton.SetListener(() => ItemTipUtility.Show(itemID));
+    }
+
+
+}
diff --git a/Main/System/HeroDebut/HeroDebutCallBubbleCell.cs.meta b/Main/System/HeroDebut/HeroDebutCallBubbleCell.cs.meta
new file mode 100644
index 0000000..603360d
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallBubbleCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c470779b736bf5144ab6d68c3989aac3
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallButton.cs b/Main/System/HeroDebut/HeroDebutCallButton.cs
new file mode 100644
index 0000000..36c203b
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallButton.cs
@@ -0,0 +1,95 @@
+using UnityEngine;
+
+public class HeroDebutCallButton : MonoBehaviour
+{
+    [SerializeField] ButtonEx clickButton;
+    [SerializeField] TextEx callText;
+    [SerializeField] TextEx needText;
+    [SerializeField] ImageEx needImage;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    HappyXBModel xbManager => HappyXBModel.Instance;
+    int index;
+    int type;
+    int needCostItemCnt;
+    long hasItemCnt;
+    int needCostMoneyCnt;
+    long moneyCount;
+    public void Display(int treasureType, int index)
+    {
+        this.index = index;
+        type = treasureType;
+        var treasureSetConfig = TreasureSetConfig.Get(treasureType);
+        if (treasureSetConfig == null) return;
+        if (treasureSetConfig.TreasureCountList == null || treasureSetConfig.TreasureCountList.Length <= index) return;
+        if (treasureSetConfig.CostItemCountList == null || treasureSetConfig.CostItemCountList.Length <= index) return;
+        if (treasureSetConfig.CostMoneyList == null || treasureSetConfig.CostMoneyList.Length <= index) return;
+
+        XBTypeInfo info = xbManager.GetXBInfoByType(treasureType);
+        if (info == null) return;
+
+        int treasureCnt = treasureSetConfig.TreasureCountList[index];
+
+        callText.text = Language.Get("HeroDebut23", treasureCnt);
+
+        int dailyMaxCountMoney = treasureSetConfig.DailyMaxCountMoney;
+        int nowMoneyCnt = info.treasureCountTodayGold;
+
+        needCostMoneyCnt = treasureSetConfig.CostMoneyList[index];
+        moneyCount = UIHelper.GetMoneyCnt(treasureSetConfig.CostMoneyType);
+
+        needCostItemCnt = treasureSetConfig.CostItemCountList[index];
+        hasItemCnt = PackManager.Instance.GetItemCountByID(PackType.Item, treasureSetConfig.CostItemID);
+
+        // 鐗╁搧涓嶈冻 && 娌¤秴璐у竵鎷涘嫙娆℃暟涓婇檺 
+        if (hasItemCnt < needCostItemCnt &&
+            nowMoneyCnt + treasureCnt <= dailyMaxCountMoney)
+        {
+            DisplayByMoney(treasureSetConfig.CostMoneyType, needCostMoneyCnt, moneyCount);
+            return;
+        }
+        DisplayByItem(treasureSetConfig.CostItemID, treasureCnt);
+    }
+
+    void DisplayByMoney(int moneyType, long needCostMoneyCnt, long moneyCount)
+    {
+
+        bool isEnough = moneyCount >= needCostMoneyCnt;
+        needText.text = Language.Get("L1100", RichTextMsgReplaceConfig.GetRichReplace("MONEY", moneyType), UIHelper.AppendColor(!isEnough ? TextColType.Red : TextColType.LightGreen, needCostMoneyCnt.ToString()));
+        needImage.SetIconWithMoneyType(moneyType);
+
+        clickButton.SetListener(() =>
+        {
+            if (!isEnough)
+            {
+                ItemTipUtility.ShowMoneyTip(moneyType, true);
+                return;
+            }
+            HeroUIManager.Instance.selectCallType = (HappXBTitle)type;
+            HeroUIManager.Instance.selectCallIndex = index;
+            HappyXBModel.Instance.SendXBQuest(type, index, 0);
+        });
+    }
+
+    void DisplayByItem(int itemID, int count)
+    {
+        ItemConfig itemConfig = ItemConfig.Get(itemID);
+        if (itemConfig == null) return;
+        bool isEnough = hasItemCnt >= needCostItemCnt;
+        needText.text = Language.Get("L1100", itemConfig.ItemName, UIHelper.AppendColor(!isEnough ? TextColType.Red : TextColType.LightGreen, count.ToString()));
+        needImage.SetItemSprite(itemID);
+
+        clickButton.SetListener(() =>
+        {
+            if (!isEnough)
+            {
+                ItemTipUtility.Show(itemID, true);
+                return;
+            }
+            HeroUIManager.Instance.selectCallType = (HappXBTitle)type;
+            HeroUIManager.Instance.selectCallIndex = index;
+            HappyXBModel.Instance.SendXBQuest(type, index, 2);
+        });
+
+    }
+
+}
diff --git a/Main/System/HeroDebut/HeroDebutCallButton.cs.meta b/Main/System/HeroDebut/HeroDebutCallButton.cs.meta
new file mode 100644
index 0000000..3ad0331
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallButton.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ddb737f7cca716044ac755290a7029fe
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallChangeCell.cs b/Main/System/HeroDebut/HeroDebutCallChangeCell.cs
new file mode 100644
index 0000000..18f0f2b
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallChangeCell.cs
@@ -0,0 +1,33 @@
+using UnityEngine;
+
+public class HeroDebutCallChangeCell : CellView
+{
+    [SerializeField] HeroDebutCallChangeItem[] items;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    public void Display(int rowIndex)
+    {
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        var heroArr = config.ActHeroIDList;
+        if (heroArr.IsNullOrEmpty()) return;
+
+        for (int i = 0; i < items.Length; i++)
+        {
+            int index = rowIndex * HeroDebutCallChangeWin.rowCountMax + i;
+            if (index < heroArr.Length)
+            {
+                items[i].SetActive(true);
+                items[i].Display(index, heroArr, act.CfgID);
+            }
+            else
+            {
+                items[i].SetActive(false);
+            }
+        }
+    }
+
+}
diff --git a/Main/System/HeroDebut/HeroDebutCallChangeCell.cs.meta b/Main/System/HeroDebut/HeroDebutCallChangeCell.cs.meta
new file mode 100644
index 0000000..1611dac
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallChangeCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ece47d072ae8d0e4a8912feed21f3e59
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallChangeItem.cs b/Main/System/HeroDebut/HeroDebutCallChangeItem.cs
new file mode 100644
index 0000000..476c3a9
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallChangeItem.cs
@@ -0,0 +1,41 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+public class HeroDebutCallChangeItem : MonoBehaviour
+{
+
+    [SerializeField] HeroHeadBaseCell heroHeadBaseCell;
+    [SerializeField] Image jobImg;
+    [SerializeField] Text nameText;
+    [SerializeField] Transform select;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    HeroConfig heroConfig;
+    int index;
+    public void Display(int index, int[] heroIds, int cfgId)
+    {
+        this.index = index;
+        if (heroIds?.Length <= index) return;
+
+        int heroId = heroIds[index];
+        heroConfig = HeroConfig.Get(heroId);
+        if (heroConfig == null) return;
+        
+        int skinID = manager.GetDefaultSkinID(heroId);
+        var heroSkinConfig = HeroSkinConfig.Get(skinID);
+        if (heroSkinConfig == null) return;
+
+        heroHeadBaseCell.Init(heroConfig.HeroID, skinID, 0, 0, 0, OnClick);
+        nameText.text = heroConfig.Name;
+        jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class));
+        bool isChoose = manager.nowCallChooseHeroID == heroId;
+        select?.SetActive(isChoose);
+    }
+
+    public void OnClick()
+    {
+        if (heroConfig == null) return;
+
+        manager.nowCallChooseHeroID = heroConfig.HeroID;
+
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutCallChangeItem.cs.meta b/Main/System/HeroDebut/HeroDebutCallChangeItem.cs.meta
new file mode 100644
index 0000000..79c2e14
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallChangeItem.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f6ce4f60b45922447b708afaa5d49213
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallChangeWin.cs b/Main/System/HeroDebut/HeroDebutCallChangeWin.cs
new file mode 100644
index 0000000..23a91f1
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallChangeWin.cs
@@ -0,0 +1,100 @@
+using UnityEngine;
+
+public class HeroDebutCallChangeWin : UIBase
+{
+    [SerializeField] ScrollerController scroller;
+    [SerializeField] ButtonEx closeButton;
+    [SerializeField] ButtonEx okButton;
+    [SerializeField] ButtonEx previewButton;
+    [SerializeField] UIHeroController uiHeroController;
+    public const int rowCountMax = 4;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+
+    protected override void InitComponent()
+    {
+        closeButton.SetListener(CloseWindow);
+        okButton.SetListener(() =>
+        {
+            var act = manager.GetOperationHeroAppearInfo();
+            if (act == null) return;
+
+            int index = manager.GetHeroIdIndex(act.CfgID, manager.nowCallChooseHeroID);
+            if (index < 0) return;
+
+            if (manager.GetCurrentDisplayCallHeroId() == manager.nowCallChooseHeroID)
+            {
+                SysNotifyMgr.Instance.ShowTip("HeroDebut01");
+                return;
+            }
+
+            manager.SnedHeroAppearCallHeroSelect(manager.actNum, index);
+            CloseWindow();
+        });
+        previewButton.SetListener(() =>
+        {
+            HeroUIManager.Instance.selectForPreviewHeroID = manager.nowCallChooseHeroID;
+            UIManager.Instance.OpenWindow<HeroBestBaseWin>();
+        });
+    }
+
+    protected override void OnPreOpen()
+    {
+        scroller.OnRefreshCell += OnRefreshCell;
+        manager.OnNowCallChooseHeroIDChangeEvent += OnNowCallChooseHeroIDChangeEvent;
+        manager.nowCallChooseHeroID = manager.GetCurrentDisplayCallHeroId();
+        Display();
+        CreateScroller();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        manager.OnNowCallChooseHeroIDChangeEvent -= OnNowCallChooseHeroIDChangeEvent;
+    }
+
+    private void OnNowCallChooseHeroIDChangeEvent()
+    {
+        Display();
+        scroller.m_Scorller.RefreshActiveCellViews();
+    }
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as HeroDebutCallChangeCell;
+        _cell.Display(cell.index);
+    }
+
+    void CreateScroller()
+    {
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        var arr = config.ActHeroIDList;
+        if (arr.IsNullOrEmpty()) return;
+
+
+        scroller.Refresh();
+        int rowCount = (int)Mathf.Ceil((float)arr.Length / rowCountMax);
+        for (int i = 0; i < rowCount; i++)
+        {
+            scroller.AddCell(ScrollerDataType.Header, i);
+        }
+        scroller.Restart();
+    }
+
+    void Display()
+    {
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+
+        int skinID = manager.GetDefaultSkinID(manager.nowCallChooseHeroID);
+        var skinConfig = HeroSkinConfig.Get(skinID);
+        if (skinConfig == null) return;
+
+        uiHeroController.Create(skinID, 1);
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutCallChangeWin.cs.meta b/Main/System/HeroDebut/HeroDebutCallChangeWin.cs.meta
new file mode 100644
index 0000000..5cedf14
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallChangeWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a286c50b901fce241bb3783575297797
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallHistoryCell.cs b/Main/System/HeroDebut/HeroDebutCallHistoryCell.cs
new file mode 100644
index 0000000..6c6e204
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallHistoryCell.cs
@@ -0,0 +1,42 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class HeroDebutCallHistoryCell : CellView
+{
+    [SerializeField] Color nameColor;
+    [SerializeField] TextEx infoText;
+    public virtual void Display(int index, List<HeroDebutGameRec> list)
+    {
+        if (list?.Count <= index) return;
+        var rec = list[index];
+
+        var itemconfig = ItemConfig.Get(rec.ItemID);
+        if (itemconfig == null) return;
+
+        //150 鏁翠釜姝﹀皢
+        if (itemconfig.Type == 150)
+        {
+            HeroConfig heroConfig = HeroConfig.Get(rec.ItemID);
+            if (heroConfig == null) return;
+            int quality = heroConfig.Quality;
+
+            infoText.text = Language.Get("HeroDebut29",
+                UIHelper.AppendColor(nameColor, rec.PlayerName),
+                UIHelper.AppendColor(UIHelper.GetUIColorByFunc(quality), Language.Get(StringUtility.Concat("CommonQuality", quality.ToString()))),
+                UIHelper.AppendColor(UIHelper.GetUIColorByFunc(quality), heroConfig.Name.ToString())
+            );
+        }
+        else
+        {
+            int quality = itemconfig.ItemColor;
+
+            infoText.text = Language.Get("HeroDebut30",
+                UIHelper.AppendColor(nameColor, rec.PlayerName),
+                UIHelper.AppendColor(UIHelper.GetUIColorByFunc(quality), itemconfig.ItemName.ToString()),
+                rec.ItemCount.ToString()
+            );
+        }
+
+    }
+
+}
diff --git a/Main/System/HeroDebut/HeroDebutCallHistoryCell.cs.meta b/Main/System/HeroDebut/HeroDebutCallHistoryCell.cs.meta
new file mode 100644
index 0000000..df02d2a
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallHistoryCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f47885b4668b2db4d8ff505bb9b07800
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallHistoryOutCell.cs b/Main/System/HeroDebut/HeroDebutCallHistoryOutCell.cs
new file mode 100644
index 0000000..1fad1cb
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallHistoryOutCell.cs
@@ -0,0 +1,21 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class HeroDebutCallHistoryOutCell : HeroDebutCallHistoryCell
+{
+    [SerializeField] CanvasGroup canvasGroup;
+  
+    public override void Display(int index, List<HeroDebutGameRec> list)
+    {
+        base.Display(index, list);
+    }
+
+    // 鎻愪緵缁欏閮ㄨ缃�忔槑搴︾殑鏂规硶
+    public void SetAlpha(float alpha)
+    {
+        if (canvasGroup != null)
+        {
+            canvasGroup.alpha = alpha;
+        }
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutCallHistoryOutCell.cs.meta b/Main/System/HeroDebut/HeroDebutCallHistoryOutCell.cs.meta
new file mode 100644
index 0000000..1f11086
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallHistoryOutCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 56e7d3092a51a944e9a737346fb5e09c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallHistoryWin.cs b/Main/System/HeroDebut/HeroDebutCallHistoryWin.cs
new file mode 100644
index 0000000..399a4e9
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallHistoryWin.cs
@@ -0,0 +1,57 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class HeroDebutCallHistoryWin : UIBase
+{
+    [SerializeField] ScrollerController scroller;
+    [SerializeField] RectTransform noRect;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+
+    protected override void OnPreOpen()
+    {
+        scroller.lockType = EnhanceLockType.LockVerticalBottom;
+
+        scroller.OnRefreshCell += OnRefreshCell;
+        manager.OnUpdateGameRecInfo += OnUpdateGameRecInfo;
+
+        CreateScroller();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        manager.OnUpdateGameRecInfo -= OnUpdateGameRecInfo;
+    }
+
+    private void OnUpdateGameRecInfo()
+    {
+        scroller.m_Scorller.RefreshActiveCellViews();
+    }
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as HeroDebutCallHistoryCell;
+        _cell.Display(cell.index, list);
+    }
+    public List<HeroDebutGameRec> list;
+
+    void CreateScroller()
+    {
+        list = manager.GetGameRecList();
+        if (list == null)
+        {
+            noRect.SetActive(true);
+            scroller.SetActive(false);
+            return;
+        }
+        noRect.SetActive(false);
+        scroller.SetActive(true);
+
+        scroller.Refresh();
+        for (int i = 0; i < list.Count; i++)
+        {
+            scroller.AddCell(ScrollerDataType.Header, i);
+        }
+        scroller.Restart();
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutCallHistoryWin.cs.meta b/Main/System/HeroDebut/HeroDebutCallHistoryWin.cs.meta
new file mode 100644
index 0000000..b9c0479
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallHistoryWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 72b89a64567af334e93d6d6e601aa62c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallRateCell.cs b/Main/System/HeroDebut/HeroDebutCallRateCell.cs
new file mode 100644
index 0000000..980d68f
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallRateCell.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class HeroDebutCallRateCell : CellView
+{
+    [SerializeField] HeroDebutCallRateItem[] items;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+
+    public void Display(int rowIndex, Dictionary<int, int> gridRateDict, List<int> gridList, XBGetItemConfig xbConfig)
+    {
+        if (gridList == null) return;
+
+        for (int i = 0; i < items.Length; i++)
+        {
+            int index = rowIndex * HeroDebutCallChangeWin.rowCountMax + i;
+            if (index < gridList.Count)
+            {
+                items[i].SetActive(true);
+                items[i].Display(index, gridRateDict, gridList, xbConfig);
+            }
+            else
+            {
+                items[i].SetActive(false);
+            }
+        }
+    }
+
+}
diff --git a/Main/System/HeroDebut/HeroDebutCallRateCell.cs.meta b/Main/System/HeroDebut/HeroDebutCallRateCell.cs.meta
new file mode 100644
index 0000000..3c5edea
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallRateCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a80d3abc6fbb27e42b345110ed2ebe66
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallRateHeroCell.cs b/Main/System/HeroDebut/HeroDebutCallRateHeroCell.cs
new file mode 100644
index 0000000..4eed23d
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallRateHeroCell.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class HeroDebutCallRateHeroCell : CellView
+{
+
+    [SerializeField] ItemCell[] itemCells;
+    public void Display(int rowIndex, List<Item> dataList)
+    {
+        if (dataList == null) return;
+
+        for (int i = 0; i < itemCells.Length; i++)
+        {
+            int dataIndex = rowIndex * HeroDebutCallRateHeroWin.rowCountMax + i;
+
+            if (dataIndex < dataList.Count)
+            {
+                itemCells[i].SetActive(true);
+                itemCells[i].Init(new ItemCellModel(dataList[dataIndex].id, true, dataList[dataIndex].countEx));
+                itemCells[i].button.SetListener(() => ItemTipUtility.Show(dataList[dataIndex].id));
+            }
+            else
+            {
+                itemCells[i].SetActive(false);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/System/HeroDebut/HeroDebutCallRateHeroCell.cs.meta b/Main/System/HeroDebut/HeroDebutCallRateHeroCell.cs.meta
new file mode 100644
index 0000000..40d779d
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallRateHeroCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: aa92522c2542a584586c1992c24395f3
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallRateHeroWin.cs b/Main/System/HeroDebut/HeroDebutCallRateHeroWin.cs
new file mode 100644
index 0000000..1d51419
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallRateHeroWin.cs
@@ -0,0 +1,119 @@
+using System.Collections.Generic;
+using Cysharp.Threading.Tasks;
+using UnityEngine;
+
+public class HeroDebutCallRateHeroWin : UIBase
+{
+
+    [SerializeField] RectTransform rectTransform;
+    [SerializeField] RectTransform arrowImage;
+    [SerializeField] RectTransform arrowUpImage;
+    [SerializeField] ScrollerController scroller;
+
+    public static Vector3 worldPos; //涓栫晫鍧愭爣绯讳綅缃�
+    public static bool isDownShow = false;  // 鏄惁鍚戜笅鏄剧ず
+    public static List<Item> dataList;
+    public const int rowCountMax = 4;
+    protected override void OnPreOpen()
+    {
+        scroller.OnRefreshCell += OnRefreshCell;
+
+        rectTransform.position = new Vector3(100, 100, 100);   //鍒濆鍖栨椂锛屽睆骞曡寖鍥村
+        arrowImage.SetActive(!isDownShow);
+        arrowUpImage.SetActive(isDownShow);
+        CreateScroller();
+    }
+
+    protected override void OnPreClose()
+    {
+        isDownShow = false;
+        scroller.OnRefreshCell -= OnRefreshCell;
+    }
+    
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as HeroDebutCallRateHeroCell;
+        _cell.Display(cell.index, dataList);
+    }
+
+    void CreateScroller()
+    {
+        if (dataList == null || dataList.Count == 0) return;
+
+        scroller.Refresh();
+        int rowCount = Mathf.CeilToInt((float)dataList.Count / rowCountMax);
+        for (int i = 0; i < rowCount; i++)
+        {
+            scroller.AddCell(ScrollerDataType.Header, i);
+        }
+        scroller.Restart();
+    }
+
+    protected override void OnOpen()
+    {
+        UpdatePos().Forget();
+    }
+
+    async UniTask UpdatePos()
+    {
+        await UniTask.DelayFrame(3);
+        // 闄愬埗鍦ㄥ睆骞曡寖鍥村唴
+        Vector3[] corners = new Vector3[4];
+        rectTransform.GetWorldCorners(corners);
+
+        float minY = corners[0].y;
+        float maxY = corners[0].y;
+
+        for (int i = 1; i < corners.Length; i++)
+        {
+            if (corners[i].y < minY) minY = corners[i].y;
+            if (corners[i].y > maxY) maxY = corners[i].y;
+        }
+
+
+        float screenHeight = maxY - minY;
+        Vector2 adjustedPos = new Vector2(worldPos.x, worldPos.y + (!isDownShow ? screenHeight * 0.5f : -screenHeight * 0.5f));
+
+        Vector2 screenAdjustedPos = CameraManager.uiCamera.WorldToScreenPoint(adjustedPos);
+        var rectWidth = rectTransform.rect.width * Screen.width / canvasScaler.referenceResolution.x;
+        screenAdjustedPos.x = Mathf.Clamp(screenAdjustedPos.x, rectWidth * 0.5f, Screen.width - rectWidth * 0.5f);
+        screenAdjustedPos.y = Mathf.Clamp(screenAdjustedPos.y, rectTransform.rect.height * 0.5f, Screen.height - rectTransform.rect.height * 0.5f - 15);
+
+        adjustedPos = CameraManager.uiCamera.ScreenToWorldPoint(screenAdjustedPos);
+        rectTransform.position = adjustedPos;
+
+        if (!isDownShow)
+        {
+            rectTransform.localPosition = new Vector3(rectTransform.localPosition.x, rectTransform.localPosition.y + 15, rectTransform.localPosition.z);
+        }
+        else
+        {
+            rectTransform.localPosition = new Vector3(rectTransform.localPosition.x, rectTransform.localPosition.y - 15, rectTransform.localPosition.z);
+        }
+
+        rectTransform.GetWorldCorners(corners);
+        float minX = corners[0].x;
+        float maxX = corners[0].x;
+
+        for (int i = 1; i < corners.Length; i++)
+        {
+            if (corners[i].x < minX) minX = corners[i].x;
+            if (corners[i].x > maxX) maxX = corners[i].x;
+        }
+
+        //鏄剧ずarrowImage 鐨剎杞翠笂鐨勪綅缃紝鍜寃orldPos鍚屾锛屼絾涓嶈秴杩噈inX 鍜� maxX鑼冨洿
+        if (!isDownShow)
+        {
+            Vector3 arrowImagePosition = arrowImage.position;
+            arrowImagePosition.x = Mathf.Clamp(worldPos.x, minX, maxX);
+            arrowImage.position = arrowImagePosition;
+        }
+        else
+        {
+            Vector3 arrowUpImagePosition = arrowUpImage.position;
+            arrowUpImagePosition.x = Mathf.Clamp(worldPos.x, minX, maxX);
+            arrowUpImage.position = arrowUpImagePosition;
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/Main/System/HeroDebut/HeroDebutCallRateHeroWin.cs.meta b/Main/System/HeroDebut/HeroDebutCallRateHeroWin.cs.meta
new file mode 100644
index 0000000..0b1d215
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallRateHeroWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8f25ce44e5dc223458403a88dfba4c42
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallRateItem.cs b/Main/System/HeroDebut/HeroDebutCallRateItem.cs
new file mode 100644
index 0000000..a1017b8
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallRateItem.cs
@@ -0,0 +1,123 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class HeroDebutCallRateItem : MonoBehaviour
+{
+    [SerializeField] ButtonEx libButton;
+    [SerializeField] ItemCell itemCell;
+    [SerializeField] Text rateText;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    public void Display(int index, Dictionary<int, int> gridRateDict, List<int> gridList, XBGetItemConfig xbConfig)
+    {
+        if (gridList?.Count <= index || gridRateDict?.Count != gridList?.Count || xbConfig == null) return;
+        if (xbConfig?.GridItemInfo == null || xbConfig?.GridLibInfo == null) return;
+        if (manager.xbGridArr == null) return;
+
+        int grid = gridList[index];
+        int rate = gridRateDict[grid];
+        rateText.text = Language.Get("TimingGift02", (double)rate / (double)100.0);
+        SetItemCell(grid, xbConfig.GridItemInfo, xbConfig.GridLibInfo, manager.xbGridArr);
+    }
+
+    public void SetCountActive(ItemCell itemCell, long count)
+    {
+        itemCell.countText.SetActive(count > 1);
+    }
+
+
+    private void SetItemCell(int grid, Dictionary<int, int[]> gridItemInfo, Dictionary<int, int> gridLibInfo, int[] xbGridArr)
+    {
+        libButton.SetActive(false);
+        itemCell.SetActive(false);
+        if (gridItemInfo.TryGetValue(grid, out var itemInfo))
+        {
+            itemCell.SetActive(true);
+            itemCell.Init(new ItemCellModel(itemInfo[0], true, itemInfo[1]));
+            SetCountActive(itemCell, itemInfo[1]);
+            itemCell.button.SetListener(() => ItemTipUtility.Show(itemInfo[0]));
+            return;
+        }
+
+        if (!gridLibInfo.TryGetValue(grid, out var libID)) return;
+
+        var list = TreasureItemLibConfig.GetItemIDList(libID);
+        if (list == null) return;
+        if (xbGridArr == null) return;
+
+        if (xbGridArr.Contains(grid))
+        {
+            int heroID = manager.GetCurrentDisplayCallHeroId();
+            if (!TryGetHeroItemInfo(heroID, libID, list, out int itemID, out int itemCount)) return;
+            itemCell.SetActive(true);
+            itemCell.Init(new ItemCellModel(itemID, true, itemCount));
+            SetCountActive(itemCell, itemCount);
+            itemCell.button.SetListener(() => ItemTipUtility.Show(itemID));
+        }
+        else
+        {
+            libButton.SetActive(true);
+            libButton.SetListener(() =>
+            {
+                HeroDebutCallRateHeroWin.worldPos = libButton.transform.position;
+                HeroDebutCallRateHeroWin.dataList = GetLibItemList(libID, list);
+                HeroDebutCallRateHeroWin.isDownShow = true;
+                UIManager.Instance.OpenWindow<HeroDebutCallRateHeroWin>();
+            });
+        }
+    }
+    public List<Item> GetLibItemList(int libID, List<int> itemList)
+    {
+        List<Item> res = new();
+        for (int i = 0; i < itemList.Count; i++)
+        {
+            int itemID = itemList[i];
+            var config = ItemConfig.Get(itemID);
+            if (config == null) continue;
+
+            if (!TreasureItemLibConfig.TryGetID(libID, itemID, out int id)) continue;
+            var treasureItemLibConfig = TreasureItemLibConfig.Get(id);
+            if (treasureItemLibConfig == null) continue;
+
+            res.Add(new Item(itemID, treasureItemLibConfig.ItemCount));
+        }
+        return res;
+    }
+
+    public bool TryGetHeroItemInfo(int heroID, int libID, List<int> itemList, out int itemID, out int itemCount)
+    {
+        itemID = 0;
+        itemCount = 0;
+        if (itemList == null) return false;
+
+        for (int i = 0; i < itemList.Count; i++)
+        {
+            itemID = itemList[i];
+            var config = ItemConfig.Get(itemID);
+            if (config == null) continue;
+
+            if (!TreasureItemLibConfig.TryGetID(libID, itemID, out int id)) continue;
+            var treasureItemLibConfig = TreasureItemLibConfig.Get(id);
+            if (treasureItemLibConfig == null) continue;
+
+            //鏈綋
+            if (config.Type == 150)
+            {
+                if (heroID == itemID)
+                {
+                    itemCount = treasureItemLibConfig.ItemCount;
+                    return true;
+                }
+            }
+            else if (config.Type == 151)
+            {
+                if (heroID == config.EffectValueA1)
+                {
+                    itemCount = treasureItemLibConfig.ItemCount;
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutCallRateItem.cs.meta b/Main/System/HeroDebut/HeroDebutCallRateItem.cs.meta
new file mode 100644
index 0000000..454efe4
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallRateItem.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7741319acfce9754caec83e02f18d8b8
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallRateWin.cs b/Main/System/HeroDebut/HeroDebutCallRateWin.cs
new file mode 100644
index 0000000..388733e
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallRateWin.cs
@@ -0,0 +1,83 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class HeroDebutCallRateWin : UIBase
+{
+    [SerializeField] ScrollerController scroller;
+    public const int rowCountMax = 4;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+
+    protected override void OnPreOpen()
+    {
+        scroller.OnRefreshCell += OnRefreshCell;
+        CreateScroller();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+    }
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as HeroDebutCallRateCell;
+        _cell.Display(cell.index, gridRateDict, gridList, xbConfig);
+    }
+
+    Dictionary<int, int> gridRateDict;
+    List<int> gridList;
+    XBGetItemConfig xbConfig;
+    void CreateScroller()
+    {
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        xbConfig = HappyXBModel.Instance.GetXBItemConfigByType(config.ActTreasureType);
+        if (xbConfig == null || xbConfig.GridItemRateList1 == null) return;
+
+        gridRateDict = GetGridRateDict(xbConfig.GridItemRateList1);
+        if (gridRateDict == null) return;
+
+        gridList = GetSortedGridList();
+        if (gridList == null) return;
+
+        scroller.Refresh();
+        int rowCount = (int)Mathf.Ceil((float)gridList.Count / rowCountMax);
+        for (int i = 0; i < rowCount; i++)
+        {
+            scroller.AddCell(ScrollerDataType.Header, i);
+        }
+        scroller.Restart();
+    }
+
+    //<鏍煎瓙,涓囧垎鐜�>
+    public Dictionary<int, int> GetGridRateDict(int[][] gridItemRateList1)
+    {
+        Dictionary<int, int> res = new();
+        for (int i = 0; i < gridItemRateList1.Length; i++)
+        {
+            res[gridItemRateList1[i][1]] = i == 0 ?
+                gridItemRateList1[i][0] :
+                gridItemRateList1[i][0] - gridItemRateList1[i - 1][0];
+        }
+        return res;
+    }
+
+    public List<int> GetSortedGridList()
+    {
+        if (gridRateDict == null || gridRateDict.Count == 0) return null;
+        List<int> sortedGrids = new List<int>(gridRateDict.Keys);
+        sortedGrids.Sort();
+        // sortedGrids.Sort((a, b) =>
+        // {
+        //     int rateA = gridRateDict[a];
+        //     int rateB = gridRateDict[b];
+        //     return rateA.CompareTo(rateB);
+        // });
+
+        return sortedGrids;
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutCallRateWin.cs.meta b/Main/System/HeroDebut/HeroDebutCallRateWin.cs.meta
new file mode 100644
index 0000000..5d8890e
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallRateWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8dc5b2c9b2441074594900b46d1abea5
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallResultCell.cs b/Main/System/HeroDebut/HeroDebutCallResultCell.cs
new file mode 100644
index 0000000..a379afc
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallResultCell.cs
@@ -0,0 +1,104 @@
+using UnityEngine;
+using DG.Tweening;
+
+public class HeroDebutCallResultCell : MonoBehaviour
+{
+    [SerializeField] public ItemCell itemCell;
+    [SerializeField] UIEffectPlayer orbBaseEffect;    // 鍒濆鐘舵�佺壒鏁�
+    [SerializeField] UIEffectPlayer orbBoomEffect;    // 鐖嗗彂鐬棿鐗规晥
+    [SerializeField] UIEffectPlayer orbQualityEffect; // 鍝佽川搴曡壊鐗规晥
+    [SerializeField] UIEffectPlayer flowEffect;       // 鏈�缁堟祦鍏夌壒鏁�
+
+    [HideInInspector] public Vector3 originalLocalPos;
+
+    void Awake()
+    {
+        // 璁板綍鍒濆鏈湴鍧愭爣锛岀敤浜庡彂鐗屽姩鐢荤殑褰掍綅
+        originalLocalPos = transform.localPosition;
+    }
+
+    /// <summary>
+    /// 鍒濆鍖栨牸瀛愭暟鎹�
+    /// </summary>
+    public void DisplayItemCell(int itemID, int count)
+    {
+        itemCell.Init(new ItemCellModel(itemID, true, count));
+        itemCell.button.SetListener(() => ItemTipUtility.Show(itemID));
+    }
+
+    /// <summary>
+    /// 閲嶇疆鎵�鏈� UI 鍏冪礌鍜岀壒鏁堣嚦鍒濆鐘舵��
+    /// </summary>
+    public void ResetState()
+    {
+        itemCell.gameObject.SetActive(false);
+        orbBaseEffect.SetActive(false);
+        orbBoomEffect.SetActive(false);
+        orbQualityEffect.SetActive(false);
+        flowEffect.SetActive(false);
+    }
+
+    /// <summary>
+    /// 闃舵 1锛氭挱鏀惧垵濮嬪紩瀵煎厜鐐癸紙椋炶闃舵锛�
+    /// </summary>
+    public void PlayInitialOrb()
+    {
+        orbBaseEffect.SetActive(true);
+        orbBoomEffect.SetActive(false);
+        orbQualityEffect.SetActive(false);
+
+        orbBaseEffect.Play(4); // 鎾斁绱㈠紩涓�4鐨勯�氱敤椋炶鏁�
+    }
+
+    /// <summary>
+    /// 闃舵 2 & 3锛氭墽琛岀垎寮�銆佹樉鑹层�佺炕鐗屻�佸睍绀烘祦鍏夌殑缁勫悎搴忓垪
+    /// </summary>
+    /// <param name="qualityIndex">鍝佽川搴曡壊鐗规晥绱㈠紩</param>
+    /// <param name="flowQualityIndex">鏈�缁堟祦鍏夌壒鏁堢储寮�</param>
+    /// <returns>杩斿洖 Sequence 鏂逛究澶栭儴杩涜 Stagger锛堜氦閿欙級鎺掑垪</returns>
+    public Tween PlayExplosionFadeAndFlipReveal(int qualityIndex, int flowQualityIndex)
+    {
+        Sequence seq = DOTween.Sequence();
+
+        // [0.0s] 鍒囨崲鐗规晥锛氬叧闂琛屾�侊紝瑙﹀彂鐖嗗彂鎬�
+        seq.InsertCallback(0f, () =>
+        {
+            orbBaseEffect.SetActive(false);
+            orbBoomEffect.SetActive(true);
+            orbBoomEffect.Play(3);
+        });
+
+        // [0.2s] 灞曠ず鍝佽川鍩鸿壊
+        seq.InsertCallback(0.2f, () =>
+        {
+            orbQualityEffect.transform.localScale = Vector3.zero;
+            orbQualityEffect.SetActive(true);
+            orbQualityEffect.Play(qualityIndex);
+        });
+
+        // 鍝佽川鍏夊洟鐢卞皬鍙樺ぇ鐨勫洖寮瑰姩鐢�
+        seq.Insert(0.2f, orbQualityEffect.transform.DOScale(Vector3.one, 0.2f).SetEase(Ease.OutBack));
+
+        // [0.8s] 鍑嗗缈荤墝锛氭縺娲� ItemCell 骞惰缃� 90 搴︿晶鍚戯紝鍑嗗鏃嬭浆
+        seq.InsertCallback(0.8f, () =>
+        {
+            itemCell.gameObject.SetActive(true);
+            itemCell.transform.localEulerAngles = new Vector3(0, 90f, 0);
+        });
+
+        // [0.8s] 缈昏浆鍔ㄤ綔锛堣�楁椂 0.3s锛夛細浠� 90 搴︽棆杞洖 0 搴�
+        seq.Insert(0.8f, itemCell.transform.DOLocalRotate(Vector3.zero, 0.3f, RotateMode.Fast).SetEase(Ease.OutSine));
+
+        // [1.1s] 搴忓垪瀹岀粨锛氭竻鐞嗕复鏃剁壒鏁堬紝婵�娲绘寔涔呮祦鍏�
+        seq.InsertCallback(1.1f, () =>
+        {
+            orbBoomEffect.SetActive(false);
+            orbQualityEffect.SetActive(false); 
+
+            flowEffect.SetActive(true);
+            flowEffect.Play(flowQualityIndex); 
+        });
+
+        return seq;
+    }
+}
\ No newline at end of file
diff --git a/Main/System/HeroDebut/HeroDebutCallResultCell.cs.meta b/Main/System/HeroDebut/HeroDebutCallResultCell.cs.meta
new file mode 100644
index 0000000..a4265e4
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallResultCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 05657965f47d7c34b8cc628132fa967f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallResultWin.cs b/Main/System/HeroDebut/HeroDebutCallResultWin.cs
new file mode 100644
index 0000000..8217162
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallResultWin.cs
@@ -0,0 +1,370 @@
+using UnityEngine;
+using DG.Tweening;
+using System.Collections.Generic;
+
+public class HeroDebutCallResultWin : UIBase
+{
+    [SerializeField] Transform moneyRect;
+    [SerializeField] OwnItemCell ownItemCell;
+    [SerializeField] ItemCell presentItemCell;         // 鎶藉崱鑾峰緱鐨勮禒閫侀亾鍏�
+    [SerializeField] RectTransform oneRect;             // 鍗曟娊瀹瑰櫒涓績鐐�
+    [SerializeField] HeroDebutCallResultCell oneCell;   // 鍗曟娊鍗曞厓鏍�
+    [SerializeField] RectTransform tenRect;             // 鍗佽繛瀹瑰櫒
+    [SerializeField] HeroDebutCallResultCell[] tenCell; // 鍗佽繛鍗曞厓鏍兼暟缁�
+
+    [SerializeField] UIEffectPlayer firstEffect;        // 寮�灞忓垵濮嬬壒鏁�
+
+    [SerializeField] HeroDebutCallButton callButton;    // 鍐嶆鎶藉彇鎸夐挳
+    [SerializeField] ButtonEx okButton;                 // 纭畾杩斿洖鎸夐挳
+
+
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    HappyXBModel xbManager => HappyXBModel.Instance;
+
+    bool isSkip;            // 鏄惁璺宠繃鍔ㄧ敾
+    int treasureType;       // 鎶藉崱瀹濆簱绫诲瀷
+    bool isOne = false;     // 鏄惁涓哄崟鎶芥ā寮�
+
+    private Sequence animSeq; // 涓诲姩鐢诲簭鍒�
+
+    protected override void InitComponent()
+    {
+        okButton.SetListener(CloseWindow);
+    }
+
+    protected override void OnPreOpen()
+    {
+        animSeq?.Kill();
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        treasureType = config.ActTreasureType;
+        // 鏍规嵁閰嶇疆鍜屾椂闂存埑鍔犺浇鐢ㄦ埛鐨勬槸鍚﹁烦杩囧姩鐢昏缃�
+        isSkip = manager.LoadCallSkipData(config.CfgID, act.startDate, act.endDate);
+
+        // 缁戝畾鏁版嵁鍒锋柊鍥炶皟
+        HappyXBModel.Instance.RefreshXBResultAct += RefreshXBResultAct;
+        HappyXBModel.Instance.RefreshXBTypeInfoAct += OnRefreshXBTypeInfoAct;
+
+        var treasureSetConfig = TreasureSetConfig.Get(config.ActTreasureType);
+        if (treasureSetConfig == null) return;
+        ownItemCell.itemID = treasureSetConfig.CostItemID;
+
+        RefreshXBResultAct();
+    }
+
+    protected override void OnPreClose()
+    {
+        animSeq?.Kill();
+        // 瑙g粦鍥炶皟锛岄槻姝㈠唴瀛樻硠婕�
+        HappyXBModel.Instance.RefreshXBResultAct -= RefreshXBResultAct;
+        HappyXBModel.Instance.RefreshXBTypeInfoAct -= OnRefreshXBTypeInfoAct;
+    }
+
+    /// <summary>
+    /// 鍒锋柊鎶藉崱缁撴灉鐣岄潰
+    /// </summary>
+    void RefreshXBResultAct()
+    {
+        isOne = HeroUIManager.Instance.selectCallIndex == 0;
+
+        // 鍒濆鍖栭《閮ㄨ禒閫佺墿鍝�
+        int itemId = xbManager.addXBAddItemID;
+        long count = xbManager.addXBItemCount;
+        presentItemCell.Init(new ItemCellModel(itemId, true, count));
+        presentItemCell.button.SetListener(() => ItemTipUtility.Show(itemId));
+
+        // 鏍规嵁鍗曟娊鎴栧崄杩炲~鍏呯墿鍝佹暟鎹�
+        if (isOne)
+        {
+            if (!xbManager.xbResultDict.IsNullOrEmpty())
+            {
+                oneCell.DisplayItemCell(xbManager.xbResultDict[0].itemId, xbManager.xbResultDict[0].count);
+            }
+        }
+        else
+        {
+            for (int i = 0; i < tenCell.Length; i++)
+            {
+                if (i < xbManager.xbResultDict?.Count)
+                {
+                    tenCell[i].DisplayItemCell(xbManager.xbResultDict[i].itemId, xbManager.xbResultDict[i].count);
+                }
+            }
+        }
+
+        callButton.Display(treasureType, HeroUIManager.Instance.selectCallIndex);
+
+        if (isSkip)
+        {
+            // 妯″紡锛氳烦杩囧姩鐢伙紝鐩存帴鏄剧ず鏈�缁堢姸鎬�
+            firstEffect.SetActive(false);
+            ShowImmediate();
+        }
+        else
+        {
+            // 妯″紡锛氭挱鏀惧畬鏁村睍绀哄姩鐢�
+            PrepareAnimation();
+            firstEffect.SetActive(true);
+            firstEffect.Play(0);
+
+            // 棰勭暀 1.1s 鐨勫紑灞忓姩鏁堟椂闂村悗锛屽紑濮嬫挱鏀惧彂鐗�/缈荤墝搴忓垪
+            PlayResultAnimation(1.1f);
+        }
+    }
+
+    private void OnRefreshXBTypeInfoAct() { RefreshXBResultAct(); }
+
+    /// <summary>
+    /// 闈欐�佹樉绀猴紙鏃犲姩鐢荤洿鎺ュ睍绀虹粨鏋滐級
+    /// </summary>
+    private void ShowImmediate()
+    {
+        animSeq?.Kill();
+        oneRect.SetActive(isOne);
+        tenRect.SetActive(!isOne);
+
+        ownItemCell.SetActive(true);
+        moneyRect.SetActive(true);
+        presentItemCell.SetActive(true);
+        callButton.SetActive(true);
+        okButton.SetActive(true);
+
+        if (isOne)
+        {
+            oneCell.SetActive(true);
+            oneCell.ResetState();
+            oneCell.itemCell.SetActive(true);
+        }
+        else
+        {
+            for (int i = 0; i < tenCell.Length; i++)
+            {
+                if (i < xbManager.xbResultDict?.Count)
+                {
+                    tenCell[i].SetActive(true);
+                    tenCell[i].transform.localPosition = tenCell[i].originalLocalPos;
+                    tenCell[i].ResetState();
+                    tenCell[i].itemCell.SetActive(true);
+                }
+                else
+                {
+                    tenCell[i].SetActive(false);
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// 鍔ㄧ敾鍓嶇疆鍑嗗锛堥殣钘忓厓绱犲苟閲嶇疆鍧愭爣锛�
+    /// </summary>
+    private void PrepareAnimation()
+    {
+        oneRect.SetActive(isOne);
+        tenRect.SetActive(!isOne);
+
+        ownItemCell.SetActive(false);
+        moneyRect.SetActive(false);
+        presentItemCell.SetActive(false);
+        callButton.SetActive(false);
+        okButton.SetActive(false);
+
+        if (isOne)
+        {
+            oneCell.SetActive(true);
+            oneCell.ResetState();
+        }
+        else
+        {
+            for (int i = 0; i < tenCell.Length; i++)
+            {
+                if (i < xbManager.xbResultDict?.Count)
+                {
+                    tenCell[i].SetActive(true);
+                    tenCell[i].ResetState();
+                    tenCell[i].transform.localPosition = tenCell[i].originalLocalPos;
+                }
+                else
+                {
+                    tenCell[i].SetActive(false);
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// 鏍稿績閫昏緫锛氱紪鎺掔粨鏋滃睍绀哄姩鐢绘椂闂磋酱
+    /// </summary>
+    private void PlayResultAnimation(float startDelay = 0f)
+    {
+        animSeq?.Kill();
+        animSeq = DOTween.Sequence();
+
+        if (isOne)
+        {
+            // ==================== 鍗曟娊鍔ㄧ敾閫昏緫 ====================
+            float timelineCursor = startDelay;
+
+            // 1. 鎾斁涓績鍏夊洟
+            animSeq.InsertCallback(timelineCursor, () => oneCell.PlayInitialOrb());
+
+            // 棰勭暀鐭殏鐨勫睍绀烘椂闂�
+            float finishShowTime = 0.12f;
+            timelineCursor += finishShowTime;
+
+            // 2. 瑙﹀彂鐖嗗紑涓庣炕鐗岀粍鍚堝姩鐢�
+            int itemId = xbManager.xbResultDict[0].itemId;
+            int quality = GetOrbQuality(itemId);
+            int flowQuality = GetFlowQuality(itemId);
+
+            animSeq.Insert(timelineCursor, oneCell.PlayExplosionFadeAndFlipReveal(quality, flowQuality));
+
+            // 鎺ㄨ繘娓告爣鑷崇粍鍚堝姩鐢荤粨鏉燂紙1.1s鍩虹鏃堕暱 + 0.3s缂撳啿锛�
+            timelineCursor += 1.4f;
+
+            // 3. 寮瑰嚭搴曢儴 UI
+            animSeq.InsertCallback(timelineCursor, ShowBottomUI);
+        }
+        else
+        {
+            // ==================== 鍗佽繛鍔ㄧ敾閫昏緫 ====================
+            int count = xbManager.xbResultDict.Count;
+            float staggerInterval = 0.1f; // 鍙戠墝闂撮殧
+            float moveDuration = 0.12f;    // 椋炶鏃堕棿
+            float timelineCursor = startDelay;
+
+            // 1. 渚濇浠庝腑蹇冪偣鍚戠洰鏍囦綅缃彂灏勫厜鍥紙鍙戠墝闃舵锛�
+            for (int i = 0; i < count; i++)
+            {
+                var cell = tenCell[i];
+                cell.transform.position = oneRect.position; // 璧峰浜庝腑蹇�
+                float delay = timelineCursor + i * staggerInterval;
+
+                animSeq.InsertCallback(delay, () => cell.PlayInitialOrb());
+                animSeq.Insert(delay, cell.transform.DOLocalMove(cell.originalLocalPos, moveDuration).SetEase(Ease.OutCubic));
+            }
+
+            // 璁$畻鎵�鏈夊崱鐗屽畬鎴愰琛岀殑鏃跺埢
+            float finishFlyingTime = ((count - 1) * staggerInterval) + moveDuration;
+            timelineCursor += finishFlyingTime;
+
+            // 2. 渚濇瑙﹀彂鐖嗗紑缈荤墝鍔ㄧ敾锛堝睍绀洪樁娈碉級
+            for (int i = 0; i < count; i++)
+            {
+                int itemId = xbManager.xbResultDict[i].itemId;
+                int quality = GetOrbQuality(itemId);
+                int flowQuality = GetFlowQuality(itemId);
+
+                animSeq.Insert(timelineCursor + i * staggerInterval, tenCell[i].PlayExplosionFadeAndFlipReveal(quality, flowQuality));
+            }
+
+            // 璁$畻鍏ㄩ儴鍗$墝缈昏浆瀹屾垚鐨勬椂闂寸偣骞跺姞鍏ョ紦鍐�
+            float finalFlipDuration = 1.1f + ((count - 1) * staggerInterval) + 0.3f;
+            timelineCursor += finalFlipDuration;
+
+            // 3. 寮瑰嚭搴曢儴 UI
+            animSeq.InsertCallback(timelineCursor, ShowBottomUI);
+        }
+    }
+
+    /// <summary>
+    /// 灞曠ず搴曢儴鎿嶄綔鎸夐挳锛屽苟妫�鏌ユ槸鍚﹁Е鍙戞灏嗙珛缁�
+    /// </summary>
+    private void ShowBottomUI()
+    {
+        ownItemCell.SetActive(true);
+        moneyRect.SetActive(true);
+        presentItemCell.SetActive(true);
+        callButton.SetActive(true);
+        okButton.SetActive(true);
+
+        presentItemCell.transform.localScale = Vector3.zero;
+        callButton.transform.localScale = Vector3.zero;
+        okButton.transform.localScale = Vector3.zero;
+
+        Sequence bottomSeq = DOTween.Sequence();
+        bottomSeq.Append(presentItemCell.transform.DOScale(Vector3.one, 0.3f).SetEase(Ease.OutBack));
+        bottomSeq.Join(callButton.transform.DOScale(Vector3.one, 0.3f).SetEase(Ease.OutBack));
+        bottomSeq.Join(okButton.transform.DOScale(Vector3.one, 0.3f).SetEase(Ease.OutBack));
+
+        bottomSeq.OnComplete(() =>
+        {
+            if (!isSkip)
+            {
+                CheckAndShowHeroLH();
+            }
+        });
+        animSeq.Append(bottomSeq);
+    }
+
+    /// <summary>
+    /// 妫�娴嬪苟灞曠ず楂樺搧璐ㄦ灏嗙珛缁橈紙寮圭獥灞曠ず锛�
+    /// </summary>
+    private void CheckAndShowHeroLH()
+    {
+        // 娓呯悊缂撳瓨鍒楄〃
+        ItemLogicUtility.Instance.poplhHeroIdList.Clear();
+
+        List<int> uniqueHeroIds = new List<int>();
+        int count = xbManager.xbResultDict.Count;
+
+        for (int i = 0; i < count; i++)
+        {
+            int itemId = xbManager.xbResultDict[i].itemId;
+
+            // 浠呭 HeroConfig 涓瓨鍦ㄧ殑瀹屾暣姝﹀皢杩涜澶勭悊
+            if (HeroConfig.HasKey(itemId))
+            {
+                // 浠呭睍绀洪珮浜庤瀹氬搧璐ㄧ殑姝﹀皢
+                if (HeroConfig.Get(itemId).Quality < HappyXBModel.Instance.lhQuality) continue;
+
+                if (!uniqueHeroIds.Contains(itemId))
+                {
+                    uniqueHeroIds.Add(itemId);
+                }
+            }
+        }
+
+        // 濡傛灉瀛樺湪绗﹀悎鏉′欢鐨勬灏嗭紝鎵撳紑澶у浘灞曠ず鐣岄潰
+        if (uniqueHeroIds.Count > 0)
+        {
+            ItemLogicUtility.Instance.poplhHeroIdList = uniqueHeroIds;
+
+            if (!UIManager.Instance.IsOpenedInList<HeroShowLHWin>())
+            {
+                UIManager.Instance.OpenWindow<HeroShowLHWin>();
+            }
+        }
+    }
+
+    // --- 杈呭姪鏂规硶锛氭槧灏勯厤缃搧璐ㄥ埌鐗规晥绱㈠紩 ---
+
+    private int GetOrbQuality(int itemId)
+    {
+        int qualityLevel = ItemConfig.Get(itemId).ItemColor;
+        switch (qualityLevel)
+        {
+            case 2: return 5; // 绱壊
+            case 3: return 2; // 榛勮壊
+            case 4: return 0; // 姗欒壊
+            case 5: return 1; // 绾㈣壊
+            default: return 0;
+        }
+    }
+
+    private int GetFlowQuality(int itemId)
+    {
+        int qualityLevel = ItemConfig.Get(itemId).ItemColor;
+        switch (qualityLevel)
+        {
+            case 2: return 3; // 绱壊
+            case 3: return 2; // 榛勮壊
+            case 4: return 0; // 姗欒壊
+            case 5: return 1; // 绾㈣壊
+            default: return 0;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/System/HeroDebut/HeroDebutCallResultWin.cs.meta b/Main/System/HeroDebut/HeroDebutCallResultWin.cs.meta
new file mode 100644
index 0000000..97ac892
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallResultWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6ffc73cd38a0318498657bf4ae3312a4
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCallWin.cs b/Main/System/HeroDebut/HeroDebutCallWin.cs
new file mode 100644
index 0000000..f988de6
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallWin.cs
@@ -0,0 +1,398 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+using DG.Tweening;
+using System.Linq;
+using EnhancedUI.EnhancedScroller;
+
+public class HeroDebutCallWin : UIBase
+{
+    [SerializeField] ImageEx bgImage;
+    [SerializeField] RectTransform changeRect;
+    [SerializeField] UIEffectPlayer changeUIEffect;
+
+    [SerializeField] OwnItemCell ownItemCell;
+    [SerializeField] ButtonEx closeBtn;
+    [SerializeField] Toggle skipToggle;
+    [SerializeField] HeroDebutCallButton xbButton1;
+    [SerializeField] HeroDebutCallButton xbButton10;
+    [SerializeField] TextEx resMoneyCallCntText;
+    [SerializeField] TextEx nextBigAwardCntText;
+    [SerializeField] GradientText heroQualityText;
+    [SerializeField] GradientText heroNameText;
+
+    [SerializeField] TextEx timeText;
+
+    [SerializeField] TextEx nameText;
+    [SerializeField] TextEx descText;
+    [SerializeField] ImageEx countryImage;
+    [SerializeField] ImageEx jobImage;
+    [SerializeField] ButtonEx changeHeroButton;//鏇存崲鑻遍泟
+    [SerializeField] ButtonEx previewButton;//婊$骇棰勮
+    [SerializeField] ButtonEx closeButton;
+    [SerializeField] ButtonEx shopButton; // 鍏戞崲鍟嗗簵
+    [SerializeField] RedpointBehaviour shopRedpoint;
+    [SerializeField] ButtonEx giftButton; // 鐨囨潈绀煎寘
+    [SerializeField] RedpointBehaviour giftRedpoint;
+
+    [SerializeField] ButtonEx rankButton;
+    [SerializeField] TextEx[] top3NameText;
+    [SerializeField] TextEx rankTipText;
+    [SerializeField] ButtonEx rateButton;
+    [SerializeField] ScrollerController scroller;
+    [SerializeField] ButtonEx historyButton;
+    [SerializeField] UIHeroController lhController;
+    [SerializeField] UIHeroController uiHeroController;
+    [SerializeField] HeroDebutCallBubbleCell[] bubbleCell;
+
+    [SerializeField] float modleSize = 1f;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+
+    protected override void InitComponent()
+    {
+        closeButton.SetListener(CloseWindow);
+        shopButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutShopWin>());
+        giftButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutGiftWin>());
+        changeHeroButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutCallChangeWin>());
+        rankButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutRankWin>());
+        rateButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutCallRateWin>());
+        historyButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutCallHistoryWin>());
+        previewButton.SetListener(OnClickPreview);
+        skipToggle.AddListener((value) =>
+        {
+            manager.SaveCallSkipData(config.CfgID, act.startDate, act.endDate, value);
+        });
+    }
+
+
+    protected override void OnPreOpen()
+    {
+        scroller.lockType = EnhanceLockType.LockVerticalBottom;
+        RankModel.Instance.ResetQueryParam();
+        RankModel.Instance.QueryRankByPage(manager.sendRankType, watchID: (int)PlayerDatas.Instance.baseData.PlayerID, groupValue1: manager.actNum);
+
+        HappyXBModel.Instance.RefreshXBTypeInfoAct += OnRefreshXBTypeInfoAct;
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        RankModel.Instance.onRankRefresh += OnRankRefresh;
+        PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefresh;
+        PackManager.Instance.RefreshItemEvent += RefreshItemEvent;
+        scroller.OnRefreshCell += OnRefreshCell;
+        manager.OnUpdateGameRecInfo += OnUpdateGameRecInfo;
+
+        if (manager.isSendFirst)
+        {
+            act = manager.GetOperationHeroAppearInfo();
+            if (act == null) return;
+
+            config = ActHeroAppearConfig.Get(act.CfgID);
+            if (config == null) return;
+
+            int treasureType = config.ActTreasureType;
+            manager.SendViewGameRecPack(treasureType);
+        }
+
+        InitRedpoint();
+        CreateScroller();
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        HappyXBModel.Instance.RefreshXBTypeInfoAct -= OnRefreshXBTypeInfoAct;
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+        RankModel.Instance.onRankRefresh -= OnRankRefresh;
+        PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefresh;
+        PackManager.Instance.RefreshItemEvent -= RefreshItemEvent;
+        scroller.OnRefreshCell -= OnRefreshCell;
+        manager.OnUpdateGameRecInfo -= OnUpdateGameRecInfo;
+        manager.OnUpdateHeroAppearPlayerInfoEvent -= OnUpdateHeroAppearPlayerInfoEvent;
+    }
+
+
+
+    // 1. 鍦ㄧ被涓0鏄庝竴涓叏灞�鐨� Sequence 鍙橀噺锛岀敤浜庣粺涓�绠℃帶鍔ㄧ敾
+    private Sequence heroAnimSeq;
+
+    private void OnUpdateHeroAppearPlayerInfoEvent(int actNum)
+    {
+        changeRect.SetActive(false);
+
+        // 2. 褰诲簳鏉�姝讳箣鍓嶇殑 Sequence锛岄槻姝㈠揩閫熻繛鐐归�犳垚鍐呴儴 Tween 澶嶇敤閿欎贡
+        if (heroAnimSeq != null)
+        {
+            heroAnimSeq.Kill();
+            heroAnimSeq = null;
+        }
+
+        // 鍒锋柊鐣岄潰鏁版嵁鍜岃嫳闆勬ā鍨嬶紙杩欓噷闈細璋冪敤 lhController.Create锛�
+        Display();
+
+        Transform targetTrans = lhController.transform;
+
+        // 鍋滄 Transform 涓婂彲鑳芥畫鐣欑殑鍗曠嫭鍔ㄧ敾
+        targetTrans.DOKill();
+
+        int heroID = manager.GetCurrentDisplayCallHeroId();
+        int skinID = manager.GetDefaultSkinID(heroID);
+        var skinConfig = HeroSkinConfig.Get(skinID);
+
+        float baseScaleValue = 1f; // 榛樿缂╂斁
+        // 妫�鏌ユ槸鍚︽湁閰嶇疆涓撳睘鐨勭珛缁樼缉鏀惧弬鏁帮紙TachieParam[2]锛�
+        if (skinConfig != null && skinConfig.TachieParam != null && skinConfig.TachieParam.Length == 4)
+        {
+            baseScaleValue = skinConfig.TachieParam[2];
+        }
+
+        Vector3 baseScale = Vector3.one * baseScaleValue;
+
+        // 銆愬己鍒跺浣嶏紒銆戣В鍐� UIHeroController 鍐呴儴 return 瀵艰嚧鐨勭缉鏀炬湭澶嶄綅闂
+        targetTrans.localScale = baseScale;
+
+        // 鑾峰彇鎴栨坊鍔� CanvasGroup 鐢ㄤ簬閫忔槑搴︽帶鍒�
+        CanvasGroup cg = lhController.GetComponent<CanvasGroup>();
+        if (cg == null) cg = lhController.gameObject.AddComponent<CanvasGroup>();
+        cg.DOKill();
+        cg.alpha = 0.8f;
+
+        changeUIEffect.Play();
+
+        // 4. 鍒涘缓鏂扮殑 Sequence 骞惰祴鍊肩粰鎴愬憳鍙橀噺
+        heroAnimSeq = DOTween.Sequence();
+
+        // 缂╂斁鍔ㄧ敾鍩轰簬姝g‘鐨� baseScale 杩涜璁$畻锛堝彉澶�1.1鍊嶅悗鍐嶈繕鍘燂級
+        heroAnimSeq.Append(targetTrans.DOScale(baseScale * 1.1f, 0.3f).SetEase(Ease.OutQuad));
+        heroAnimSeq.Append(targetTrans.DOScale(baseScale, 0.3f).SetEase(Ease.InQuad));
+
+        // 閫忔槑搴�
+        heroAnimSeq.Join(cg.DOFade(1f, 0.3f).SetEase(Ease.Linear));
+
+        // 鍔ㄧ敾瀹屾垚鍚庢樉绀� changeRect锛屽苟娓呯┖寮曠敤
+        heroAnimSeq.OnComplete(() =>
+        {
+            changeRect.SetActive(true);
+            heroAnimSeq = null;
+        });
+    }
+
+    private void OnUpdateGameRecInfo()
+    {
+        CreateScroller();
+    }
+
+    public void RefreshItemEvent(PackType packType, int index, int itemID)
+    {
+        if (packType != PackType.Item && treasureSetConfig?.CostItemID != itemID) return;
+        Display();
+    }
+    private void PlayerDataRefresh(PlayerDataType type)
+    {
+        if (type != PlayerDataType.Gold) return;
+        Display();
+    }
+
+    private void OnRankRefresh(int type)
+    {
+        if (type != manager.sendRankType) return;
+        ShowTop3();
+    }
+
+    private void OnSecondEvent()
+    {
+        manager.GetActTimeStr(timeText);
+    }
+
+    private void OnRefreshXBTypeInfoAct()
+    {
+        Display();
+    }
+
+    public void InitRedpoint()
+    {
+        shopRedpoint.redpointId = manager.GetRedPointId(HeroDebutRedPointType.Shop);
+        giftRedpoint.redpointId = manager.GetRedPointId(HeroDebutRedPointType.Gift);
+    }
+
+    private void OnClickPreview()
+    {
+        if (heroConfig == null) return;
+        HeroUIManager.Instance.selectForPreviewHeroID = heroConfig.HeroID;
+        UIManager.Instance.OpenWindow<HeroBestBaseWin>();
+    }
+    OperationHeroAppearInfo act;
+    ActHeroAppearConfig config;
+    HeroConfig heroConfig;
+    TreasureSetConfig treasureSetConfig;
+    XBTypeInfo xbTypeInfo;
+    private void Display()
+    {
+        act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        int heroID = manager.GetCurrentDisplayCallHeroId();
+        heroConfig = HeroConfig.Get(heroID);
+        if (heroConfig == null) return;
+
+        int skinID = manager.GetDefaultSkinID(heroID);
+        var skinConfig = HeroSkinConfig.Get(skinID);
+        if (skinConfig == null) return;
+
+        var artConfig = ActHeroAppearArtConfig.Get(heroID);
+        if (artConfig == null || artConfig.CallBubbleItems == null) return;
+
+        int treasureType = config.ActTreasureType;
+        treasureSetConfig = TreasureSetConfig.Get(treasureType);
+        if (treasureSetConfig == null) return;
+
+        xbTypeInfo = HappyXBModel.Instance.GetXBInfoByType(treasureType);
+        if (xbTypeInfo == null) return;
+
+        bgImage.SetSprite(artConfig.MainBgImage);
+
+        lhController.Create(skinID, 1, motionName: "", isLh: true);
+        uiHeroController.Create(skinID, modleSize);
+        uiHeroController.transform.localScale = new Vector3(modleSize, modleSize, modleSize);
+
+        ownItemCell.itemID = treasureSetConfig.CostItemID;
+        skipToggle.isOn = manager.LoadCallSkipData(config.CfgID, act.startDate, act.endDate);
+
+        xbButton1.Display(config.ActTreasureType, 0);
+        xbButton10.Display(config.ActTreasureType, 1);
+        resMoneyCallCntText.text = Language.Get("HeroDebut24", Mathf.Max(treasureSetConfig.DailyMaxCountMoney - xbTypeInfo.treasureCountTodayGold, 0));
+
+        var needCount = GetNextXBCountForBigAward(treasureType);
+        nextBigAwardCntText.text = Language.Get("HeroDebut08", needCount.ToString());
+
+        heroQualityText.text = Language.Get($"heroCallQaulity{heroConfig.Quality}");
+        manager.SetheroQaulityColor(heroQualityText, heroConfig.Quality);
+
+        nameText.text = heroConfig.Name;
+        nameText.color = UIHelper.GetUIColorByFunc(heroConfig.Quality);
+        descText.text = heroConfig.Desc;
+        countryImage.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
+        jobImage.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class));
+
+        heroNameText.text = heroConfig.Name;
+        manager.SetGradientTextColor(heroNameText, artConfig.HeroNameColor);
+
+        for (int i = 0; i < bubbleCell.Length; i++)
+        {
+            if (i < artConfig.CallBubbleItems.Length)
+            {
+                bubbleCell[i].SetActive(true);
+                bubbleCell[i].Display(artConfig.CallBubbleItems[i][0], artConfig.CallBubbleItems[i][1]);
+            }
+            else
+            {
+                bubbleCell[i].SetActive(false);
+            }
+        }
+
+        ShowTop3();
+        OnSecondEvent();
+    }
+
+    public int GetNextXBCountForBigAward(int type)
+    {
+        XBTypeInfo typeInfo = HappyXBModel.Instance.GetXBInfoByType(type);
+        if (typeInfo == null) return 0;
+
+        var xbConfig = HappyXBModel.Instance.GetXBItemConfigByType(type);
+        var luckList = xbConfig.LuckyItemRateInfo.Keys.ToList();
+        luckList.Sort();
+        for (int i = 0; i < luckList.Count; i++)
+        {
+            var luckyValue = typeInfo.luckValue;
+            if (luckyValue < luckList[i])
+            {
+                return luckList[i] - luckyValue;
+            }
+        }
+        return 0;
+    }
+    void ShowTop3()
+    {
+        for (int i = 0; i < top3NameText.Length; i++)
+        {
+            var rankData = RankModel.Instance.GetRankDataByRank(manager.loadRankType, i + 1);
+            top3NameText[i].text = rankData == null ? Language.Get("L1124") : rankData.name1;
+        }
+        int billTempID = config.BillTempID;
+        rankTipText.text = Language.Get("HeroDebut27", ActBillboardAwardConfig.GetTop3MinCalNeedValue(billTempID));
+    }
+    public List<HeroDebutGameRec> list;
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as HeroDebutCallHistoryOutCell;
+        _cell.Display(cell.index, list);
+    }
+
+    float autoScrollInterval = 2f;
+    private float autoScrollTimer = 0f;
+    private int currentScrollerIndex = 0;
+    private bool isScrollerReady = false; // 鍒ゅ畾鏍囧織
+    void CreateScroller()
+    {
+        list = manager.GetGameRecList();
+        scroller.Refresh();
+
+        int listCount = list?.Count ?? 0;
+        if (list != null)
+        {
+            for (int i = 0; i < listCount; i++)
+            {
+                scroller.AddCell(ScrollerDataType.Header, i);
+            }
+        }
+
+
+        bool canScroll = listCount > 4;// 鍙湁鏁伴噺 > 4 鏃舵墠寮�鍚� Loop 鍜岃鏃跺櫒
+        scroller.m_Scorller.Loop = canScroll;
+        isScrollerReady = canScroll;
+
+        scroller.vertical = false;
+        scroller.horizontal = false;
+        scroller.Restart();
+
+        // 濡傛灉鏄惊鐜ā寮忥紝纭繚鍒濆浣嶇疆姝g‘
+        if (canScroll)
+        {
+            scroller.m_Scorller.JumpToDataIndex(0,
+            tweenType: EnhancedScroller.TweenType.immediate);
+        }
+        autoScrollTimer = 0f;
+        currentScrollerIndex = 0;
+    }
+
+    private void LateUpdate()
+    {
+        // 鍙湁鍦ㄦ暟鎹氨缁笖瓒呰繃 4 涓椂锛屾墠鎵ц璁℃椂閫昏緫
+        if (isScrollerReady)
+        {
+            autoScrollTimer += Time.deltaTime;
+            if (autoScrollTimer >= autoScrollInterval)
+            {
+                autoScrollTimer = 0f;
+                AutoScrollNext();
+            }
+        }
+    }
+
+    private void AutoScrollNext()
+    {
+        if (list?.Count <= 4)
+        {
+            isScrollerReady = false;
+            return;
+        }
+
+        currentScrollerIndex++;
+        // 鍦� Loop 妯″紡涓嬭繘琛屽钩婊戣烦杞�
+        scroller.m_Scorller.JumpToDataIndex(
+            currentScrollerIndex % list.Count,
+            tweenType: EnhancedScroller.TweenType.easeInOutQuad,
+            tweenTime: 0.5f);
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutCallWin.cs.meta b/Main/System/HeroDebut/HeroDebutCallWin.cs.meta
new file mode 100644
index 0000000..43cdcd0
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCallWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d2e10a7ad06305c4dbd67d43b5343202
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCell.cs b/Main/System/HeroDebut/HeroDebutCell.cs
new file mode 100644
index 0000000..cd64d51
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCell.cs
@@ -0,0 +1,31 @@
+using UnityEngine;
+public class HeroDebutCell : MonoBehaviour
+{
+    [SerializeField] ButtonEx clickButton;
+    [SerializeField] ImageEx bgImage;
+    [SerializeField] ImageEx heroImage;
+    [SerializeField] GradientText titleText;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    public void Display()
+    {
+        clickButton.SetListener(() =>
+        {
+            UIManager.Instance.OpenWindow<HeroDebutWin>();
+        });
+
+
+        int heroID = manager.GetCurrentDisplayCallHeroId();
+        var artConfig = ActHeroAppearArtConfig.Get(heroID);
+        if (artConfig == null) return;
+
+        int skinID = manager.GetDefaultSkinID(heroID);
+        var skinConfig = HeroSkinConfig.Get(skinID);
+        if (skinConfig == null) return;
+
+        bgImage.SetSprite(artConfig.EntryBgImage);
+        manager.SetHeroSquareIcon(heroImage, skinConfig.SquareIcon);
+        titleText.text = artConfig.EntryTitleText;
+    }
+
+
+}
diff --git a/Main/System/HeroDebut/HeroDebutCell.cs.meta b/Main/System/HeroDebut/HeroDebutCell.cs.meta
new file mode 100644
index 0000000..7813e75
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2d56020c6e8624a4d9451d33aca7ef47
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCheckInCell.cs b/Main/System/HeroDebut/HeroDebutCheckInCell.cs
new file mode 100644
index 0000000..0fedc6e
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCheckInCell.cs
@@ -0,0 +1,60 @@
+using UnityEngine;
+
+public class HeroDebutCheckInCell : MonoBehaviour
+{
+    [SerializeField] ButtonEx clickButton;
+    [SerializeField] ImageEx bgImage;
+    [SerializeField] TextEx dayText;
+    [SerializeField] TextEx itemNameText;
+    [SerializeField] ItemCell itemCell;
+    [SerializeField] UIEffectPlayer uiEffectPlayer;
+    [SerializeField] Transform imgMask;
+
+    HeroDebutManager manager => HeroDebutManager.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/HeroDebut/HeroDebutCheckInCell.cs.meta b/Main/System/HeroDebut/HeroDebutCheckInCell.cs.meta
new file mode 100644
index 0000000..38c00a1
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCheckInCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f2adf3253dbe5a7429ed0a362a3c5c53
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutCheckInWin.cs b/Main/System/HeroDebut/HeroDebutCheckInWin.cs
new file mode 100644
index 0000000..251d4c9
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCheckInWin.cs
@@ -0,0 +1,82 @@
+using UnityEngine;
+
+public class HeroDebutCheckInWin : UIBase
+{
+    [SerializeField] ImageEx bgImage;
+    [SerializeField] UIHeroController rolelhShow;
+    [SerializeField] TextEx timeText;
+    [SerializeField] ButtonEx closeButton;
+    [SerializeField] HeroDebutCheckInCell[] cells;
+    HeroDebutManager manager => HeroDebutManager.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()
+    {
+        int heroID = manager.GetCurrentDisplayCallHeroId();
+        var artConfig = ActHeroAppearArtConfig.Get(heroID);
+        if (artConfig == null) return;
+
+        var heroConfig = HeroConfig.Get(heroID);
+        if (heroConfig == null) return;
+
+        int skinID = manager.GetDefaultSkinID(heroID);
+
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        int templateID = config.SignTempID;
+        var list = ActSignAwardConfig.GetDayNumSortList(templateID);
+        if (list == null) return;
+        
+        bgImage.SetSprite(artConfig.CheckInBgImage);
+
+
+        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);
+            }
+        }
+
+        rolelhShow.Create(skinID, 1, motionName: "", isLh: true);
+        OnSecondEvent();
+    }
+}
\ No newline at end of file
diff --git a/Main/System/HeroDebut/HeroDebutCheckInWin.cs.meta b/Main/System/HeroDebut/HeroDebutCheckInWin.cs.meta
new file mode 100644
index 0000000..dad0e72
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutCheckInWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ac084043fc15fba478af2e039db46fbe
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutGiftCell.cs b/Main/System/HeroDebut/HeroDebutGiftCell.cs
new file mode 100644
index 0000000..868083c
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutGiftCell.cs
@@ -0,0 +1,165 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class HeroDebutGiftCell : 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] TextEx limitCountText;
+    [SerializeField] ImageEx redImage;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    StoreModel storeModel => StoreModel.Instance;
+
+    public void Display(int index, List<HeroDebutGiftItem> giftItems)
+    {
+        if (giftItems.IsNullOrEmpty() || index < 0 || index >= giftItems.Count) return;
+
+        HeroDebutGiftItem item = giftItems[index];
+        if (item.type == 0)
+        {
+            DisplayStore(item.id);
+            return;
+        }
+
+        DisplayCTG(item.id);
+    }
+
+    private void DisplayCTG(int ctgId)
+    {
+        redImage.SetActive(false);
+        buyText.SetActive(true);
+        buyText1.SetActive(false);
+        moneyIconImage.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.IsCanBuyToday(ctgId);
+        titleText.text = config.Title;
+        buyImage.SetSprite(isCanBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2");
+        buyText.text = !isCanBuy ? Language.Get("storename11") : Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderConfig.PayRMBNumOnSale));
+        limitCountText.SetActive(config.DailyBuyCount > 0);
+        limitCountText.text = Language.Get("HeroDebut39", UIHelper.AppendColor(rechargeCount.todayCount >= config.DailyBuyCount ? TextColType.Red : TextColType.LightGreen, Mathf.Max(0, config.DailyBuyCount - rechargeCount.todayCount).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("TimeRush08", 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);
+        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);
+            }
+        }
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutGiftCell.cs.meta b/Main/System/HeroDebut/HeroDebutGiftCell.cs.meta
new file mode 100644
index 0000000..0a4681b
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutGiftCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3c4c10ba84995ee49925ec3512064f3c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutGiftWin.cs b/Main/System/HeroDebut/HeroDebutGiftWin.cs
new file mode 100644
index 0000000..4f161b8
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutGiftWin.cs
@@ -0,0 +1,86 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class HeroDebutGiftWin : UIBase
+{
+    [SerializeField] ButtonEx closeButton;
+    [SerializeField] ImageEx bgImage;
+    [SerializeField] ImageEx heroImage;
+    [SerializeField] ScrollerController scroller;
+    [SerializeField] TextEx timeText;
+    HeroDebutManager manager => HeroDebutManager.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;
+
+        int heroID = manager.GetCurrentDisplayCallHeroId();
+        var artConfig = ActHeroAppearArtConfig.Get(heroID);
+        if (artConfig == null) return;
+
+        bgImage.SetSprite(artConfig.GiftBgImage);
+        heroImage.SetNativeSize();
+
+        heroImage.SetSprite(artConfig.GiftHeroImage);
+        heroImage.SetNativeSize();
+
+        OnSecondEvent();
+        CreateGiftScroller();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+        RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent;
+        storeModel.RefreshBuyShopLimitEvent -= RefreshBuyShopLimitEvent;
+    }
+    private void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell.GetComponent<HeroDebutGiftCell>();
+        _cell?.Display(cell.index, giftItems);
+    }
+
+    private void OnSecondEvent()
+    {
+        manager.GetActTimeStr(timeText);
+    }
+
+    private void OnRechargeCountEvent(int obj)
+    {
+        RefreshAll();
+    }
+
+    private void RefreshBuyShopLimitEvent()
+    {
+        RefreshAll();
+    }
+
+    List<HeroDebutGiftItem> 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/HeroDebut/HeroDebutGiftWin.cs.meta b/Main/System/HeroDebut/HeroDebutGiftWin.cs.meta
new file mode 100644
index 0000000..c677203
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutGiftWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a8fd1e3fe78ecf540bd5ff1360a746d7
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutManager.cs b/Main/System/HeroDebut/HeroDebutManager.cs
new file mode 100644
index 0000000..d966740
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutManager.cs
@@ -0,0 +1,1051 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using LitJson;
+using UnityEngine;
+
+public class HeroDebutManager : GameSystemManager<HeroDebutManager>, IOpenServerActivity
+{
+    public int[] xbGridArr;
+    public Dictionary<int, int[][]> heroQaulityColor;
+    public int[][] seeArr;
+    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;
+
+
+        var config = FuncConfigConfig.Get("HeroAppear");
+        xbGridArr = JsonMapper.ToObject<int[]>(config.Numerical1);
+        heroQaulityColor = ConfigParse.ParseIntArray2Dict(config.Numerical2);
+        seeArr = JsonMapper.ToObject<int[][]>(config.Numerical3);
+
+        InitRedPointId();
+    }
+
+    public void SetheroQaulityColor(GradientText text, int qaulity)
+    {
+        if (!heroQaulityColor.TryGetValue(qaulity, out var colors)) return;
+        if (colors?.Length < 2) return;
+        text.SetVerticalGradient(ParseColor32(colors[0]), ParseColor32(colors[1]));
+    }
+
+    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;
+    }
+
+    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()
+    {
+        isSendFirst = true;
+        starHeroIndexDict.Clear();
+        starFreeAwardDict.Clear();
+        callHeroIndexDict.Clear();
+    }
+
+    private void OnPlayerLoginOk()
+    {
+        TryPopWin();
+    }
+
+    private void OnFuncStateChangeEvent(int obj)
+    {
+        if (obj != (int)FuncOpenEnum.HeroDebut)
+            return;
+        TryPopWin();
+    }
+    public readonly int sendRankType = 6;
+    public int loadRankType => actNum * 1000 + sendRankType;
+    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
+    public const int activityID = (int)NewDayActivityID.HeroDebutAct;
+    public static OperationType operaType = OperationType.HeroDebut;
+    public Redpoint redPoint = new Redpoint(MainRedDot.HeroDebutRepoint);
+
+    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 = 10;
+    public event Action<int> onStateUpdate;
+
+    private void OperationTimeUpdateEvent(OperationType type)
+    {
+        if (type == operaType)
+        {
+            if (UIManager.Instance.IsOpened<HeroDebutPopWin>())
+                UIManager.Instance.CloseWindow<HeroDebutPopWin>();
+            if (UIManager.Instance.IsOpened<HeroDebutWin>())
+                UIManager.Instance.CloseWindow<HeroDebutWin>();
+            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<HeroDebutPopWin>())
+                UIManager.Instance.CloseWindow<HeroDebutPopWin>();
+            if (UIManager.Instance.IsOpened<HeroDebutWin>())
+                UIManager.Instance.CloseWindow<HeroDebutWin>();
+            UpdateRedpoint();
+        }
+    }
+    private void OperationAdvanceEvent(OperationType type)
+    {
+        if (type == operaType)
+        {
+            onStateUpdate?.Invoke(activityID);
+            UpdateRedpoint();
+        }
+    }
+
+    public OperationHeroAppearInfo GetOperationHeroAppearInfo()
+    {
+        OperationTimeHepler.Instance.TryGetOperation(operaType, out OperationHeroAppearInfo act);
+        return act;
+    }
+
+    public void SetHeroSquareIcon(ImageEx image, string name)
+    {
+        var sprite = UILoader.LoadSprite("HeroHead", name);
+        if (sprite != null)
+        {
+            image.overrideSprite = sprite;
+            return;
+        }
+
+        image.SetSprite("herohead_default");
+    }
+
+    public void GetActTimeStr(TextEx timeText, string key = "TimeRush05")
+    {
+        var act = GetOperationHeroAppearInfo();
+        if (act == null)
+        {
+            timeText.text = Language.Get("OSActivity6");
+            return;
+        }
+        timeText.text = Language.Get(key, TimeUtility.SecondsToShortDHMS(act.GetResetSurplusTime()));
+    }
+
+    public void SetGradientTextColor(GradientText text, int[][] colors)
+    {
+        if (colors?.Length < 4) return;
+        text.topLeftColor = ParseColor32(colors[0]);
+        text.topRightColor = ParseColor32(colors[1]);
+        text.bottomLeftColor = ParseColor32(colors[2]);
+        text.bottomRightColor = ParseColor32(colors[3]);
+        text.SetVerticesDirty();
+    }
+
+    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 int GetDefaultSkinID(int heroID)
+    {
+        HeroConfig heroConfig = HeroConfig.Get(heroID);
+        if (heroConfig == null || heroConfig.SkinIDList.IsNullOrEmpty()) return 0;
+        return heroConfig.SkinIDList[0];
+    }
+
+    public bool IsHeroDebutOpen()
+    {
+        if (!IsOpen) return false;
+        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.HeroDebut)) return false;
+        return true;
+    }
+
+
+    public int GetHeroIdIndex(int cfgID, int heroID)
+    {
+        var config = ActHeroAppearConfig.Get(cfgID);
+        if (config == null) return 0;
+
+        var heroArr = config.ActHeroIDList;
+        if (heroArr.IsNullOrEmpty()) return 0;
+
+        int index = Array.IndexOf(heroArr, heroID);
+        return index;
+    }
+
+
+
+    public event Action OnNowCallChooseHeroIDChangeEvent;
+    private int m_heroAppearActNum = 0;
+    public int nowCallChooseHeroID
+    {
+        get { return m_heroAppearActNum; }
+        set
+        {
+            if (m_heroAppearActNum == value) return;
+            m_heroAppearActNum = value;
+            OnNowCallChooseHeroIDChangeEvent?.Invoke();
+        }
+    }
+    public event Action<int> OnUpdateHeroAppearPlayerInfoEvent;
+    public void UpdateHeroAppearPlayerInfo(HAA22_tagSCActHeroAppearPlayerInfo vNetData)
+    {
+        if (vNetData == null) return;
+        int actNum = vNetData.ActNum;
+        starHeroIndexDict[actNum] = vNetData.StarHeroIndex;
+        callHeroIndexDict[actNum] = vNetData.CallHeroIndex;
+
+        if (!starFreeAwardDict.TryGetValue(actNum, out var dict))
+        {
+            dict = new Dictionary<int, uint>();
+            starFreeAwardDict[actNum] = dict;
+        }
+        dict[vNetData.StarHeroIndex] = vNetData.StarFreeAward;
+        UpdateRedpoint();
+        OnUpdateHeroAppearPlayerInfoEvent?.Invoke(actNum);
+    }
+
+    public void SendHeroAppearStarHeroSelect(int actNum, int starHeroIndex)
+    {
+        var pack = new CAA01_tagCSActHeroAppearStarHeroSelect();
+        pack.ActNum = (byte)actNum;                 // 娲诲姩缂栧彿
+        pack.StarHeroIndex = (byte)starHeroIndex;   // 鍗囨槦璁″垝閫夋嫨鐨勬灏咺D绱㈠紩
+        GameNetSystem.Instance.SendInfo(pack);
+    }
+
+    public void SnedHeroAppearCallHeroSelect(int actNum, int callHeroIndex)
+    {
+        var pack = new CAA02_tagCSActHeroAppearCallHeroSelect();
+        pack.ActNum = (byte)actNum;                 // 娲诲姩缂栧彿
+        pack.CallHeroIndex = (byte)callHeroIndex;   // 鎷涘嫙閫夋嫨鐨勬灏咺D绱㈠紩
+        GameNetSystem.Instance.SendInfo(pack);
+    }
+
+    public void SendGetStarReward()
+    {
+        var pack = new CA504_tagCMPlayerGetReward();
+        pack.RewardType = 10;
+        pack.DataEx = (uint)actNum;
+        GameNetSystem.Instance.SendInfo(pack);
+    }
+
+    #region 绾㈢偣
+    public int GetRedPointId(HeroDebutRedPointType type)
+    {
+        return MainRedDot.HeroDebutRepoint * 10 + (int)type;
+    }
+    public Redpoint checkInRedpoint;
+    public Redpoint starUpRedpoint;
+    public Redpoint shopRedpoint;
+    public Redpoint giftRedpoint;
+    public void InitRedPointId()
+    {
+        checkInRedpoint ??= new Redpoint(MainRedDot.HeroDebutRepoint, GetRedPointId(HeroDebutRedPointType.CheckIn));
+        starUpRedpoint ??= new Redpoint(MainRedDot.HeroDebutRepoint, GetRedPointId(HeroDebutRedPointType.StarUp));
+        shopRedpoint ??= new Redpoint(MainRedDot.HeroDebutRepoint, GetRedPointId(HeroDebutRedPointType.Shop));
+        giftRedpoint ??= new Redpoint(MainRedDot.HeroDebutRepoint, GetRedPointId(HeroDebutRedPointType.Gift));
+    }
+
+    public void UpdateRedpoint()
+    {
+        redPoint.state = RedPointState.None;
+        checkInRedpoint.state = RedPointState.None;
+        starUpRedpoint.state = RedPointState.None;
+        shopRedpoint.state = RedPointState.None;
+        giftRedpoint.state = RedPointState.None;
+
+        if (!IsHeroDebutOpen()) return;
+
+        if (HasCheckInCanHave()) //绛惧埌璧犵ぜ 
+        {
+            checkInRedpoint.state = RedPointState.Simple;
+        }
+
+        if (HasStarUpCanHave())//鏄熺骇鎻愬崌 
+        {
+            starUpRedpoint.state = RedPointState.Simple;
+        }
+
+        //鍏戞崲鍟嗗簵姣忓ぉ0鐐规樉绀虹孩鐐癸紝鐐瑰嚮杩涘叆涓�娆$晫闈㈠悗娑堝け
+        if (!IsShopVisitedToday) //鍏戞崲鍟嗗簵
+        {
+            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 $"HeroDebutManager_PopTimeData_{PlayerDatas.Instance.PlayerId}"; } }
+
+    private int LoadPopTimeData()
+    {
+        return LocalSave.GetInt(PopTimeDataKey);
+    }
+
+    public void SavePopTimeData()
+    {
+        LocalSave.SetInt(PopTimeDataKey, TimeUtility.AllSeconds);
+    }
+
+    private void TryPopWin()
+    {
+        if (!IsHeroDebutOpen()) return;
+        if (!IsTodayPop) return;
+        if (UIManager.Instance.IsOpened<HeroDebutPopWin>()) return;
+        if (UIManager.Instance.IsOpened<HeroDebutWin>()) return;
+        PopupWindowsProcessor.Instance.Add("HeroDebutPopWin");
+    }
+    #endregion
+
+    #region 绛惧埌
+    private int GetNowDayNum()
+    {
+        var act = GetOperationHeroAppearInfo();
+        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)
+    {
+        var act = GetOperationHeroAppearInfo();
+        if (act == null) return 0;
+
+        int actType = act.ActType;
+        if (GeneralActInfoManager.Instance.IsDaySigned(actType, actNum, gridDayNum)) return 2;
+        if (IsCheckInGridUnlock(gridDayNum)) return 1;
+        return 0;
+    }
+
+    public void SendGetCheckInReward()
+    {
+        var act = GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        int actType = act.ActType;
+        GeneralActInfoManager.Instance.SendGetSignReward(actType, actNum);
+    }
+
+    public bool HasCheckInCanHave()
+    {
+        var act = GetOperationHeroAppearInfo();
+        if (act == null) return false;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) 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;
+    }
+    #endregion
+
+    #region 鍗囨槦璁″垝
+
+    //<娲诲姩缂栧彿,鍗囨槦璁″垝閫夋嫨鐨勬灏咺D绱㈠紩>
+    public Dictionary<int, int> starHeroIndexDict = new();
+
+    //<娲诲姩缂栧彿,<鍗囨槦璁″垝閫夋嫨鐨勬灏咺D绱㈠紩,鍗囨槦璁″垝鍏嶈垂濂栧姳璁板綍>>
+    public Dictionary<int, Dictionary<int, uint>> starFreeAwardDict = new();
+
+    /// <summary>
+    /// 褰撳墠鍗囨槦璁″垝閫変腑鐨勬灏咺D
+    /// </summary>
+    public int GetCurrentDisplayStarUpHeroId()
+    {
+        var act = GetOperationHeroAppearInfo();
+        if (act == null) return 0;
+        if (!starHeroIndexDict.TryGetValue(actNum, out int index)) return 0;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null || config.ActHeroIDList?.Length <= index) return 0;
+
+        return config.ActHeroIDList[index];
+    }
+
+    private Dictionary<int, Dictionary<int, int[][]>> showHeroGiftItemInfoDict = new();
+    public bool TryGetStarUpAwardArr(int id, int heroID, out int[][] arr)
+    {
+        arr = null;
+        var config = ActHeroAppearStarConfig.Get(id);
+        if (config == null) return false;
+
+        var ctgConfig = CTGConfig.Get(config.StarGiftCTGID);
+        if (ctgConfig == null) return false;
+
+        if (!showHeroGiftItemInfoDict.TryGetValue(id, out var dict))
+        {
+            dict = new Dictionary<int, int[][]>();
+            showHeroGiftItemInfoDict[id] = dict;
+        }
+
+        if (!dict.TryGetValue(heroID, out arr))
+        {
+            // 濡傛灉缂撳瓨閲屾病鏈夊綋鍓嶆灏嗙殑鏁版嵁锛屾墠杩涜瑙f瀽
+            var giftdict = ConfigParse.ParseIntArray2Dict(config.HeroGiftItemInfo);
+            int[][] ctgArray = ctgConfig.GainItemList;
+
+            foreach (var kvp in giftdict)
+            {
+                int hId = kvp.Key;
+                int[][] hGift = kvp.Value ?? Array.Empty<int[]>();
+                dict[hId] = hGift.Concat(ctgArray).ToArray();
+            }
+
+            // 濡傛灉閬嶅巻瀹屽彂鐜伴厤琛ㄩ噷鏍规湰娌℃湁杩欎釜 heroID
+            if (!dict.TryGetValue(heroID, out arr))
+            {
+                arr = ctgArray;
+                dict[heroID] = arr;
+            }
+        }
+
+        return true;
+    }
+
+    /// <summary>
+    /// 0 - 鏈В閿� 1 - 鍙鍙� 2 - 宸查鍙�
+    /// </summary>
+    public int GetStarUpFreeState(int id)
+    {
+        var config = ActHeroAppearStarConfig.Get(id);
+        if (config == null) return 0;
+
+        int heroId = GetCurrentDisplayStarUpHeroId();
+        var heroConfig = HeroConfig.Get(heroId);
+        if (heroConfig == null) return 0;
+
+        // 娌¤幏寰楁灏嗘湰浣撲笉鍙鍙�
+        if (!HeroManager.Instance.HasHero(heroId))return 0;
+        
+        if (!starHeroIndexDict.TryGetValue(actNum, out int index)) return 0;
+        if (IsStarUpFreeHave(index, config.AwardIndex)) return 2;
+        if (IsHeroStarCntOk(heroConfig.HeroID, config.NeedStar)) return 1;
+        return 0;
+    }
+
+    private bool IsStarUpFreeHave(int starHeroIndex, int awardIndex)
+    {
+        if (!starFreeAwardDict.TryGetValue(actNum, out var dict)) return false;
+        if (!dict.TryGetValue(starHeroIndex, out uint freeAward)) return false;
+        return ((freeAward >> awardIndex) & 1u) == 1u;
+    }
+
+    public bool IsHeroStarCntOk(int heroId, int needStar)
+    {
+        return GetNowHeroMaxStarCnt(heroId) >= needStar;
+    }
+
+    public int GetNowHeroMaxStarCnt(int heroId)
+    {
+        int res = 0;
+        foreach (var item in HeroManager.Instance.GetHeroList())
+        {
+            if (item == null) continue;
+            if (item.heroId == heroId)
+            {
+                if (res < item.heroStar)
+                    res = item.heroStar;
+            }
+        }
+        return res;
+    }
+
+    public bool TryGetStarUpStateIndex(int starGiftTempID, int tarState, out int index)
+    {
+        index = 0;
+        var list = ActHeroAppearStarConfig.GetAwardIndexSortList(starGiftTempID);
+        if (list == null) return false;
+
+        for (int i = 0; i < list.Count; i++)
+        {
+            var awardIndex = list[i];
+            var config = ActHeroAppearStarConfig.GetConfig(starGiftTempID, awardIndex);
+            if (config == null) continue;
+
+            int state = GetStarUpFreeState(config.ID);
+            if (state == tarState)
+            {
+                index = i;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public int GetStarUpJumpIndex(int starGiftTempID)
+    {
+        // 浼樺厛鏌ユ壘鍙鍙栫殑濂栧姳
+        if (TryGetStarUpStateIndex(starGiftTempID, 1, out int index)) return index;
+
+        // 鑻ユ病鏈夊彲棰嗗彇鐨勶紝鍒欐煡鎵炬湭杈惧埌鏉′欢鐨勫鍔�
+        if (TryGetStarUpStateIndex(starGiftTempID, 0, out index)) return index;
+
+        // 閮芥病鏈�
+        return 0;
+    }
+
+    public bool HasStarUpCanHave()
+    {
+        var act = GetOperationHeroAppearInfo();
+        if (act == null) return false;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return false;
+
+        int starGiftTempID = config.StarGiftTempID;
+        return TryGetStarUpStateIndex(starGiftTempID, 1, out _);
+    }
+    #endregion
+
+    #region 鍏戞崲鍟嗗簵
+
+
+    private string ShopVisitTimeDataKey { get { return $"HeroDebutManager_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;
+        }
+    }
+    #endregion
+
+    #region 鐨囨潈绀煎寘
+    //娌″敭缃�
+    public bool IsCanBuyToday(int ctgID)
+    {
+        CTGConfig config = CTGConfig.Get(ctgID);
+        if (config == null) return false;
+        if (!RechargeManager.Instance.TryGetRechargeCount(ctgID, out var rechargeCount)) return false;
+
+        if (config.DailyBuyCount == 0) return true;
+        return rechargeCount.todayCount < config.DailyBuyCount;
+    }
+
+    public bool IsNoSellOutCTGID(int ctgID)
+    {
+        CTGConfig config = CTGConfig.Get(ctgID);
+        if (config == null) return false;
+        if (!RechargeManager.Instance.TryGetRechargeCount(ctgID, out var rechargeCount)) return false;
+        return rechargeCount.totalCount < config.TotalBuyCount;
+    }
+
+    // 鍏嶈垂鍟嗗搧
+    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<HeroDebutGiftItem> GetGiftItemList(bool isSort = false)
+    {
+        var act = GetOperationHeroAppearInfo();
+        if (act == null) return null;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return null;
+
+        List<HeroDebutGiftItem> res = new List<HeroDebutGiftItem>();
+
+        var list = StoreModel.Instance.storeTypeDict[config.GiftShopType];
+        if (!list.IsNullOrEmpty())
+        {
+            for (int i = 0; i < list.Count; i++)
+            {
+                var item = list[i];
+                if (item.storeConfig == null)
+                    continue;
+                res.Add(new HeroDebutGiftItem
+                {
+                    type = 0,
+                    id = item.storeConfig.ID,
+                });
+            }
+        }
+
+        if (config.GiftCTGIDList != null)
+        {
+            for (int i = 0; i < config.GiftCTGIDList.Length; i++)
+            {
+                var item = config.GiftCTGIDList[i];
+                res.Add(new HeroDebutGiftItem
+                {
+                    type = 1,
+                    id = item,
+                });
+            }
+        }
+
+        if (isSort)
+        {
+            res = res.OrderBy(item =>
+            {
+                bool isCanBuy = item.type == 0 ? IsNoSellOutShopID(item.id) : IsCanBuyToday(item.id);
+                return !isCanBuy;
+            })
+            .ThenBy(item => item.type)
+            .ThenBy(item => item.id)
+            .ToList();
+        }
+
+        return res;
+    }
+
+    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;
+            }
+        }
+        return false;
+    }
+
+    #endregion
+    #region 鎷涘嫙
+    public int ToInt(OperationDate date)
+    {
+        return date.year * 10000 + date.month * 100 + date.day;
+    }
+    private string GetCallSkipKey(int cfgID, OperationDate startDate, OperationDate endDate)
+    {
+        return string.Concat("HeroDebutManager_CallSkip_", cfgID, ToInt(startDate), ToInt(endDate), PlayerDatas.Instance.PlayerId);
+    }
+
+    public bool LoadCallSkipData(int cfgID, OperationDate startDate, OperationDate endDate)
+    {
+        return LocalSave.GetBool(GetCallSkipKey(cfgID, startDate, endDate));
+    }
+
+    public void SaveCallSkipData(int cfgID, OperationDate startDate, OperationDate endDate, bool value)
+    {
+        LocalSave.SetBool(GetCallSkipKey(cfgID, startDate, endDate), value);
+    }
+
+    //<娲诲姩缂栧彿,鎷涘嫙閫夋嫨鐨勬灏咺D绱㈠紩>
+    public Dictionary<int, int> callHeroIndexDict = new();
+
+    /// <summary>
+    /// 褰撳墠鎷涘嫙閫変腑鐨勬灏咺D
+    /// </summary>
+    public int GetCurrentDisplayCallHeroId()
+    {
+        var act = GetOperationHeroAppearInfo();
+        if (act == null) return 0;
+        if (!callHeroIndexDict.TryGetValue(actNum, out int index)) return 0;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null || config.ActHeroIDList?.Length <= index) return 0;
+
+        return config.ActHeroIDList[index];
+    }
+
+
+    #endregion
+
+    #region 鏃惰鐗瑰崠
+
+    public event Action OnCurrentChooseSkinIDChangeEevent;
+    private int m_currentChooseSkinID = 0;
+
+    public int currentChooseSkinID
+    {
+        get
+        {
+            return m_currentChooseSkinID;
+        }
+        set
+        {
+            if (m_currentChooseSkinID == value) return;
+            m_currentChooseSkinID = value;
+            OnCurrentChooseSkinIDChangeEevent?.Invoke();
+        }
+    }
+
+    /// <summary>
+    /// 閫氳繃skinID鑾峰彇瀵瑰簲鐨刪eroID
+    /// </summary>
+    public int GetHeroIDBySkinID(int skinID)
+    {
+        foreach (var heroConfig in HeroConfig.GetValues())
+        {
+            if (heroConfig.SkinIDList != null && heroConfig.SkinIDList.Contains(skinID))
+            {
+                return heroConfig.HeroID;
+            }
+        }
+        return 0;
+    }
+
+    /// <summary>
+    /// 鑾峰彇skinID鍦℉eroConfig.SkinIDList涓殑绱㈠紩
+    /// </summary>
+    public int GetSkinIndexInHeroConfig(int heroID, int skinID)
+    {
+        var heroConfig = HeroConfig.Get(heroID);
+        if (heroConfig?.SkinIDList == null) return int.MaxValue;
+
+        for (int i = 0; i < heroConfig.SkinIDList.Length; i++)
+        {
+            if (heroConfig.SkinIDList[i] == skinID)
+                return i;
+        }
+        return int.MaxValue;
+    }
+
+    //<skinID,ctgID>
+    Dictionary<int, int> ctgDict = new();
+    public int GetCtgIDBySkinID(int skinID)
+    {
+        if (ctgDict.IsNullOrEmpty())
+        {
+            GetSkinIDToCtgIDDict();
+        }
+
+        int ctgID;
+        ctgDict.TryGetValue(skinID, out ctgID);
+        return ctgID;
+    }
+
+    Dictionary<int, int> GetSkinIDToCtgIDDict()
+    {
+        if (!ctgDict.IsNullOrEmpty())
+        {
+            return ctgDict;
+        }
+
+        foreach (var config in ActHeroAppearConfig.GetValues())
+        {
+            if (config == null || config.SkinCTGIDList == null) return null;
+
+            for (int i = 0; i < config.SkinCTGIDList.Length; i++)
+            {
+                var ctgID = config.SkinCTGIDList[i];
+                var ctgConfig = CTGConfig.Get(ctgID);
+                if (ctgConfig == null || ctgConfig.GainItemList == null) continue;
+
+                for (int j = 0; j < ctgConfig.GainItemList.Length; j++)
+                {
+                    var itemID = ctgConfig.GainItemList[j][0];
+                    var itemConfig = ItemConfig.Get(itemID);
+
+                    if (itemConfig == null) continue;
+                    if (!HeroSkinAttrConfig.TryGetSkinIDByItemID(itemID, out var skinID)) continue;
+                    if (ctgDict.ContainsKey(skinID)) continue;
+                    ctgDict[skinID] = ctgID;
+                }
+            }
+        }
+
+        return ctgDict;
+    }
+
+    public bool HasItemInSkinCTGIDList(int cfgID, int findItemID)
+    {
+        var config = ActHeroAppearConfig.Get(cfgID);
+        if (config == null || config.SkinCTGIDList == null) return false;
+
+        for (int i = 0; i < config.SkinCTGIDList.Length; i++)
+        {
+            var ctgID = config.SkinCTGIDList[i];
+            var ctgConfig = CTGConfig.Get(ctgID);
+            if (ctgConfig == null || ctgConfig.GainItemList == null) continue;
+
+            for (int j = 0; j < ctgConfig.GainItemList.Length; j++)
+            {
+                var itemID = ctgConfig.GainItemList[j][0];
+                if (itemID == findItemID) return true;
+            }
+        }
+        return false;
+    }
+
+
+    public List<int> GetSkinIDList(int cfgID, int heroID, int mainSkinID)
+    {
+        var config = ActHeroAppearConfig.Get(cfgID);
+        if (config == null || config.SkinCTGIDList == null) return null;
+
+        var res = new List<int>();
+        for (int i = 0; i < config.SkinCTGIDList.Length; i++)
+        {
+            var ctgID = config.SkinCTGIDList[i];
+            var ctgConfig = CTGConfig.Get(ctgID);
+            if (ctgConfig == null || ctgConfig.GainItemList == null) continue;
+
+            for (int j = 0; j < ctgConfig.GainItemList.Length; j++)
+            {
+                var itemID = ctgConfig.GainItemList[j][0];
+                var itemConfig = ItemConfig.Get(itemID);
+
+                if (itemConfig == null) continue;
+                if (!HeroSkinAttrConfig.TryGetSkinIDByItemID(itemID, out var skinID)) continue;
+                if (res.Contains(skinID)) continue;
+
+                res.Add(skinID);
+            }
+        }
+        // 鑷畾涔夋帓搴�
+        res.Sort((a, b) =>
+        {
+            // 1. 鍒ゆ柇鏄惁鏄紶鍏eroID鐨勭毊鑲わ紝浼樺厛鎺掑墠闈�
+            int heroIDA = GetHeroIDBySkinID(a);
+            int heroIDB = GetHeroIDBySkinID(b);
+
+            bool isPriorityA = (heroIDA == heroID);
+            bool isPriorityB = (heroIDB == heroID);
+
+            if (isPriorityA != isPriorityB)
+                return isPriorityA ? -1 : 1;
+
+            // 2. 鐩稿悓姝﹀皢鐨勫涓毊鑲よ繛缁尐鍦ㄤ竴璧�
+            if (heroIDA != heroIDB)
+                return heroIDA.CompareTo(heroIDB);
+
+            // 3. 濡傛灉heroid鐩稿悓锛屽拰MainSkinID鐩稿悓鐨勬帓鍦ㄦ渶鍓嶉潰
+            if (a == mainSkinID) return -1;
+            if (b == mainSkinID) return 1;
+
+            // 4. 鍏朵粬鎸塖kinIDList绱㈠紩鎺掑簭
+            int indexA = GetSkinIndexInHeroConfig(heroIDA, a);
+            int indexB = GetSkinIndexInHeroConfig(heroIDB, b);
+
+            return indexA.CompareTo(indexB);
+        });
+        return res;
+    }
+
+    #endregion
+
+    #region 鑾峰璁板綍
+    public static readonly int RecordType = 311;
+
+    public void SendViewGameRecPack(int treasureType)
+    {
+        CA008_tagCSViewGameRec pack = new CA008_tagCSViewGameRec();
+        pack.RecType = (ushort)RecordType;
+        pack.RecID = (uint)treasureType;
+        GameNetSystem.Instance.SendInfo(pack);
+    }
+
+    public bool isSendFirst = true;
+
+    List<HeroDebutGameRec> gameRecDict = new();
+
+    public List<HeroDebutGameRec> GetGameRecList()
+    {
+        return gameRecDict;
+    }
+    public List<HeroDebutGameRec> GetLastFourRecords()
+    {
+        if (gameRecDict == null || gameRecDict.Count == 0) return new List<HeroDebutGameRec>();
+
+        int count = gameRecDict.Count;
+        int takeCount = Math.Min(4, count);
+        return gameRecDict.GetRange(count - takeCount, takeCount);
+    }
+
+    public event Action OnUpdateGameRecInfo;
+    public void UpdateGameRecInfo(HA009_tagSCGameRecInfo vNetData)
+    {
+
+        var act = GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        int treasureType = config.ActTreasureType;
+        if (vNetData.RecType != RecordType || treasureType != (int)vNetData.RecID) return;
+
+        if (vNetData.RecList.IsNullOrEmpty()) return;
+
+        if (isSendFirst)
+        {
+            gameRecDict.Clear();
+        }
+
+        foreach (var rec in vNetData.RecList)
+        {
+            try
+            {
+                var playerName = JsonMapper.ToObject(rec.UserData)["Name"].ToString();
+                var arenaGameRec = new HeroDebutGameRec
+                {
+                    Time = (int)rec.Time,
+                    ItemID = (int)rec.Value1,
+                    ItemCount = rec.Value2,
+                    PlayerID = (int)rec.Value3,
+                    ServerID = (int)rec.Value4,
+                    PlayerName = playerName,
+                };
+                gameRecDict.Add(arenaGameRec);
+            }
+            catch (Exception ex)
+            {
+                Debug.LogError($"JSON瑙f瀽閿欒: {ex.Message}, UserData: {rec.UserData}");
+                continue;
+            }
+        }
+
+        if (isSendFirst)
+        {
+            isSendFirst = !isSendFirst;
+            gameRecDict.Sort((x, y) => x.Time.CompareTo(y.Time));
+        }
+
+        OnUpdateGameRecInfo?.Invoke();
+
+    }
+
+    #endregion
+}
+
+
+public class HeroDebutGiftItem
+{
+    public int type;//0 鍟嗗簵id 1 鍏呭�糹d
+    public int id;
+}
+
+public enum HeroDebutRedPointType
+{
+    CheckIn = 1,
+    StarUp = 2,
+    Shop = 3,
+    Gift = 4,
+}
+
+public class HeroDebutGameRec
+{
+    public int Time;
+    public int ItemID;
+    public long ItemCount;
+    public int PlayerID;
+    public int ServerID;
+    public string PlayerName;
+}
\ No newline at end of file
diff --git a/Main/System/HeroDebut/HeroDebutManager.cs.meta b/Main/System/HeroDebut/HeroDebutManager.cs.meta
new file mode 100644
index 0000000..c66eb0a
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f5c5e5d4f591d88438fe2de638524e94
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutPopWin.cs b/Main/System/HeroDebut/HeroDebutPopWin.cs
new file mode 100644
index 0000000..dc25cdf
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutPopWin.cs
@@ -0,0 +1,96 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+public class HeroDebutPopWin : UIBase
+{
+    [SerializeField] ImageEx bgImage;
+    [SerializeField] UIHeroController rolelhShow;
+    [SerializeField] ImageEx qaulityBgImage;
+    [SerializeField] ImageEx qaulityImage;
+    [SerializeField] ButtonEx goButton;
+    [SerializeField] ImageEx titleBgImage;
+    [SerializeField] ImageEx titleImage;
+    [SerializeField] ImageEx infoBgImage;
+    [SerializeField] UIEffectPlayer uiEffectPlayer;
+    [SerializeField] TextEx infoText;
+    [SerializeField] TextEx timeText;
+    [SerializeField] Toggle todayPopToggle;
+    [SerializeField] ButtonEx closeButton;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    protected override void InitComponent()
+    {
+        closeButton.SetListener(CloseWindow);
+        goButton.SetListener(() =>
+        {
+            UIManager.Instance.CloseWindow<HeroDebutPopWin>();
+            if (!UIManager.Instance.IsOpened<HeroDebutWin>())
+                UIManager.Instance.OpenWindow<HeroDebutWin>();
+        });
+        todayPopToggle.AddListener((bool value) =>
+        {
+            if (value)
+                manager.SavePopTimeData();
+        });
+    }
+
+    protected override void OnPreOpen()
+    {
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+    }
+
+    private void OnSecondEvent()
+    {
+        manager.GetActTimeStr(timeText, "HeroDebutPop02");
+    }
+
+    private void Display()
+    {
+        uiEffectPlayer.Stop();
+        todayPopToggle.isOn = !manager.IsTodayPop;
+
+        int heroID = manager.GetCurrentDisplayCallHeroId();
+        var artConfig = ActHeroAppearArtConfig.Get(heroID);
+        if (artConfig == null) return;
+
+        var heroConfig = HeroConfig.Get(heroID);
+        if (heroConfig == null) return;
+
+        int skinID = manager.GetDefaultSkinID(heroID);
+        var skinConfig = HeroSkinConfig.Get(skinID);
+        if (skinConfig == null) return;
+
+        uiEffectPlayer.effectId = artConfig.PopInfoBgUIEffectId;
+        uiEffectPlayer.Play();
+
+        bgImage.SetSprite(artConfig.PopBgImage);
+        bgImage.SetNativeSize();
+
+        qaulityBgImage.SetSprite($"HeroDebutPopQaulityBG{heroConfig.Quality}");
+        qaulityBgImage.SetNativeSize();
+
+        qaulityImage.SetSprite($"HeroDebutPopQaulity{heroConfig.Quality}");
+        qaulityImage.SetNativeSize();
+
+        titleBgImage.SetSprite(artConfig.PopTitleBgImage);
+        titleBgImage.SetNativeSize();
+
+        titleImage.SetSprite(artConfig.PopTitleImage);
+        titleImage.SetNativeSize();
+
+        infoBgImage.SetSprite(artConfig.PopInfoBgImage);
+        infoBgImage.SetNativeSize();
+
+        infoText.text = artConfig.PopInfoText;
+        infoText.color = manager.ParseColor32(artConfig.PopInfoColor);
+
+        rolelhShow.Create(skinID, 1, motionName: "", isLh: true);
+
+        OnSecondEvent();
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutPopWin.cs.meta b/Main/System/HeroDebut/HeroDebutPopWin.cs.meta
new file mode 100644
index 0000000..1efcfe3
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutPopWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 24ad8ea9f5a40274bad405fecb092325
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutRankAwardCell.cs b/Main/System/HeroDebut/HeroDebutRankAwardCell.cs
new file mode 100644
index 0000000..0de8a09
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutRankAwardCell.cs
@@ -0,0 +1,45 @@
+using UnityEngine;
+
+public class HeroDebutRankAwardCell : CellView
+{
+    [SerializeField] ImageEx imgRank;
+    [SerializeField] TextEx txtRank;
+    [SerializeField] ItemCell[] itemCells;
+    public void Display(int rankA, int templateID)
+    {
+        var config = ActBillboardAwardConfig.GetConfig(templateID, rankA);
+        if (config == null) return;
+
+
+        if (rankA <= 3)
+        {
+            imgRank.SetActive(true);
+            txtRank.SetActive(false);
+            imgRank.SetSprite(StringUtility.Concat("Rank", rankA.ToString()));
+            txtRank.text = rankA.ToString();
+        }
+        else
+        {
+            imgRank.SetActive(false);
+            txtRank.SetActive(true);
+            txtRank.text = Language.Get("Arena15", rankA, config.RankB);
+        }
+
+        int[][] rewardArr = config.AwardItemList;
+        for (int i = 0; i < itemCells.Length; i++)
+        {
+            var itemCell = itemCells[i];
+            if (!rewardArr.IsNullOrEmpty() && i < rewardArr.Length)
+            {
+                int itemCellIndex = i;
+                itemCell.SetActive(true);
+                itemCell.Init(new ItemCellModel(rewardArr[i][0], true, rewardArr[i][1]));
+                itemCell.button.SetListener(() => ItemTipUtility.Show(rewardArr[itemCellIndex][0], true));
+            }
+            else
+            {
+                itemCell.SetActive(false);
+            }
+        }
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutRankAwardCell.cs.meta b/Main/System/HeroDebut/HeroDebutRankAwardCell.cs.meta
new file mode 100644
index 0000000..168761d
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutRankAwardCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3afacd7889426a94db84c1bc905ca6f2
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutRankCell.cs b/Main/System/HeroDebut/HeroDebutRankCell.cs
new file mode 100644
index 0000000..3c9a4ea
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutRankCell.cs
@@ -0,0 +1,76 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+public class HeroDebutRankCell : MonoBehaviour
+{
+    [SerializeField] AvatarCell avatarCell;
+    [SerializeField] Text rankText;
+    [SerializeField] Text rankValueText;    //鎺掑悕姣旇緝鍐呭
+    [SerializeField] Text nameText;
+    [SerializeField] OfficialTitleCell officialTitleCell;
+    [SerializeField] Button queryPlayerBtn; //鍚庣画娣诲姞鐐瑰嚮鏌ョ湅鐜╁璇︽儏
+
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    // rank 涓�0 浠h〃鐜╁鑷繁
+    public void Display(int rankType, int rank, string valueFormat)
+    {
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        int billTempID = config.BillTempID;
+        var awardConfig = ActBillboardAwardConfig.GetConfig(billTempID, rank);
+
+        RankData rankData = null;
+        int viewPlayerId = (int)PlayerDatas.Instance.baseData.PlayerID;
+        if (rank != 0)
+        {
+            rankData = RankModel.Instance.GetRankDataByRank(rankType, rank);
+        }
+        else
+        {
+            rankData = RankModel.Instance.GetMyRank(rankType);
+            if (rankData == null)
+            {
+                //鍙栫帺瀹惰嚜宸辩殑鏁版嵁
+                avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)PlayerDatas.Instance.baseData.PlayerID,
+                                                PlayerDatas.Instance.baseData.face,
+                                                PlayerDatas.Instance.baseData.facePic));
+                rankText.text = Language.Get("L1045");
+                rankValueText.text = awardConfig == null || awardConfig.NeedValue == 0 ? "0" : Language.Get("HeroDebut27", awardConfig.NeedValue);
+                nameText.text = PlayerDatas.Instance.baseData.PlayerName;
+                officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
+                return;
+            }
+            rank = rankData.rank;
+        }
+        if (rankData == null)
+        {
+            officialTitleCell.SetActive(false);
+            avatarCell.SetActive(false);
+            nameText.text = Language.Get("L1124");
+            rankValueText.text = awardConfig == null || awardConfig.NeedValue == 0 ? "0" : Language.Get("HeroDebut27", awardConfig.NeedValue);
+        }
+        else
+        {
+            officialTitleCell.SetActive(true);
+            officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2);
+            avatarCell.SetActive(true);
+            avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)rankData.id, (int)rankData.value3, (int)rankData.value4));
+            viewPlayerId = (int)rankData.id;
+            nameText.text = rankData.name1;
+            rankValueText.text = string.Format(valueFormat, UIHelper.ReplaceLargeNum(rankData.cmpValue));
+        }
+
+        rankText.text = rank.ToString();
+        if (queryPlayerBtn != null)
+        {
+            queryPlayerBtn.AddListener(() =>
+            {
+                AvatarHelper.TryViewOtherPlayerInfo(viewPlayerId);
+            });
+        }
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutRankCell.cs.meta b/Main/System/HeroDebut/HeroDebutRankCell.cs.meta
new file mode 100644
index 0000000..2ea81ae
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutRankCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fbdf6f5d48d9a404ba6e0f542c629ca5
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutRankTop3Cell.cs b/Main/System/HeroDebut/HeroDebutRankTop3Cell.cs
new file mode 100644
index 0000000..11b71d9
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutRankTop3Cell.cs
@@ -0,0 +1,47 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+public class HeroDebutRankTop3Cell : MonoBehaviour
+{
+    //[SerializeField] Model 鏄剧ずNPC 姝﹀皢妯″瀷
+    [SerializeField] Text rankValueText;    //鎺掑悕姣旇緝鍐呭
+    [SerializeField] Text nameText;
+    [SerializeField] OfficialTitleCell officialTitleCell;
+    [SerializeField] Button queryPlayerBtn; //鍚庣画娣诲姞鐐瑰嚮鏌ョ湅鐜╁璇︽儏
+    [SerializeField] HorseController model;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    public void Display(int rankType, int rank, string valueFormat = "{0}")
+    {
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        int billTempID = config.BillTempID;
+        var awardConfig = ActBillboardAwardConfig.GetConfig(billTempID, rank);
+
+
+        var rankData = RankModel.Instance.GetRankDataByRank(rankType, rank);
+        if (rankData == null)
+        {
+            rankValueText.text = awardConfig == null || awardConfig.NeedValue == 0 ? "0" : Language.Get("HeroDebut40", awardConfig.NeedValue);
+            nameText.text = Language.Get("L1124");
+            officialTitleCell.SetActive(false);
+            model.SetActive(false);
+            return;
+        }
+        officialTitleCell.SetActive(true);
+        rankValueText.text = string.Format(valueFormat, UIHelper.ReplaceLargeNum(rankData.cmpValue));
+        nameText.text = rankData.name1;
+        officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2);
+        model.SetActive(true);
+        model.Create(HorseManager.Instance.GetOtherPlayerHorseSkinID((int)rankData.value6), (int)rankData.value5, rank == 1 ? 1f : 0.8f);
+        queryPlayerBtn.SetListener(() =>
+        {
+            AvatarHelper.TryViewOtherPlayerInfo((int)rankData.id);
+        });
+    }
+
+
+}
diff --git a/Main/System/HeroDebut/HeroDebutRankTop3Cell.cs.meta b/Main/System/HeroDebut/HeroDebutRankTop3Cell.cs.meta
new file mode 100644
index 0000000..eacd8b8
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutRankTop3Cell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4c2c1678330ae2942ad512bb4b5dd76c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutRankWin.cs b/Main/System/HeroDebut/HeroDebutRankWin.cs
new file mode 100644
index 0000000..f35f885
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutRankWin.cs
@@ -0,0 +1,175 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class HeroDebutRankWin : FunctionsBaseWin
+{
+    [SerializeField] ButtonEx btnClose;
+    [SerializeField] RectTransform rankRect;
+    [SerializeField] RectTransform awardRect;
+    [SerializeField] TextEx timeText;
+
+
+
+    [Header("鎺掕")]
+    [SerializeField] ScrollerController rankScroller;
+    [SerializeField] List<HeroDebutRankTop3Cell> playerTop3Cells;
+    [SerializeField] HeroDebutRankCell myRankCell;
+    [HideInInspector] public string valueFormat = "{0}";
+    [Header("濂栧姳")]
+    // [SerializeField] TextEx txtCountdown;
+    [SerializeField] ScrollerController awardScroller;
+    [SerializeField] ImageEx heroImage;
+    [SerializeField] TextEx myRankNumText;
+    [SerializeField] TextEx myCallCntText;
+    [SerializeField] TextEx timeText1;
+
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    protected override void InitComponent()
+    {
+        base.InitComponent();
+        btnClose.SetListener(CloseWindow);
+    }
+
+    protected override void OnPreOpen()
+    {
+        base.OnPreOpen();
+        RankModel.Instance.ResetQueryParam();
+        RankModel.Instance.QueryRankByPage(manager.sendRankType, watchID: (int)PlayerDatas.Instance.baseData.PlayerID, groupValue1: manager.actNum);
+
+        RankModel.Instance.onRankRefresh += OnRankRefresh;
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        rankScroller.OnRefreshCell += OnRefreshCell;
+        awardScroller.OnRefreshCell += OnRefreshAwardCell;
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        base.OnPreClose();
+        RankModel.Instance.onRankRefresh -= OnRankRefresh;
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+        rankScroller.OnRefreshCell -= OnRefreshCell;
+        awardScroller.OnRefreshCell -= OnRefreshAwardCell;
+    }
+
+    void OnRankRefresh(int type)
+    {
+        RankRefresh();
+    }
+
+    void RankRefresh()
+    {
+        ShowTop3();
+        rankScroller.m_Scorller.RefreshActiveCellViews();
+        DisplayMyRank();
+        DisplayAwardMyRank();
+    }
+
+    void CreateRankScroller()
+    {
+        rankScroller.Refresh();
+        var cnt = RankModel.Instance.GetRankShowMaxCnt(manager.sendRankType);
+        for (int i = 3; i < cnt; i++)
+        {
+            rankScroller.AddCell(ScrollerDataType.Header, i);
+        }
+        rankScroller.Restart();
+    }
+
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell.GetComponent<HeroDebutRankCell>();
+        _cell.Display(manager.loadRankType, cell.index + 1, valueFormat);
+        RankModel.Instance.ListenRankPage(manager.sendRankType, cell.index, groupValue1: manager.actNum);
+    }
+
+    private void OnSecondEvent()
+    {
+        manager.GetActTimeStr(timeText);
+        manager.GetActTimeStr(timeText1);
+    }
+
+    protected override void OpenSubUIByTabIndex()
+    {
+        rankRect.SetActive(functionOrder == 0);
+        awardRect.SetActive(functionOrder == 1);
+        Display();
+    }
+
+    public void Display()
+    {
+        int heroID = manager.GetCurrentDisplayCallHeroId();
+        var artConfig = ActHeroAppearArtConfig.Get(heroID);
+        if (artConfig == null) return;
+
+        if (functionOrder == 0)
+        {
+            ShowTop3();
+            CreateRankScroller();
+            DisplayMyRank();
+        }
+        else
+        {
+            CreateAwardScroller();
+            heroImage.SetSprite(artConfig.RankAwardHeroImage);
+            heroImage.SetNativeSize();
+            DisplayAwardMyRank();
+        }
+        OnSecondEvent();
+    }
+
+    private void DisplayMyRank()
+    {
+        myRankCell.Display(manager.loadRankType, 0, valueFormat);
+    }
+
+    void ShowTop3()
+    {
+        for (int i = 0; i < playerTop3Cells.Count; i++)
+        {
+            playerTop3Cells[i].Display(manager.loadRankType, i + 1);
+        }
+    }
+
+    void DisplayAwardMyRank()
+    {
+
+        RankData rankData = RankModel.Instance.GetMyRank(manager.loadRankType);
+        if (rankData == null)
+        {
+            myRankNumText.text = Language.Get("L1045");
+            myCallCntText.text = "0";
+            return;
+        }
+        myRankNumText.text = Language.Get("WarlordPavilion12", rankData.rank);
+        myCallCntText.text = string.Format(valueFormat, UIHelper.ReplaceLargeNum(rankData.cmpValue));
+    }
+
+    int billTempID;
+    private void CreateAwardScroller()
+    {
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        billTempID = config.BillTempID;
+        var list = ActBillboardAwardConfig.GetRankASortList(billTempID);
+        if (list == null) return;
+
+        awardScroller.Refresh();
+        for (int i = 0; i < list.Count; i++)
+        {
+            awardScroller.AddCell(ScrollerDataType.Header, list[i]);
+        }
+        awardScroller.Restart();
+    }
+
+    private void OnRefreshAwardCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell.GetComponent<HeroDebutRankAwardCell>();
+        _cell?.Display(cell.index, billTempID);
+    }
+}
\ No newline at end of file
diff --git a/Main/System/HeroDebut/HeroDebutRankWin.cs.meta b/Main/System/HeroDebut/HeroDebutRankWin.cs.meta
new file mode 100644
index 0000000..41978b4
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutRankWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a81d546baaf89554eb10f8deaa384226
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutShopCell.cs b/Main/System/HeroDebut/HeroDebutShopCell.cs
new file mode 100644
index 0000000..5a5a9a3
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutShopCell.cs
@@ -0,0 +1,134 @@
+锘縰sing UnityEngine;
+using UnityEngine.UI;
+
+public class HeroDebutShopCell : 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;//鍞絼
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    public void Display(int index)
+    {
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        if (!StoreModel.Instance.storeTypeDict.TryGetValue(config.ExShopType, 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 == 2 ? Language.Get("storename10", storeData.storeConfig.UnlockValue) : string.Empty;
+
+        priceRect.SetActive(state != 2 && storeData.storeConfig.MoneyOriginal != 0);
+        priceRect1.SetActive(state != 2 && storeData.storeConfig.MoneyOriginal == 0);
+        freeText.SetActive(state == 2);
+        salePriceRect.SetActive(state != 2 && 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/HeroDebut/HeroDebutShopCell.cs.meta b/Main/System/HeroDebut/HeroDebutShopCell.cs.meta
new file mode 100644
index 0000000..4f515cb
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutShopCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 868584e8775d70b45a260329d5666b60
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutShopLineCell.cs b/Main/System/HeroDebut/HeroDebutShopLineCell.cs
new file mode 100644
index 0000000..12e096c
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutShopLineCell.cs
@@ -0,0 +1,30 @@
+锘縰sing UnityEngine;
+
+public class HeroDebutShopLineCell : CellView
+{
+    [SerializeField] HeroDebutShopCell[] storeCells;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    public void Display(int index)
+    {
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        if (!StoreModel.Instance.storeTypeDict.TryGetValue(config.ExShopType, 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/HeroDebut/HeroDebutShopLineCell.cs.meta b/Main/System/HeroDebut/HeroDebutShopLineCell.cs.meta
new file mode 100644
index 0000000..4e5f9dc
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutShopLineCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 13317ad05161a4047992bc2ea9471602
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutShopWin.cs b/Main/System/HeroDebut/HeroDebutShopWin.cs
new file mode 100644
index 0000000..534b3b7
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutShopWin.cs
@@ -0,0 +1,80 @@
+using UnityEngine;
+
+public class HeroDebutShopWin : UIBase
+{
+    [SerializeField] OwnItemCell ownItemCell;
+    [SerializeField] ButtonEx closeButton;
+    [SerializeField] TextEx timeText;
+    [SerializeField] ScrollerController scroller;
+    HeroDebutManager manager => HeroDebutManager.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)
+        {
+            HeroDebutManager.Instance.SaveShopVisitTimeData();
+            manager.UpdateRedpoint();
+        }
+
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        ownItemCell.itemID = config.ExShopCostItemID;
+        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 HeroDebutShopLineCell;
+        _cell.Display(cell.index);
+    }
+
+    private void OnSecondEvent()
+    {
+        manager.GetActTimeStr(timeText);
+    }
+
+    void CreateScroller()
+    {
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        if (!StoreModel.Instance.storeTypeDict.TryGetValue(config.ExShopType, 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/HeroDebut/HeroDebutShopWin.cs.meta b/Main/System/HeroDebut/HeroDebutShopWin.cs.meta
new file mode 100644
index 0000000..0907de5
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutShopWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 473e6aff97f65f44db8f1810ecf7a0f1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutSkinAwardCell.cs b/Main/System/HeroDebut/HeroDebutSkinAwardCell.cs
new file mode 100644
index 0000000..87ac4d9
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutSkinAwardCell.cs
@@ -0,0 +1,18 @@
+using UnityEngine;
+
+public class HeroDebutSkinAwardCell : CellView
+{
+    [SerializeField] ItemCell itemCell;
+    public void Display(int index, int[][] arr)
+    {
+        if (arr == null || arr.Length <= index) return;
+        int itemID = arr[index][0];
+        long itemCount = arr[index][1];
+        
+        itemCell.Init(new ItemCellModel(itemID, false, itemCount));
+        itemCell.button.AddListener(() =>
+        {
+            ItemTipUtility.Show(itemID);
+        });
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutSkinAwardCell.cs.meta b/Main/System/HeroDebut/HeroDebutSkinAwardCell.cs.meta
new file mode 100644
index 0000000..d31a52a
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutSkinAwardCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 31cefbc704fb50d4f863263aafa70814
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutSkinTabCell.cs b/Main/System/HeroDebut/HeroDebutSkinTabCell.cs
new file mode 100644
index 0000000..998d893
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutSkinTabCell.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class HeroDebutSkinTabCell : CellView
+{
+    [SerializeField] ImageEx tabBgImage;
+    [SerializeField] ButtonEx tabButton;
+    [SerializeField] RectTransform chooseRect;
+    [SerializeField] RectTransform maskRect;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    public void Display(int index, List<int> list)
+    {
+        if (list?.Count <= index) return;
+
+        var skinID = list[index];
+        var skinArtConfig = ActHeroAppearSkinArtConfig.Get(skinID);
+        if (skinArtConfig == null) return;
+
+        tabBgImage.SetSprite(skinArtConfig.TabInfoImage);
+        tabBgImage.SetNativeSize();
+        maskRect.SetActive(manager.currentChooseSkinID != skinID);
+        chooseRect.SetActive(manager.currentChooseSkinID == skinID);
+        tabButton.SetListener(() =>
+        {
+            manager.currentChooseSkinID = skinID;
+        });
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutSkinTabCell.cs.meta b/Main/System/HeroDebut/HeroDebutSkinTabCell.cs.meta
new file mode 100644
index 0000000..0407f69
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutSkinTabCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: de6e158685024444f9af2711cb4bce26
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutSkinWin.cs b/Main/System/HeroDebut/HeroDebutSkinWin.cs
new file mode 100644
index 0000000..8fc2731
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutSkinWin.cs
@@ -0,0 +1,229 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class HeroDebutSkinWin : UIBase
+{
+    [SerializeField] float modelScale = 1f;
+    [SerializeField] RawImage bgImage;
+    [SerializeField] ImageEx heroNameImage;
+    [SerializeField] ImageEx skinInfoImage;
+    [SerializeField] ImageEx awardBgImage;
+    [SerializeField] TextEx timeText;
+    [SerializeField] ButtonEx buyButton;
+    [SerializeField] ImageEx buyImage;
+    [SerializeField] ImageEx countryImage;
+    [SerializeField] TextEx buyText;
+    [SerializeField] ButtonEx closeButton;
+    [SerializeField] UIHeroController uiHeroController;
+    [SerializeField] UIHeroController lhController;
+    [SerializeField] ScrollerController awardScroller;
+    [SerializeField] ScrollerController tabScroller;
+    [SerializeField] Color numColor;
+    [SerializeField] TextEx[] wearAttrText;
+    [SerializeField] TextEx[] roleAttrText;
+    [SerializeField] ButtonEx infoButton;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    protected override void InitComponent()
+    {
+        closeButton.SetListener(CloseWindow);
+        infoButton.SetListener(() =>
+        {
+            int heroID = manager.GetHeroIDBySkinID(manager.currentChooseSkinID);
+            HeroUIManager.Instance.selectForPreviewHeroID = heroID;
+            HeroUIManager.Instance.selectSkinIndex = manager.GetSkinIndexInHeroConfig(heroID, manager.currentChooseSkinID);
+            UIManager.Instance.OpenWindow<HeroBestBaseWin>(1);
+        });
+    }
+
+    protected override void OnPreOpen()
+    {
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent;
+        awardScroller.OnRefreshCell += OnRefreshAwardCell;
+        tabScroller.OnRefreshCell += OnRefreshTabCell;
+        manager.OnCurrentChooseSkinIDChangeEevent += OnCurrentChooseSkinIDChange;
+        CreateTabScroller();
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+        RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent;
+        awardScroller.OnRefreshCell -= OnRefreshAwardCell;
+        tabScroller.OnRefreshCell -= OnRefreshTabCell;
+        manager.OnCurrentChooseSkinIDChangeEevent -= OnCurrentChooseSkinIDChange;
+    }
+
+    private void OnCurrentChooseSkinIDChange()
+    {
+        tabScroller.m_Scorller.RefreshActiveCellViews();
+        Display();
+    }
+
+    void OnRefreshTabCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as HeroDebutSkinTabCell;
+        _cell.Display(cell.index, skinIDList);
+    }
+
+    List<int> skinIDList;
+    void CreateTabScroller()
+    {
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        int heroID = manager.GetCurrentDisplayCallHeroId();
+        var artConfig = ActHeroAppearArtConfig.Get(heroID);
+        if (artConfig == null) return;
+
+        skinIDList = manager.GetSkinIDList(act.CfgID, heroID, artConfig.MainSkinID);
+        if (skinIDList.IsNullOrEmpty()) return;
+        manager.currentChooseSkinID = skinIDList[0];
+
+        tabScroller.Refresh();
+        for (int i = 0; i < skinIDList.Count; i++)
+        {
+            tabScroller.AddCell(ScrollerDataType.Header, i);
+        }
+        tabScroller.Restart();
+    }
+
+    int[][] arr = null;
+    void OnRefreshAwardCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as HeroDebutSkinAwardCell;
+        _cell.Display(cell.index, arr);
+    }
+
+    void CreateAwardScroller(int[][] sourceArr)
+    {
+        if (sourceArr == null) return;
+
+        // 1. 鑾峰彇宸叉嫢鏈夌殑 ID 闆嗗悎 (浣跨敤 LINQ 绠�娲佹槑浜�)
+        var ownedItems = HeroSkinAttrConfig.GetItemList();
+        var itemIds = ownedItems != null ? new HashSet<int>(ownedItems) : new HashSet<int>();
+
+        // 2. 杩囨护鎺� items 涓凡鏈夌殑椤癸紝骞剁洿鎺ヨ祴鍊肩粰鎴愬憳鍙橀噺
+        // arr[i][0] 鍋囪涓哄垽鏂槸鍚﹀瓨鍦ㄤ簬 items 涓殑 ID
+        this.arr = System.Array.FindAll(sourceArr, row => !itemIds.Contains(row[0]));
+
+        // 3. 鍒锋柊 UI
+        awardScroller.Refresh();
+        for (int i = 0; i < this.arr.Length; i++)
+        {
+            awardScroller.AddCell(ScrollerDataType.Header, i);
+        }
+        awardScroller.Restart();
+    }
+
+    private void OnSecondEvent()
+    {
+        manager.GetActTimeStr(timeText);
+    }
+
+    private void OnRechargeCountEvent(int obj)
+    {
+        Display();
+    }
+
+    public void Display()
+    {
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+
+        int heroID = manager.GetCurrentDisplayCallHeroId();
+        var artConfig = ActHeroAppearArtConfig.Get(heroID);
+        if (artConfig == null) return;
+
+        var heroConfig = HeroConfig.Get(heroID);
+        if (heroConfig == null) return;
+
+        int skinID = manager.currentChooseSkinID;
+        var skinArtConfig = ActHeroAppearSkinArtConfig.Get(skinID);
+        if (skinArtConfig == null) return;
+
+        var heroSkinAttrConfig = HeroSkinAttrConfig.Get(skinID);
+        if (heroSkinAttrConfig == null) return;
+        if (heroSkinAttrConfig.WearAttrIDList == null) return;
+        if (heroSkinAttrConfig.WearAttrValueList == null) return;
+        if (heroSkinAttrConfig.RoleAttrIDList == null) return;
+        if (heroSkinAttrConfig.RoleAttrValueList == null) return;
+
+        var skinIDList = manager.GetSkinIDList(act.CfgID, heroID, skinID);
+        if (skinIDList.IsNullOrEmpty()) return;
+
+        int ctgId = manager.GetCtgIDBySkinID(skinID);
+        var ctgConfig = CTGConfig.Get(ctgId);
+        if (ctgConfig == null) return;
+
+        if (!RechargeManager.Instance.TryGetOrderInfo(ctgId, out var orderConfig)) return;
+        if (!RechargeManager.Instance.TryGetRechargeCount(ctgId, out var rechargeCount)) return;
+        if (!RechargeManager.Instance.TryGetRechargeItem(ctgId, out var rechargeItemList)) return;
+
+        bgImage.SetTexture2D(skinArtConfig.BGImage);
+
+        heroNameImage.SetSprite(skinArtConfig.HeroNameImage);
+        heroNameImage.SetNativeSize();
+
+        skinInfoImage.SetSprite(skinArtConfig.SkinInfoImage);
+        skinInfoImage.SetNativeSize();
+
+        awardBgImage.SetSprite(skinArtConfig.AwardBGImage);
+        awardBgImage.SetNativeSize();
+
+        uiHeroController.Create(skinID, modelScale);
+        lhController.Create(skinID, 1, motionName: "", isLh: true);
+        countryImage.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
+        OnSecondEvent();
+
+        CreateAwardScroller(ctgConfig.GainItemList);
+
+        bool isCanBuy = manager.IsNoSellOutCTGID(ctgId);
+        //buyImage.gray = !isCanBuy;
+        buyText.text = !isCanBuy ? Language.Get("storename11") : Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderConfig.PayRMBNumOnSale));
+
+        buyButton.interactable = isCanBuy;
+        buyButton.SetListener(() =>
+        {
+            RechargeManager.Instance.CTG(ctgId);
+        });
+
+        for (int i = 0; i < wearAttrText.Length; i++)
+            SetAttrInfo(0, i, heroSkinAttrConfig, wearAttrText[i]);
+
+        for (int i = 0; i < roleAttrText.Length; i++)
+            SetAttrInfo(1, i, heroSkinAttrConfig, roleAttrText[i]);
+
+    }
+
+    // type 0 绌挎埓灞炴�у�� 1 涓诲叕灞炴��
+    public void SetAttrInfo(int type, int index, HeroSkinAttrConfig heroSkinAttrConfig, TextEx info)
+    {
+        if (heroSkinAttrConfig == null) return;
+
+        int[] arrID = type == 0 ? heroSkinAttrConfig.WearAttrIDList : heroSkinAttrConfig.RoleAttrIDList;
+        int[] arrValue = type == 0 ? heroSkinAttrConfig.WearAttrValueList : heroSkinAttrConfig.RoleAttrValueList;
+        if (arrID?.Length <= index || arrValue?.Length <= index)
+        {
+            info.text = string.Empty;
+            return;
+        }
+
+        info.text = GetFullDescription(arrID[index], arrValue[index]);
+    }
+
+    string GetFullDescription(int id, long value)
+    {
+        var config = PlayerPropertyConfig.Get(id);
+        if (config == null) return string.Empty;
+        return Language.Get("HeroDebut33", config.ShowName, PlayerPropertyConfig.GetValueDescription(id, value));
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutSkinWin.cs.meta b/Main/System/HeroDebut/HeroDebutSkinWin.cs.meta
new file mode 100644
index 0000000..f816017
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutSkinWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6330e8f4c656dd34ab077262bf052ca5
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutStarUpCell.cs b/Main/System/HeroDebut/HeroDebutStarUpCell.cs
new file mode 100644
index 0000000..b41e05b
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutStarUpCell.cs
@@ -0,0 +1,126 @@
+using System.Linq;
+using UnityEngine;
+
+public class HeroDebutStarUpCell : CellView
+{
+    [SerializeField] ItemCell freeAwardItemCell;
+    [SerializeField] Transform freeAwardHaveTransform;//宸查鍙�
+    [SerializeField] Transform freeAwardCanHaveTransform;//鍙鍙�
+
+    [SerializeField] Transform upProcssBGTransform;
+    [SerializeField] Transform upProcessTransform;
+    [SerializeField] Transform downProcssBGTransform;
+    [SerializeField] Transform downProcessTransform;
+    [SerializeField] TextEx starCntText;
+    [SerializeField] TextEx limitText;
+    [SerializeField] ButtonEx buyButton;
+    [SerializeField] ImageEx buyImage;
+    [SerializeField] TextEx buyText;
+    [SerializeField] ImageEx rateImage;
+    [SerializeField] TextEx rateText;
+    [SerializeField] ScrollerController scroller;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    int id;
+    public void Display(int id, CellView cell)
+    {
+        this.id = id;
+
+        int heroID = cell.info.Value.infoInt1;
+        bool isFrist = cell.info.Value.infoInt2 == 1;
+        bool isEnd = cell.info.Value.infoInt3 == 1;
+
+        var config = ActHeroAppearStarConfig.Get(id);
+        if (config == null) return;
+
+        var heroConfig = HeroConfig.Get(heroID);
+        if (heroConfig == null) return;
+
+        if (config.FreeAwardItemList.IsNullOrEmpty()) return;
+        int ctgId = config.StarGiftCTGID;
+        int awardIndex = config.AwardIndex;
+        if (!manager.TryGetStarUpAwardArr(id, heroID, out int[][] list)) return;
+        if (!RechargeManager.Instance.TryGetOrderInfo(ctgId, out var orderConfig)) return;
+        if (!RechargeManager.Instance.TryGetRechargeCount(ctgId, out var rechargeCount)) return;
+        if (!RechargeManager.Instance.TryGetRechargeItem(ctgId, out var rechargeItemList)) return;
+        CTGConfig ctgConfig = CTGConfig.Get(ctgId);
+        if (ctgConfig == null) return;
+
+        rateImage.SetActive(true);
+        rateText.text = Language.Get("DailySpecials07", ctgConfig.Percentage);
+
+        int state = manager.GetStarUpFreeState(id);//0 - 鏈В閿� 1 - 鍙鍙� 2 - 宸查鍙�
+        freeAwardHaveTransform.SetActive(state == 2);
+        freeAwardCanHaveTransform.SetActive(state == 1);
+
+        bool isNoSellOut = manager.IsNoSellOutCTGID(ctgId);
+        buyButton.interactable = state != 0 && isNoSellOut;
+        buyButton.SetListener(() =>
+        {
+            if (isNoSellOut && state != 0)
+            {
+                RechargeManager.Instance.CTG(ctgId);
+            }
+        });
+        //buyImage.gray = state == 0 || !isNoSellOut;
+        buyText.text = !isNoSellOut ? Language.Get("storename11") : Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderConfig.PayRMBNumOnSale));
+        limitText.text = Language.Get("TimeRush08", UIHelper.AppendColor(rechargeCount.totalCount >= ctgConfig.TotalBuyCount ? TextColType.Red : TextColType.DarkGreen, $"{rechargeCount.totalCount}/{ctgConfig.TotalBuyCount}"));
+        bool isHeroStarOk = manager.IsHeroStarCntOk(heroConfig.HeroID, config.NeedStar) && HeroManager.Instance.HasHero(heroConfig.HeroID);
+        upProcssBGTransform.SetActive(!isFrist);
+        downProcssBGTransform.SetActive(!isEnd);
+
+        upProcessTransform.SetActive(isHeroStarOk);
+        downProcessTransform.SetActive(isHeroStarOk);
+
+        CreateScroller(list);
+
+        int[] arr = config.FreeAwardItemList.First();
+        int itemID = arr[0];
+        int itemCount = arr[1];
+        freeAwardItemCell.SetActive(true);
+        freeAwardItemCell.Init(new ItemCellModel(itemID, false, itemCount));
+        freeAwardItemCell.button.AddListener(() =>
+        {
+            if (state == 1)
+            {
+                manager.SendGetStarReward();
+            }
+            else
+            {
+                ItemTipUtility.Show(itemID);
+            }
+        });
+
+        starCntText.text = Language.Get("HeroDebut20", config.NeedStar);
+    }
+
+    private void CreateScroller(int[][] list)
+    {
+        if (list == null) return;
+        var config = ActHeroAppearStarConfig.Get(id);
+        if (config == null) return;
+
+        scroller.OnRefreshCell += OnRefreshCell;
+        scroller.Refresh();
+        for (int i = 0; i < list.Length; i++)
+        {
+            var item = list[i];
+            var itemID = item[0];
+            var itemCount = item[1];
+            CellInfo cellInfo = new()
+            {
+                infoInt1 = itemID,
+                infoInt2 = itemCount,
+                infoInt3 = manager.IsNoSellOutCTGID(config.StarGiftCTGID) ? 1 : 0,
+            };
+            scroller.AddCell(ScrollerDataType.Header, i, cellInfo);
+        }
+        scroller.Restart();
+        scroller.OnRefreshCell -= OnRefreshCell;
+    }
+
+    private void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell.GetComponent<HeroDebutStarUpPaidItemCell>();
+        _cell?.Display(cell.index, cell);
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutStarUpCell.cs.meta b/Main/System/HeroDebut/HeroDebutStarUpCell.cs.meta
new file mode 100644
index 0000000..a49bc2e
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutStarUpCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 74da6ff1c960d3a409be13a89136573d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutStarUpPaidItemCell.cs b/Main/System/HeroDebut/HeroDebutStarUpPaidItemCell.cs
new file mode 100644
index 0000000..6506201
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutStarUpPaidItemCell.cs
@@ -0,0 +1,17 @@
+using UnityEngine;
+
+public class HeroDebutStarUpPaidItemCell : CellView
+{
+    [SerializeField] ItemCell itemCell;
+    [SerializeField] Transform soldOutTransform;
+    public void Display(int index, CellView cell)
+    {
+        int itemID = cell.info.Value.infoInt1;
+        int count = cell.info.Value.infoInt2;
+        bool isSoldOut = cell.info.Value.infoInt3 == 0;
+        soldOutTransform.SetActive(isSoldOut);
+        itemCell.SetActive(true);
+        itemCell.Init(new ItemCellModel((int)itemID, false, count));
+        itemCell.button.AddListener(() => ItemTipUtility.Show(itemID));
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutStarUpPaidItemCell.cs.meta b/Main/System/HeroDebut/HeroDebutStarUpPaidItemCell.cs.meta
new file mode 100644
index 0000000..d0fb6df
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutStarUpPaidItemCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2ba8d299ce307054c8e3b9e6608dffd5
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutStarUpWin.cs b/Main/System/HeroDebut/HeroDebutStarUpWin.cs
new file mode 100644
index 0000000..5c46d69
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutStarUpWin.cs
@@ -0,0 +1,121 @@
+using UnityEngine;
+
+public class HeroDebutStarUpWin : UIBase
+{
+    [SerializeField] GradientText heroNameText;
+    [SerializeField] TextEx timeText;
+    [SerializeField] ImageEx heroImage;
+    [SerializeField] ButtonEx goCallButton;
+    [SerializeField] ButtonEx goInfoButton;
+    [SerializeField] ButtonEx closeButton;
+    [SerializeField] ScrollerController scroller;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    protected override void InitComponent()
+    {
+        closeButton.SetListener(CloseWindow);
+        goCallButton.SetListener(() =>
+        {
+            UIManager.Instance.CloseWindow<HeroDebutStarUpWin>();
+            UIManager.Instance.OpenWindow<HeroDebutCallWin>();
+        });
+        goInfoButton.SetListener(() =>
+        {
+            if (heroConfig == null) return;
+            UIManager.Instance.CloseWindow<HeroDebutStarUpWin>();
+            HeroUIManager.Instance.selectForPreviewHeroID = heroConfig.HeroID;
+            UIManager.Instance.OpenWindow<HeroBestBaseWin>();
+        });
+    }
+
+    protected override void OnPreOpen()
+    {
+        scroller.OnRefreshCell += OnRefreshCell;
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent;
+        manager.OnUpdateHeroAppearPlayerInfoEvent += OnUpdateHeroAppearPlayerInfoEvent;
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+        RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent;
+        manager.OnUpdateHeroAppearPlayerInfoEvent -= OnUpdateHeroAppearPlayerInfoEvent;
+    }
+
+    private void OnUpdateHeroAppearPlayerInfoEvent(int obj)
+    {
+        scroller.m_Scorller.RefreshActiveCellViews();
+    }
+
+    private void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell.GetComponent<HeroDebutStarUpCell>();
+        _cell?.Display(cell.index, cell);
+    }
+
+    private void OnSecondEvent()
+    {
+        manager.GetActTimeStr(timeText);
+    }
+
+    private void OnRechargeCountEvent(int obj)
+    {
+        scroller.m_Scorller.RefreshActiveCellViews();
+    }
+
+    HeroConfig heroConfig;
+    private void Display()
+    {
+        int heroID = manager.GetCurrentDisplayStarUpHeroId();
+        heroConfig = HeroConfig.Get(heroID);
+        if (heroConfig == null) return;
+
+        var artConfig = ActHeroAppearArtConfig.Get(heroID);
+        if (artConfig == null) return;
+
+        var act = manager.GetOperationHeroAppearInfo();
+        if (act == null) return;
+
+        var config = ActHeroAppearConfig.Get(act.CfgID);
+        if (config == null) return;
+        
+        heroNameText.text = heroConfig.Name;
+        manager.SetGradientTextColor(heroNameText, artConfig.HeroNameColor);
+        
+        heroImage.SetSprite(artConfig.StarUpHeroImage);
+        heroImage.SetNativeSize();
+
+        CreateScroller(config, heroConfig);
+    }
+
+    private void CreateScroller(ActHeroAppearConfig appearConfig, HeroConfig heroConfig)
+    {
+
+
+        if (appearConfig == null || heroConfig == null) return;
+        int starGiftTempID = appearConfig.StarGiftTempID;
+        var list = ActHeroAppearStarConfig.GetAwardIndexSortList(starGiftTempID);
+        if (list == null) return;
+
+        scroller.Refresh();
+        for (int i = 0; i < list.Count; i++)
+        {
+            var awardIndex = list[i];
+
+            var config = ActHeroAppearStarConfig.GetConfig(starGiftTempID, awardIndex);
+            if (config == null) continue;
+
+            CellInfo cellInfo = new()
+            {
+                infoInt1 = heroConfig.HeroID,
+                infoInt2 = i == 0 ? 1 : 0,
+                infoInt3 = i == list.Count - 1 ? 1 : 0
+            };
+            scroller.AddCell(ScrollerDataType.Header, config.ID, cellInfo);
+        }
+        scroller.Restart();
+        scroller.JumpIndex(manager.GetStarUpJumpIndex(starGiftTempID));
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutStarUpWin.cs.meta b/Main/System/HeroDebut/HeroDebutStarUpWin.cs.meta
new file mode 100644
index 0000000..8d81fc1
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutStarUpWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1093406ae678d4843b4b41a662287bb9
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/HeroDebutWin.cs b/Main/System/HeroDebut/HeroDebutWin.cs
new file mode 100644
index 0000000..c9ddc46
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutWin.cs
@@ -0,0 +1,115 @@
+using System;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class HeroDebutWin : UIBase
+{
+    [SerializeField] RectTransform activeRect;
+    [SerializeField] RectTransform moveRect;
+    [SerializeField] RectTransform startRect;
+    [SerializeField] RectTransform endRect;
+
+    [SerializeField] ImageEx bgImage;
+    [SerializeField] ImageEx titleImage;
+    [SerializeField] TextEx timeText;
+    [SerializeField] ButtonEx animationButton;
+    [SerializeField] ButtonEx checkInButton; // 绛惧埌璧犵ぜ
+    [SerializeField] RedpointBehaviour checkInRedpoint;
+    [SerializeField] ButtonEx starUpButton; // 鍗囨槦璁″垝
+    [SerializeField] RedpointBehaviour starUpRedpoint;
+    [SerializeField] ButtonEx shopButton; // 鍏戞崲鍟嗗簵
+    [SerializeField] RedpointBehaviour shopRedpoint;
+    [SerializeField] ImageEx skinImage;
+    [SerializeField] ButtonEx skinButton; // 鏃惰鐗瑰崠
+    [SerializeField] ButtonEx giftButton; // 鐨囨潈绀煎寘
+    [SerializeField] RedpointBehaviour giftRedpoint;
+    [SerializeField] ButtonEx callButton; // 鐨囨潈鎷涘嫙
+    [SerializeField] UIHeroController uiHeroController;
+    [SerializeField] UIHeroController lhController;
+    [SerializeField] Image callRedImage;
+    [SerializeField] ButtonEx closeButton;
+    [SerializeField] float modleSize = 0.8f;
+    HeroDebutManager manager => HeroDebutManager.Instance;
+    protected override void InitComponent()
+    {
+        closeButton.SetListener(() => UIManager.Instance.CloseWindow<HeroDebutWin>());
+        checkInButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutCheckInWin>());
+        starUpButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutStarUpWin>());
+        shopButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutShopWin>());
+        skinButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutSkinWin>());
+        giftButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutGiftWin>());
+        callButton.SetListener(() => UIManager.Instance.OpenWindow<HeroDebutCallWin>());
+    }
+
+    protected override void OnPreOpen()
+    {
+        InitRedpoint();
+
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent += Display;
+        manager.OnUpdateHeroAppearPlayerInfoEvent += OnUpdateHeroAppearPlayerInfoEvent;
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+        RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent;
+        StoreModel.Instance.RefreshBuyShopLimitEvent -= Display;
+        manager.OnUpdateHeroAppearPlayerInfoEvent -= OnUpdateHeroAppearPlayerInfoEvent;
+    }
+
+    private void OnUpdateHeroAppearPlayerInfoEvent(int obj)
+    {
+        Display();
+    }
+
+    private void OnRechargeCountEvent(int obj)
+    {
+        Display();
+    }
+
+    public void InitRedpoint()
+    {
+        checkInRedpoint.redpointId = manager.GetRedPointId(HeroDebutRedPointType.CheckIn);
+        starUpRedpoint.redpointId = manager.GetRedPointId(HeroDebutRedPointType.StarUp);
+        shopRedpoint.redpointId = manager.GetRedPointId(HeroDebutRedPointType.Shop);
+        giftRedpoint.redpointId = manager.GetRedPointId(HeroDebutRedPointType.Gift);
+    }
+
+    private void Display()
+    {
+
+        int heroID = manager.GetCurrentDisplayCallHeroId();
+        var artConfig = ActHeroAppearArtConfig.Get(heroID);
+        if (artConfig == null) return;
+
+        int skinID = manager.GetDefaultSkinID(heroID);
+        var skinConfig = HeroSkinConfig.Get(skinID);
+        if (skinConfig == null) return;
+
+        var skinArtConfig = ActHeroAppearSkinArtConfig.Get(artConfig.MainSkinID);
+        if (skinArtConfig == null) return;
+
+        uiHeroController.Create(skinID, modleSize);
+        uiHeroController.transform.localScale = new Vector3(-modleSize, modleSize, modleSize);
+        lhController.Create(skinID, 1, motionName: "", isLh: true);
+
+        callRedImage.SetActive(!manager.IsShopVisitedToday || manager.HasGiftCanHave());
+
+        bgImage.SetSprite(artConfig.MainBgImage);
+        bgImage.SetNativeSize();
+
+        titleImage.SetSprite(artConfig.MainTitleImage);
+        titleImage.SetNativeSize();
+
+        skinImage.SetSprite(skinArtConfig.MainSkinBuyBgImage);
+        OnSecondEvent();
+    }
+
+    private void OnSecondEvent()
+    {
+        manager.GetActTimeStr(timeText);
+    }
+}
diff --git a/Main/System/HeroDebut/HeroDebutWin.cs.meta b/Main/System/HeroDebut/HeroDebutWin.cs.meta
new file mode 100644
index 0000000..bb04ef9
--- /dev/null
+++ b/Main/System/HeroDebut/HeroDebutWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ef7895a8e56d7424d9f3bc87d12e997e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroDebut/OperationHeroAppearInfo.cs b/Main/System/HeroDebut/OperationHeroAppearInfo.cs
new file mode 100644
index 0000000..e1e5c8a
--- /dev/null
+++ b/Main/System/HeroDebut/OperationHeroAppearInfo.cs
@@ -0,0 +1,21 @@
+锘�
+//鑻遍泟鐧诲満锛堟灏嗙櫥鍦猴級
+public class OperationHeroAppearInfo : OperationBase
+{
+    public int ActType; // 娲诲姩绫诲瀷锛岀敤浜庡叧鑱旀椿鍔ㄧ浉鍏虫ā鍧楃敤锛屽绛惧埌銆佷换鍔$瓑
+    public int CfgID;   // 娲诲姩鏃堕棿琛ㄩ厤缃甀D
+
+    public override string ToDisplayTime()
+    {
+        var textBuilder = OperationTimeHepler.textBuilder;
+        textBuilder.Length = 0;
+        textBuilder.Append(startDate.ToDisplay());
+        if (startDate != endDate)
+        {
+            textBuilder.Append("鈥�");
+            textBuilder.Append(endDate.ToDisplay());
+        }
+        return textBuilder.ToString();
+    }
+
+}
diff --git a/Main/System/HeroDebut/OperationHeroAppearInfo.cs.meta b/Main/System/HeroDebut/OperationHeroAppearInfo.cs.meta
new file mode 100644
index 0000000..59f8793
--- /dev/null
+++ b/Main/System/HeroDebut/OperationHeroAppearInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2c27b7bd6b1cca749b6b40fcb645785d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroFates/HeroFatesIHItem.cs b/Main/System/HeroFates/HeroFatesIHItem.cs
index 858fe93..a02655b 100644
--- a/Main/System/HeroFates/HeroFatesIHItem.cs
+++ b/Main/System/HeroFates/HeroFatesIHItem.cs
@@ -1,7 +1,6 @@
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
-using Cysharp.Threading.Tasks;
 
 public class HeroFatesIHItem : MonoBehaviour
 {
@@ -49,12 +48,12 @@
                 }
                 HeroInfo heroInfo = nowMaxStarHeroDict[heroId];
                 HeroUIManager.Instance.selectHeroGuid = heroInfo.itemHero.guid;
-                UIManager.Instance.OpenWindowAsync<HeroTrainWin>().Forget();
+                UIManager.Instance.OpenWindow<HeroTrainBaseWin>();
             }
             else
             {
                 HeroUIManager.Instance.selectForPreviewHeroID = heroId;
-                UIManager.Instance.OpenWindowAsync<HeroBestWin>().Forget();
+                UIManager.Instance.OpenWindow<HeroBestBaseWin>();
             }
         });
     }
diff --git a/Main/System/HeroUI/HeroBestBaseWin.cs b/Main/System/HeroUI/HeroBestBaseWin.cs
new file mode 100644
index 0000000..aba3e7e
--- /dev/null
+++ b/Main/System/HeroUI/HeroBestBaseWin.cs
@@ -0,0 +1,74 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class HeroBestBaseWin : OneLevelWin
+{
+
+
+    protected override void OpenSubUIByTabIndex()
+    {
+        ShowSkinBtn();
+        switch (functionOrder)
+        {
+            case 0:
+
+                currentSubUI = UIManager.Instance.OpenWindow<HeroBestWin>();
+
+                if (GetSortingOrder() < currentSubUI.GetSortingOrder())
+                {
+                    SetSortingOrder(currentSubUI.GetSortingOrder() + 1);
+                }
+                break;
+
+            case 1:
+                //鐨偆 鍥鹃壌鐣岄潰鎵撳紑鐨勪紶1
+                currentSubUI = UIManager.Instance.OpenWindow<HeroSkinWin>(1);
+
+                if (GetSortingOrder() < currentSubUI.GetSortingOrder())
+                {
+                    SetSortingOrder(currentSubUI.GetSortingOrder() + 1);
+                }
+                break;
+            default:
+                Debug.LogWarning("鏈煡鐨勬爣绛剧储寮�: " + functionOrder);
+                break;
+        }
+
+    }
+
+    //鏈夌殑姝﹀皢娌℃湁鐨偆
+    public void ShowSkinBtn()
+    {
+        if (HeroUIManager.Instance.selectForPreviewHeroID == 0)
+        {
+            return;
+        }
+        var config = HeroConfig.Get(HeroUIManager.Instance.selectForPreviewHeroID);
+        tabButtons[1].SetActive(config.SkinIDList.Length > 1);
+    }
+
+    //鍏朵粬鐣岄潰鍜屾鐣岄潰鐨勫眰绾ф樉绀洪棶棰�
+    protected override void OnPreOpen()
+    {
+        base.OnPreOpen();
+        UIManager.Instance.OnAfterSortWinLayer += OnAfterSortWinLayer;
+
+    }
+
+    protected override void OnPreClose()
+    {
+        base.OnPreClose();
+        UIManager.Instance.OnAfterSortWinLayer -= OnAfterSortWinLayer;
+    }
+
+    void OnAfterSortWinLayer()
+    {
+        if (currentSubUI == null) return;
+
+        if (GetSortingOrder() < currentSubUI.GetSortingOrder())
+        {
+            SetSortingOrder(currentSubUI.GetSortingOrder() + 1);
+        }
+    }
+}
diff --git a/Main/System/HeroUI/HeroBestBaseWin.cs.meta b/Main/System/HeroUI/HeroBestBaseWin.cs.meta
new file mode 100644
index 0000000..a7bfade
--- /dev/null
+++ b/Main/System/HeroUI/HeroBestBaseWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 882d8d5319479394489f7f787d2bafbb
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroUI/HeroBestWin.cs b/Main/System/HeroUI/HeroBestWin.cs
index 2bb3e8f..3d7bd97 100644
--- a/Main/System/HeroUI/HeroBestWin.cs
+++ b/Main/System/HeroUI/HeroBestWin.cs
@@ -25,7 +25,6 @@
     [SerializeField] SkillBaseCell normalSkillCell;
     [SerializeField] SkillBaseCell angerSkillCell;
 
-    [SerializeField] Button closeBtn;   //鍏抽棴鎸夐挳
     [SerializeField] Button starBtn;   //鏄剧ず鏄熺骇鏂囧瓧
     [SerializeField] List<Image> starImgList;
     [SerializeField] Text nameText;
@@ -72,12 +71,13 @@
         showFuncBtn.AddListener(() =>
         {
             funcForm.SetActive(true);
+            UIManager.Instance.GetUI<HeroBestBaseWin>().GetCanvasGroup().alpha = 1;
         });
         seeLhBtn.AddListener(() =>
         {
             funcForm.SetActive(false);
+            UIManager.Instance.GetUI<HeroBestBaseWin>().GetCanvasGroup().alpha = 0;
         });
-        closeBtn.AddListener(CloseWindow);
         rightBtn.AddListener(() =>
         {
             ChangeHero(1);
@@ -126,6 +126,8 @@
         unfoldState = false;
         allAttrScroll.verticalNormalizedPosition = 1;
         Display();
+        HeroUIManager.Instance.skinRedpoint.state = HeroUIManager.Instance.HeroAllSkinStateForRedpoint(HeroUIManager.Instance.selectForPreviewHeroID, true) > 0 ? RedPointState.Simple : RedPointState.None;
+    
     }
 
 
@@ -133,15 +135,15 @@
     public void Display()
     {
         heroConfig = HeroConfig.Get(HeroUIManager.Instance.selectForPreviewHeroID);
-        bgTexture.SetTexture2D("countryBG" + heroConfig.Country);
         int skinID = heroConfig.SkinIDList[0];
+        bgTexture.SetTexture2D(HeroUIManager.Instance.GetBGName(skinID, heroConfig.Country));
         roleLhModel.Create(skinID, 1, motionName: "", isLh: true);
         roleXsModel.Create(skinID, 1);
         jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class));
         jobPosNameText.text = HeroUIManager.Instance.GetJobName(heroConfig.Class);
         descText.text = heroConfig.Desc;
-
-
+        HeroUIManager.Instance.PlayerLHSound(skinID);
+        
         RefreshConn();
         normalSkillCell.Init(heroConfig.AtkSkillID, () =>
         {
@@ -221,6 +223,13 @@
         }
         HeroUIManager.Instance.selectForPreviewHeroID = HeroUIManager.Instance.heroCollectList[resultIndex];
         Display();
+        
+        //鎺у埗涓�绾у姛鑳界晫闈㈢殑鐨偆鎸夐挳
+        var ui = UIManager.Instance.GetUI<HeroBestBaseWin>();
+        if (ui != null)
+        {
+            ui.ShowSkinBtn();
+        }
     }
 
 
diff --git a/Main/System/HeroUI/HeroCardCell.cs b/Main/System/HeroUI/HeroCardCell.cs
index 0b78714..ad82c97 100644
--- a/Main/System/HeroUI/HeroCardCell.cs
+++ b/Main/System/HeroUI/HeroCardCell.cs
@@ -1,7 +1,6 @@
-锘縰sing UnityEngine;
+using UnityEngine;
 using UnityEngine.UI;
 using System.Collections.Generic;
-using Cysharp.Threading.Tasks;
 
 public class HeroCardCell : MonoBehaviour
 {
@@ -65,7 +64,7 @@
             trainStateImg.SetActive(false);
         }
 
-        starRedImg.SetActive(funcState == 2);
+        starRedImg.SetActive(funcState == 2 || HeroUIManager.Instance.HeroAllSkinStateForRedpoint(hero.heroId) > 0);
 
         nameText.text = hero.breakLevel == 0 ? heroConfig.Name : Language.Get("herocardbreaklv", heroConfig.Name, hero.breakLevel);
         awakeImg.SetActive(hero.awakeLevel > 0);
@@ -93,7 +92,7 @@
         heroCardBtn.AddListener(() =>
         {
             HeroUIManager.Instance.selectHeroGuid = guid;
-            UIManager.Instance.OpenWindowAsync<HeroTrainWin>(funcState == 3 ? 1 : 0).Forget();
+            UIManager.Instance.OpenWindow<HeroTrainBaseWin>(funcState == 3 ? 1 : 0);
         });
     }
 }
diff --git a/Main/System/HeroUI/HeroCollectionCardCell.cs b/Main/System/HeroUI/HeroCollectionCardCell.cs
index e2e041c..5ea7b56 100644
--- a/Main/System/HeroUI/HeroCollectionCardCell.cs
+++ b/Main/System/HeroUI/HeroCollectionCardCell.cs
@@ -1,7 +1,6 @@
-锘縰sing UnityEngine;
+using UnityEngine;
 using UnityEngine.UI;
 using System.Collections.Generic;
-using Cysharp.Threading.Tasks;
 
 public class HeroCollectionCardCell : MonoBehaviour
 {
@@ -17,7 +16,7 @@
     // [SerializeField] Button bookLVBtn;
     [SerializeField] GameObject unGetObj;
     [SerializeField] GameObject activeObj; // 鍙縺娲诲甫娴佸厜鏁堟灉鏉愯川
-
+    [SerializeField] GameObject actLimitObj; // 娲诲姩闄愬畾
     public void Display(int index, int quality)
     {
         var heroID = HeroUIManager.Instance.heroCollectDict[quality][index];
@@ -35,6 +34,7 @@
         activeObj.SetActive(funcState == 1);
         // bookLVBtn.SetActive(funcState > 1);
         unGetObj.SetActive(funcState == 0);
+        actLimitObj.SetActive(heroConfig.IsActLimit == 1);
 
         countryImg.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
         jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class));
@@ -51,25 +51,11 @@
         {
             trainStateImg.SetActive(false);
         }
-        nameText.text = colData.BookBreakLV == 0 ? heroConfig.Name : Language.Get("herocardbreaklv", heroConfig.Name, colData.BookBreakLV);
+        nameText.text = heroConfig.Name;
 
         for (int i = 0; i < starImgList.Count; i++)
         {
-            if (colData.BookStarLV == 0 && i == 0)
-            {
-                // 鏃犳槦绾� 鐗规畩澶勭悊
-                starImgList[i].SetActive(true);
-                starImgList[i].SetSprite("herostar" + colData.BookStarLV);
-            }
-            else if ((colData.BookStarLV - 1) % starImgList.Count >= i)
-            {
-                starImgList[i].SetActive(true);
-                starImgList[i].SetSprite("herostar" + (((colData.BookStarLV - 1) / starImgList.Count) + 1) * starImgList.Count);
-            }
-            else
-            {
-                starImgList[i].SetActive(false);
-            }
+            starImgList[i].SetActive(false);
         }
 
         heroCardBtn.AddListener(() =>
@@ -78,19 +64,19 @@
             var state = HeroUIManager.Instance.GetHeroBookState(heroID, quality);
             if (state == 1 || state == 3 || state == 4)
             {
-                UIManager.Instance.OpenWindowAsync<HeroCollectionLvUpWin>().Forget();
+                UIManager.Instance.OpenWindow<HeroCollectionLvUpWin>();
             }
             else
             {
                 HeroUIManager.Instance.selectForPreviewHeroID = heroID;
-                UIManager.Instance.OpenWindowAsync<HeroBestWin>().Forget();
+                UIManager.Instance.OpenWindow<HeroBestBaseWin>();
             }
         });
         
         // bookLVBtn.AddListener(() =>
         // {
         //     HeroUIManager.Instance.selectCollectHeroID = heroID;
-        //     UIManager.Instance.OpenWindowAsync<HeroCollectionLvUpWin>().Forget();
+        //     UIManager.Instance.OpenWindow<HeroCollectionLvUpWin>();
         // });
     }
 }
diff --git a/Main/System/HeroUI/HeroCollectionLvUpWin.cs b/Main/System/HeroUI/HeroCollectionLvUpWin.cs
index bdeb670..776d987 100644
--- a/Main/System/HeroUI/HeroCollectionLvUpWin.cs
+++ b/Main/System/HeroUI/HeroCollectionLvUpWin.cs
@@ -1,6 +1,5 @@
 using System.Collections.Generic;
 using System.Linq;
-using Cysharp.Threading.Tasks;
 using UnityEngine;
 using UnityEngine.UI;
 
@@ -96,8 +95,8 @@
         {
             // fullPanel.SetActive(true);
             lvupPanel.SetActive(state == 1);
-            fullHeadCell.Init(HeroUIManager.Instance.selectCollectHeroID, config.SkinIDList[0], colData.BookStarLV).Forget();
-            name3.text = colData.BookBreakLV == 0 ? config.Name : Language.Get("herocardbreaklv", config.Name, colData.BookBreakLV);
+            fullHeadCell.Init(HeroUIManager.Instance.selectCollectHeroID, config.SkinIDList[0]);
+            name3.text = config.Name;
 
 
             btn.SetActive(true);
@@ -110,8 +109,6 @@
             awardInfo.text = string.Empty;
             unActiveGo.SetActive(false);
             // titleText.text = Language.Get("HeroAwake12");
-            int afterBreakLV = colData.BookBreakLV;
-            int afterStarLV = colData.BookStarLV;
             if (state == 1)
             {
                 lvupPanel.SetActive(true);
diff --git a/Main/System/HeroUI/HeroCollectionWin.cs b/Main/System/HeroUI/HeroCollectionWin.cs
index 9c69e79..50bd021 100644
--- a/Main/System/HeroUI/HeroCollectionWin.cs
+++ b/Main/System/HeroUI/HeroCollectionWin.cs
@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using Cysharp.Threading.Tasks;
 using UnityEngine;
 using UnityEngine.UI;
 
@@ -27,13 +26,15 @@
         {
             SmallTipWin.worldPos = CameraManager.uiCamera.ScreenToWorldPoint(Input.mousePosition);
             SmallTipWin.showText = Language.Get("herocard6");
-            UIManager.Instance.OpenWindowAsync<SmallTipWin>().Forget();
+            UIManager.Instance.OpenWindow<SmallTipWin>();
         });
 
         heroPackBtn.AddListener(() =>
         {
             HeroUIManager.Instance.QueryUnLockHeroPack();
         });
+
+        fiterManager = HeroSelectBehaviour.Create(heroSelectBehaviour);
     }
 
     protected override void OnPreOpen()
@@ -43,43 +44,30 @@
         PackManager.Instance.RefreshItemEvent += RefreshItemEvent;
         HeroUIManager.Instance.OnHeroCollectEvent += OnHeroCollectEvent;
         heroListScroller.OnRefreshCell += OnRefreshCell;
+        TimeMgr.Instance.OnDayEvent += OnDayEvent;
         HeroUIManager.Instance.SortHeroCollectList();
         Display();
     }
 
     protected override void OnPreClose()
     {
-
         PackManager.Instance.gridRefreshEvent -= GridRefreshEvent;
         PackManager.Instance.RefreshItemEvent -= RefreshItemEvent;
         HeroUIManager.Instance.OnHeroCollectEvent -= OnHeroCollectEvent;
         heroListScroller.OnRefreshCell -= OnRefreshCell;
+        TimeMgr.Instance.OnDayEvent -= OnDayEvent;
     }
 
+    private void OnDayEvent()
+    {
+        HeroUIManager.Instance.SortHeroCollectList();
+        CreateScroller();
+    }
 
     void Display()
     {
-        if (null != fiterManager)
-        {
-            fiterManager.Display(0, SelectJobCountry);
-        }
-        else
-        {
-            HeroSelectBehaviour.Create(heroSelectBehaviour).ContinueWith(fmgr =>
-            {
-                if (this == null)
-                {
-                    if (fmgr != null)
-                    {
-                        GameObject.DestroyImmediate(fmgr.gameObject);
-                    }
-                    return;
-                }
-                fiterManager = fmgr;
-                fiterManager.Display(0, SelectJobCountry);
-            }).Forget();   
-        }
-        
+        fiterManager.Display(0, SelectJobCountry);
+
         // CreateScroller();
         // RefreshTotalAttr();
         RefreshPackCount();
diff --git a/Main/System/HeroUI/HeroDeleteWin.cs b/Main/System/HeroUI/HeroDeleteWin.cs
index 26032ad..a626b47 100644
--- a/Main/System/HeroUI/HeroDeleteWin.cs
+++ b/Main/System/HeroUI/HeroDeleteWin.cs
@@ -261,9 +261,72 @@
             allItemDict[key] = Math.Max((long)(allItemDict[key] * HeroUIManager.Instance.deletePayBackPer / 100.0), 1);
         }
 
+        List<Item> items = new List<Item>();
+        foreach (var data in allItemDict)
+        {
+            items.Add(new Item(data.Key, data.Value, _dataEx:$"( {HeroUIManager.Instance.deletePayBackPer}% )"));
+        }
 
+        Dictionary<int, long> moreMMItemDict = new Dictionary<int, long>();
+        Dictionary<int, long> moreTitleItemDict = new Dictionary<int, long>();
+        int beautyEffectPer = BeautyMMManager.Instance.GetTalentEffectByType(TalentEffectType.HeroDelete);
+        int titleEffect = PhantasmPavilionManager.Instance.GetTotalTalentValue(PhantasmPavilionType.Title, 3);
+        //绾㈤鍜岀О鍙烽澶栬幏寰�
+        if (beautyEffectPer > 0)
+        {
+            for (int i = 0; i < HeroUIManager.Instance.selectDeleteHeroList.Count; i++)
+            {
+                HeroInfo hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectDeleteHeroList[i]);
+                if (hero == null)
+                    continue;
 
-        List<Item> items = CommonFunc.ChangeToItemList(allItemDict);
+                foreach (var tmp in hero.qualityConfig.TitleReturnItems)
+                {
+                    if (!moreMMItemDict.ContainsKey(tmp[0]))
+                    {
+                        moreMMItemDict.Add(tmp[0], (long)Math.Ceiling(tmp[1] * beautyEffectPer / 100.0f));
+                    }
+                    else
+                    {
+                        moreMMItemDict[tmp[0]] += (long)Math.Ceiling(tmp[1] * beautyEffectPer / 100.0f);
+                    }
+                }
+
+            }
+
+            foreach (var key in moreMMItemDict.Keys)
+            {
+                items.Add(new Item(key, moreMMItemDict[key], 20, _dataEx: $"( {beautyEffectPer}% )"));
+            }
+        }
+        if (titleEffect > 0)
+        {
+            for (int i = 0; i < HeroUIManager.Instance.selectDeleteHeroList.Count; i++)
+            {
+                HeroInfo hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectDeleteHeroList[i]);
+                if (hero == null)
+                    continue;
+
+                foreach (var tmp in hero.qualityConfig.TitleReturnItems)
+                {
+                    if (!moreTitleItemDict.ContainsKey(tmp[0]))
+                    {
+                        moreTitleItemDict.Add(tmp[0], (long)Math.Ceiling(tmp[1] * titleEffect / 100.0f));
+                    }
+                    else
+                    {
+                        moreTitleItemDict[tmp[0]] += (long)Math.Ceiling(tmp[1] * titleEffect / 100.0f);
+                    }
+                }
+
+            }
+
+            foreach (var key in moreTitleItemDict.Keys)
+            {
+                items.Add(new Item(key, moreTitleItemDict[key], 30, _dataEx: $"( {titleEffect}% )"));
+            }
+        }
+
         ConfirmCancel.ShowItemsConfirm(items, Language.Get("herocard25"), Language.Get("herocard26"), (bool isOk) =>
         {
             if (isOk)
@@ -280,7 +343,7 @@
                 GameNetSystem.Instance.SendInfo(pack);
                 HeroUIManager.Instance.selectDeleteHeroList.Clear();
             }
-        }, itemName:$"( {HeroUIManager.Instance.deletePayBackPer}% )");
+        });
 
     }
 
diff --git a/Main/System/HeroUI/HeroListWin.cs b/Main/System/HeroUI/HeroListWin.cs
index d801b33..29f7fb6 100644
--- a/Main/System/HeroUI/HeroListWin.cs
+++ b/Main/System/HeroUI/HeroListWin.cs
@@ -107,7 +107,7 @@
     private void OnCloseWindow(UIBase closeUI)
     {
         //鍏朵粬姝﹀皢鍔熻兘浜х敓鏁版嵁鍙樺寲锛岄渶瑕佸埛鏂版灏嗗垪琛�
-        if (closeUI is HeroTrainWin ||
+        if (closeUI is HeroTrainBaseWin ||
             closeUI is HeroCallWin ||
             closeUI is HeroDeleteWin ||
             closeUI is HeroPosWin)
diff --git a/Main/System/HeroUI/HeroSkinCell.cs b/Main/System/HeroUI/HeroSkinCell.cs
new file mode 100644
index 0000000..b53b37c
--- /dev/null
+++ b/Main/System/HeroUI/HeroSkinCell.cs
@@ -0,0 +1,47 @@
+锘縰sing System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+public class HeroSkinCell : CellView
+{
+    [SerializeField] Image skinImage;
+    [SerializeField] Image skinFrame;
+    [SerializeField] Image skinAttrOnImg;
+    [SerializeField] Image skinRoleOnImg;
+    [SerializeField] Text skinName;
+    [SerializeField] Image unselectImg;
+    [SerializeField] Image ungetImg;
+    [SerializeField] Image fakeRed;
+    [SerializeField] Button cardBtn;
+    [SerializeField] Transform selectObj;   //鏀惧ぇ鐢�
+
+    public void Display(int heroID, int index, bool isHero)
+    {
+        var skinID = HeroConfig.Get(heroID).SkinIDList[index];
+        var skinConfig = HeroSkinConfig.Get(skinID);
+        var attrCfg = HeroSkinAttrConfig.Get(skinID);
+        skinImage.SetOrgSprite(skinConfig.CardPic, "HeroSkinCard");
+        skinFrame.SetSprite("HeroSkinFrame" + (attrCfg== null ? 0 : attrCfg.Quality));
+        skinName.text = skinConfig.SkinName == "" ? Language.Get("HeroSkin2") : skinConfig.SkinName;
+        if (!isHero)
+        {
+            skinAttrOnImg.SetActive(false);
+            skinRoleOnImg.SetActive(false);
+        }
+        else
+        {
+            var hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectHeroGuid);
+            //鍒嗙┛鎴� 鍜屽舰璞★紝閫変腑鍚屼竴涓椂绌挎埓浼樺厛
+            skinAttrOnImg.SetActive(hero.SkinAttrIndex == index);
+            skinRoleOnImg.SetActive(hero.SkinIndex != hero.SkinAttrIndex && hero.SkinIndex == index);
+        }
+        unselectImg.SetActive(HeroUIManager.Instance.selectSkinIndex != index);
+        selectObj.localScale = HeroUIManager.Instance.selectSkinIndex != index ? Vector3.one*0.9f : Vector3.one * 1f;
+        ungetImg.SetActive(!HeroUIManager.Instance.IsHeroSkinActive(heroID, skinID));
+        fakeRed.SetActive(HeroUIManager.Instance.HeroSkinStateForRedpoint(skinID) > 0);
+        cardBtn.AddListener(()=>
+        {
+            HeroUIManager.Instance.selectSkinIndex = index;
+        });
+    }
+}
diff --git a/Main/System/HeroUI/HeroSkinCell.cs.meta b/Main/System/HeroUI/HeroSkinCell.cs.meta
new file mode 100644
index 0000000..605e2a9
--- /dev/null
+++ b/Main/System/HeroUI/HeroSkinCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 834258ed4bb79f9468a4f083e753317f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroUI/HeroSkinChooseWin.cs b/Main/System/HeroUI/HeroSkinChooseWin.cs
new file mode 100644
index 0000000..7fe66ca
--- /dev/null
+++ b/Main/System/HeroUI/HeroSkinChooseWin.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+
+/// <summary>
+/// 姝﹀皢鐨偆褰㈣薄閫夋嫨
+/// </summary>
+public class HeroSkinChooseWin : UIBase
+{
+    [SerializeField] Button closeBtn;
+    [SerializeField] Button okBtn;
+    [SerializeField] ScrollerController skinScroller;
+
+    public static int selectIndex;
+    public static List<int> activeIndexList = new List<int>();
+    HeroConfig heroConfig;
+
+    protected override void InitComponent()
+    {
+        closeBtn.AddListener(() =>
+        {
+            CloseWindow();
+        });
+        okBtn.AddListener(() =>
+        {
+            var hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectHeroGuid);
+            HeroUIManager.Instance.SendSkinOP(hero.heroId, heroConfig.SkinIDList[selectIndex], 2, hero.itemHero.gridIndex);
+            CloseWindow();
+        });
+
+    }
+
+    protected override void OnPreOpen()
+    {
+        var hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectHeroGuid);
+        heroConfig = hero.heroConfig;
+        skinScroller.OnRefreshCell += OnRefreshCell;
+        selectIndex = hero.SkinIndex;
+        activeIndexList = new List<int>();
+        for (int i = 0; i < heroConfig.SkinIDList.Length; i++)
+        {
+            if (HeroUIManager.Instance.IsHeroSkinActive(hero.heroId, heroConfig.SkinIDList[i]))
+            {
+                activeIndexList.Add(i);
+            }
+        }
+        CreateScroller();
+    }
+
+    protected override void OnPreClose()
+    {
+        skinScroller.OnRefreshCell -= OnRefreshCell;
+        heroConfig = null;
+    }
+
+    void CreateScroller()
+    {
+
+        skinScroller.Refresh();
+        for (int i = 0; i < activeIndexList.Count; i++)
+        {
+            if (i % 4 == 0)
+            {
+                skinScroller.AddCell(ScrollerDataType.Header, i);
+            }
+        }
+        skinScroller.Restart();
+
+    }
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as HeroSkinRoleLineCell;
+        _cell.Display(heroConfig, cell.index);
+    }
+
+    public void SetSelectIndex(int index)
+    {
+        selectIndex = index;
+        skinScroller.m_Scorller.RefreshActiveCellViews();
+    }
+}
\ No newline at end of file
diff --git a/Main/System/HeroUI/HeroSkinChooseWin.cs.meta b/Main/System/HeroUI/HeroSkinChooseWin.cs.meta
new file mode 100644
index 0000000..b593658
--- /dev/null
+++ b/Main/System/HeroUI/HeroSkinChooseWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 186027f98fd6d5e4d95ce7d41ba5f040
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroUI/HeroSkinRoleCell.cs b/Main/System/HeroUI/HeroSkinRoleCell.cs
new file mode 100644
index 0000000..a0a6fef
--- /dev/null
+++ b/Main/System/HeroUI/HeroSkinRoleCell.cs
@@ -0,0 +1,23 @@
+锘縰sing System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+public class HeroSkinRoleCell : MonoBehaviour
+{
+    [SerializeField] UIHeroController heroModel;
+    [SerializeField] Image selectImg;
+    [SerializeField] Button selectBtn;
+
+    //index涓虹毊鑲よ〃涓储寮�
+    public void Display(HeroConfig heroConfig, int index)
+    {
+        selectImg.SetActive(HeroSkinChooseWin.selectIndex == index);
+        heroModel.Create(heroConfig.SkinIDList[index], heroConfig.UIScale);
+        selectBtn.AddListener(() =>
+        {
+            var ui = UIManager.Instance.GetUI<HeroSkinChooseWin>();
+            ui.SetSelectIndex(index);
+
+        });
+    }
+}
diff --git a/Main/System/HeroUI/HeroSkinRoleCell.cs.meta b/Main/System/HeroUI/HeroSkinRoleCell.cs.meta
new file mode 100644
index 0000000..b6476e4
--- /dev/null
+++ b/Main/System/HeroUI/HeroSkinRoleCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 340939aa27fc7bb4eafbe1bc3e58dda2
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroUI/HeroSkinRoleLineCell.cs b/Main/System/HeroUI/HeroSkinRoleLineCell.cs
new file mode 100644
index 0000000..a263c77
--- /dev/null
+++ b/Main/System/HeroUI/HeroSkinRoleLineCell.cs
@@ -0,0 +1,23 @@
+锘縰sing UnityEngine;
+public class HeroSkinRoleLineCell : CellView
+{
+    [SerializeField] HeroSkinRoleCell[] skinRoleCells;
+
+    //index 涓� 涓存椂鍒楄〃鐨勭储寮�
+    public void Display(HeroConfig heroConfig, int index)
+    {
+        for (int i = 0; i < skinRoleCells.Length; i++)
+        {
+            if (index + i < HeroSkinChooseWin.activeIndexList.Count)
+            {
+                skinRoleCells[i].SetActive(true);
+                skinRoleCells[i].Display(heroConfig, HeroSkinChooseWin.activeIndexList[index + i]);
+            }
+            else
+            {
+                skinRoleCells[i].SetActive(false);
+            }
+
+        }
+    }
+}
diff --git a/Main/System/HeroUI/HeroSkinRoleLineCell.cs.meta b/Main/System/HeroUI/HeroSkinRoleLineCell.cs.meta
new file mode 100644
index 0000000..f210ed1
--- /dev/null
+++ b/Main/System/HeroUI/HeroSkinRoleLineCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 37364238198b1504d979cddfa353daee
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroUI/HeroSkinWin.cs b/Main/System/HeroUI/HeroSkinWin.cs
new file mode 100644
index 0000000..a97603c
--- /dev/null
+++ b/Main/System/HeroUI/HeroSkinWin.cs
@@ -0,0 +1,354 @@
+using System;
+using UnityEngine;
+using UnityEngine.UI;
+
+
+/// <summary>
+/// 姝﹀皢鐨偆
+/// </summary>
+public class HeroSkinWin : UIBase
+{
+    [SerializeField] RawImage bgTexture;
+    [SerializeField] Button showFuncBtn;    //鍙樉绀虹珛缁樻椂鐐瑰嚮锛屾樉绀哄姛鑳�
+    [SerializeField] Transform funcForm;
+    [SerializeField] UIHeroController roleLhModel;    //灞曠ず鑻遍泟绔嬬粯
+    [SerializeField] UIHeroController roleXsModel;  //鍍忕礌
+    [SerializeField] Button seeLhBtn;   //鏌ョ湅绔嬬粯
+    [SerializeField] Button previewFightBtn;   //棰勮鎴樻枟
+    [SerializeField] Button shopBtn;   //鍟嗗簵
+    [SerializeField] Button changeClothBtn;   //鍙洿鎹㈡湇瑁呭瑙�
+    [SerializeField] GradientText nameText;
+    [SerializeField] Text skinNameText;
+    // [SerializeField] Text skinLVText;
+    //灞炴�у尯
+    [SerializeField] Text[] onAttrText;    //绌挎埓灞炴��
+    [SerializeField] Text[] allAttrText; //鍏ㄤ綋鍔犳垚
+    [SerializeField] Transform attrObj;
+
+    [SerializeField] ScrollerController skinScroller;
+    [SerializeField] Button unlockBtn;
+    [SerializeField] Image itemIcon;
+    [SerializeField] Text itemCountText;
+    [SerializeField] Button putonBtn;
+    [SerializeField] GameObject putonYetObj;
+    [SerializeField] Button showGetObj;
+    [SerializeField] GameObject showNormalObj;
+
+
+    HeroConfig heroConfig;
+    int heroID;
+    int skinID;
+    public HeroInfo hero;
+    int tmpIndex;   //鐨偆鐣岄潰鍙互鍚屾椂浠庡浘閴村拰鍩瑰吇鐣岄潰鎵撳紑锛屾墍浠ラ渶瑕佷竴涓复鏃跺彉閲忔潵缂撳瓨閬垮厤鎶ラ敊
+
+    protected override void InitComponent()
+    {
+        showFuncBtn.AddListener(() =>
+        {
+            funcForm.SetActive(true);
+            ChangeParentWinAlpha(1);
+        });
+        seeLhBtn.AddListener(() =>
+        {
+            funcForm.SetActive(false);
+            ChangeParentWinAlpha(0);
+        });
+        previewFightBtn.AddListener(() =>
+        {
+            var config = HeroConfig.Get(heroID);
+            int index = Array.IndexOf(config.SkinIDList, skinID);
+            BattleManager.Instance.SendTurnFight(30000, valueList: new uint[] { (uint)heroID, (uint)index });
+        });
+        shopBtn.AddListener(() =>
+        {
+            UIManager.Instance.OpenWindow<StoreBaseWin>(1);
+        });
+        unlockBtn.AddListener(() =>
+        {
+            UnLockSkin();
+        });
+        putonBtn.AddListener(() =>
+        {
+            if (hero == null)
+            {
+                return;
+            }
+            HeroUIManager.Instance.SendSkinOP(heroID, skinID, 4, hero.itemHero.gridIndex);
+        });
+
+        showGetObj.AddListener(() =>
+        {
+            showGetObj.SetActive(false);
+            showNormalObj.SetActive(true);
+            ChangeParentWinAlpha(1);
+        });
+        
+        changeClothBtn.AddListener(() =>
+        {
+            UIManager.Instance.OpenWindow<HeroSkinChooseWin>();
+        });
+    }
+
+    int activeSkinID;
+    protected override void OnPreOpen()
+    {
+        activeSkinID = 0;
+        skinScroller.OnRefreshCell += OnRefreshCell;
+        if (functionOrder == 0)
+        {
+            //浠h〃浠庡煿鍏荤晫闈㈡墦寮�
+            hero = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectHeroGuid);
+            heroConfig = hero.heroConfig;
+            if (HeroUIManager.Instance.selectSkinIndex == -1)
+            {
+                HeroUIManager.Instance.selectSkinIndex = hero.SkinIndex;
+            }
+        }
+        else
+        {
+            //浠庡浘閴寸晫闈㈡墦寮�
+            heroConfig = HeroConfig.Get(HeroUIManager.Instance.selectForPreviewHeroID);
+
+            if (HeroUIManager.Instance.selectSkinIndex == -1)
+            {
+                HeroUIManager.Instance.selectSkinIndex = 0;
+            }
+        }
+        tmpIndex = HeroUIManager.Instance.selectSkinIndex;
+        heroID = heroConfig.HeroID;
+
+        HeroUIManager.Instance.OnSkinIndexChanged += OnSkinIndexChanged;
+        HeroUIManager.Instance.OnHeroCollectEvent += OnHeroCollectEvent;
+        PackManager.Instance.RefreshItemEvent += OnRefreshItemEvent;
+
+        showGetObj.SetActive(false);
+        showNormalObj.SetActive(true);
+
+        Display();
+        CreateScroller();
+    }
+
+    protected override void OnPreClose()
+    {
+        skinScroller.OnRefreshCell -= OnRefreshCell;
+        HeroUIManager.Instance.OnSkinIndexChanged -= OnSkinIndexChanged;
+        HeroUIManager.Instance.OnHeroCollectEvent -= OnHeroCollectEvent;
+        PackManager.Instance.RefreshItemEvent -= OnRefreshItemEvent;
+        hero = null;
+        heroConfig = null;
+        HeroUIManager.Instance.selectSkinIndex = -1;
+    }
+
+    public void Display()
+    {
+        //鍙寮傚父澶勭悊
+        if (HeroUIManager.Instance.selectSkinIndex >= heroConfig.SkinIDList.Length ||
+        HeroUIManager.Instance.selectSkinIndex < 0)
+        {
+            if (HeroUIManager.Instance.selectSkinIndex == -1)
+            {
+                HeroUIManager.Instance.selectSkinIndex = 0; //榛樿绗竴涓� 璇存槑鏄彟澶栧湴鏂规竻闄わ紙鍏抽棴锛�
+            }
+            tmpIndex = 0;
+        }
+        else
+        {
+            tmpIndex = HeroUIManager.Instance.selectSkinIndex;
+        }
+        
+        skinID = heroConfig.SkinIDList[tmpIndex];
+        bgTexture.SetTexture2D(HeroUIManager.Instance.GetBGName(skinID, heroConfig.Country));
+        roleLhModel.Create(skinID, 1, motionName: "", isLh: true);
+        roleXsModel.Create(skinID, 1);
+        HeroUIManager.Instance.PlayerLHSound(skinID);
+        nameText.text = heroConfig.Name;
+
+
+        switch (heroConfig.Quality)
+        {
+            case 3:
+                //fff8db
+                // nameText.topLeftColor = new Color(0.98f, 0.94f, 0.91f);
+                nameText.topLeftColor = new Color(1f, 1f, 1f);
+                //ffe050
+                nameText.bottomLeftColor = new Color(0.98f, 0.88f, 0.25f);
+                break;
+            case 4:
+                // ffe8db
+                // ff9250
+                // nameText.topLeftColor = new Color(0.98f, 0.94f, 0.91f);
+                nameText.topLeftColor = new Color(1f, 1f, 1f);
+                nameText.bottomLeftColor = new Color(0.98f, 0.41f, 0.25f);
+                break;
+            case 5:
+                // ffdbdb
+                // ff5050
+                // nameText.topLeftColor = new Color(0.98f, 0.88f, 0.88f);
+                nameText.topLeftColor = new Color(1f, 1f, 1f);
+                nameText.bottomLeftColor = new Color(0.98f, 0.25f, 0.25f);
+                break;
+        }
+
+        skinNameText.text = HeroSkinConfig.Get(skinID).SkinName;
+        RefreshAttr();
+        ShowBtns();
+        HeroUIManager.Instance.skinRedpoint.state = HeroUIManager.Instance.HeroAllSkinStateForRedpoint(heroID, hero == null) > 0 ? RedPointState.Simple : RedPointState.None;
+    }
+
+
+
+    void RefreshAttr()
+    {
+        var cfg = HeroSkinAttrConfig.Get(skinID);
+        if (cfg == null)
+        {
+            attrObj.SetActive(false);
+            return;
+        }
+        attrObj.SetActive(true);
+        string format = "{0}" + UIHelper.AppendColor(TextColType.Green, "+{1}", false);
+        for (int i = 0; i < onAttrText.Length; i++)
+        {
+            if (i < cfg.WearAttrIDList.Length)
+            {
+                onAttrText[i].text = PlayerPropertyConfig.GetFullDescription(cfg.WearAttrIDList[i], cfg.WearAttrValueList[i], format);
+            }
+            else
+            {
+                onAttrText[i].text = "";
+            }
+        }
+
+        for (int i = 0; i < allAttrText.Length; i++)
+        {
+            if (i < cfg.RoleAttrIDList.Length)
+            {
+                allAttrText[i].text = PlayerPropertyConfig.GetFullDescription(cfg.RoleAttrIDList[i], cfg.RoleAttrValueList[i], format);
+            }
+            else
+            {
+                allAttrText[i].text = "";
+            }
+        }
+
+    }
+
+    void CreateScroller()
+    {
+        skinScroller.Refresh();
+        for (int i = 0; i < heroConfig.SkinIDList.Length; i++)
+        {
+            skinScroller.AddCell(ScrollerDataType.Header, i);
+        }
+        skinScroller.Restart();
+        if (tmpIndex > 2)
+        {
+            skinScroller.JumpIndex(tmpIndex - 1);
+        }
+    }
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as HeroSkinCell;
+        _cell.Display(heroID, cell.index, hero != null);
+    }
+
+    void OnSkinIndexChanged()
+    {
+        Display();
+        skinScroller.m_Scorller.RefreshActiveCellViews();
+    }
+
+    void OnHeroCollectEvent()
+    {
+        if (activeSkinID == skinID && HeroUIManager.Instance.IsHeroSkinActive(heroID, skinID))
+        {
+            showGetObj.SetActive(true);
+            ChangeParentWinAlpha(0);
+            showNormalObj.SetActive(false);
+            Display();
+            skinScroller.m_Scorller.RefreshActiveCellViews();
+            activeSkinID = 0;
+            return;
+        }
+    }
+
+    void OnRefreshItemEvent(PackType type, int index, int itemID)
+    {
+        if (type == PackType.Hero)
+        {
+            ShowBtns();
+            skinScroller.m_Scorller.RefreshActiveCellViews();
+        }
+    }
+
+    void UnLockSkin()
+    {
+        var cfg = HeroSkinAttrConfig.Get(skinID);
+        if (cfg == null)
+        {
+            return;
+        }
+        if (!ItemLogicUtility.CheckItemCount(PackType.Item, cfg.NeedItemID, 1, 2))
+        {
+            return;
+        }
+        activeSkinID = skinID;
+        HeroUIManager.Instance.SendSkinOP(heroID, skinID, 1);
+    }
+
+    void ShowBtns()
+    {
+        if (hero == null)
+        {
+            putonBtn.SetActive(false);
+            putonYetObj.SetActive(false);
+            shopBtn.SetActive(false);
+            changeClothBtn.SetActive(false);
+        }
+        else
+        {
+            shopBtn.SetActive(true);
+            changeClothBtn.SetActive(true);
+        }
+
+        if (!HeroUIManager.Instance.IsHeroSkinActive(heroID, skinID))
+        {
+            var cfg = HeroSkinAttrConfig.Get(skinID);
+            if (cfg == null)
+            {
+                unlockBtn.SetActive(false);
+            }
+            else
+            {
+                unlockBtn.SetActive(true);
+                int itemID = cfg.NeedItemID;
+                itemIcon.SetItemSprite(itemID);
+                itemCountText.text = UIHelper.ShowUseItem(PackType.Item, itemID, 1, bright: false);
+            }
+            putonBtn.SetActive(false);
+            putonYetObj.SetActive(false);
+            return;
+        }
+        unlockBtn.SetActive(false);
+
+        if (hero == null) return;
+
+        putonBtn.SetActive(hero.SkinAttrID != skinID);
+        putonYetObj.SetActive(hero.SkinAttrID == skinID);
+
+
+    }
+
+    void ChangeParentWinAlpha(float alpha)
+    {
+        if (hero != null)
+        {
+            UIManager.Instance.GetUI<HeroTrainBaseWin>().GetCanvasGroup().alpha = alpha;
+        }
+        else
+        {
+            UIManager.Instance.GetUI<HeroBestBaseWin>().GetCanvasGroup().alpha = alpha;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/System/HeroUI/HeroSkinWin.cs.meta b/Main/System/HeroUI/HeroSkinWin.cs.meta
new file mode 100644
index 0000000..9ecb7a6
--- /dev/null
+++ b/Main/System/HeroUI/HeroSkinWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 43e5706b2aee0df459589c7482f9d8ad
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroUI/HeroTrainBaseWin.cs b/Main/System/HeroUI/HeroTrainBaseWin.cs
new file mode 100644
index 0000000..7b3c9f8
--- /dev/null
+++ b/Main/System/HeroUI/HeroTrainBaseWin.cs
@@ -0,0 +1,95 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+// 姝﹀皢鍔熻兘鐣岄潰
+public class HeroTrainBaseWin : OneLevelWin
+{
+
+
+    protected override void OpenSubUIByTabIndex()
+    {
+        ShowSkinBtn();
+        switch (functionOrder)
+        {
+            case 0:
+
+                //鍩瑰吇
+                if (UIManager.Instance.IsOpened<HeroTrainWin>())
+                {
+                    UIManager.Instance.CloseWindow<HeroTrainWin>();
+                }
+                currentSubUI = UIManager.Instance.OpenWindow<HeroTrainWin>();
+
+                if (GetSortingOrder() < currentSubUI.GetSortingOrder())
+                {
+                    SetSortingOrder(currentSubUI.GetSortingOrder() + 1);
+                }
+                break;
+            case 1:
+                //绐佺牬
+                if (UIManager.Instance.IsOpened<HeroTrainWin>())
+                {
+                    UIManager.Instance.CloseWindow<HeroTrainWin>();
+                }
+                currentSubUI = UIManager.Instance.OpenWindow<HeroTrainWin>(1);
+
+                if (GetSortingOrder() < currentSubUI.GetSortingOrder())
+                {
+                    SetSortingOrder(currentSubUI.GetSortingOrder() + 1);
+                }
+                break;
+            case 2:
+                //鐨偆
+                currentSubUI = UIManager.Instance.OpenWindow<HeroSkinWin>();
+
+                if (GetSortingOrder() < currentSubUI.GetSortingOrder())
+                {
+                    SetSortingOrder(currentSubUI.GetSortingOrder() + 1);
+                }
+                break;
+            default:
+                Debug.LogWarning("鏈煡鐨勬爣绛剧储寮�: " + functionOrder);
+                break;
+        }
+
+    }
+
+    //鏈夌殑姝﹀皢娌℃湁鐨偆
+    public void ShowSkinBtn()
+    {
+        if (string.IsNullOrEmpty(HeroUIManager.Instance.selectHeroGuid))
+        {
+            return;
+        }
+        var config = HeroManager.Instance.GetHero(HeroUIManager.Instance.selectHeroGuid).heroConfig;
+        tabButtons[2].SetActive(config.SkinIDList.Length > 1);
+    }
+
+
+    //鍏朵粬鐣岄潰鍜屾鐣岄潰鐨勫眰绾ф樉绀洪棶棰�
+    protected override void OnPreOpen()
+    {
+        base.OnPreOpen();
+        UIManager.Instance.OnAfterSortWinLayer += OnAfterSortWinLayer;
+
+    }
+
+    protected override void OnPreClose()
+    {
+        base.OnPreClose();
+        UIManager.Instance.OnAfterSortWinLayer -= OnAfterSortWinLayer;
+    }
+
+    void OnAfterSortWinLayer()
+    {
+        if (currentSubUI == null) return;
+
+        if (GetSortingOrder() < currentSubUI.GetSortingOrder())
+        {
+            SetSortingOrder(currentSubUI.GetSortingOrder() + 1);
+        }
+    }
+
+
+}
diff --git a/Main/System/HeroUI/HeroTrainBaseWin.cs.meta b/Main/System/HeroUI/HeroTrainBaseWin.cs.meta
new file mode 100644
index 0000000..78cc2ad
--- /dev/null
+++ b/Main/System/HeroUI/HeroTrainBaseWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0b3eddca22f174c448766192183bd9a2
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/HeroUI/HeroTrainWin.cs b/Main/System/HeroUI/HeroTrainWin.cs
index e0b5aaf..f08d797 100644
--- a/Main/System/HeroUI/HeroTrainWin.cs
+++ b/Main/System/HeroUI/HeroTrainWin.cs
@@ -104,11 +104,9 @@
     // 鍖哄垎绐佺牬鍜屽煿鍏绘ā鍧�
     [SerializeField] HeroLVBreakCell heroLVBreakCell;   //瀵瑰簲鍩瑰吇鐨� allAttrScroll  鍜� attrBtn
 
-    [SerializeField] GroupButtonEx trainMainButton; //鍩瑰吇鍏ュ彛鎸夐挳
-    [SerializeField] GroupButtonEx breakMainButton; //绐佺牬鍏ュ彛鎸夐挳
-    //鍏ュ彛浼孩鐐圭敤鍥剧墖浠f浛
-    [SerializeField] Image trainMainRedImg;
-    [SerializeField] Image breakMainRedImg;
+
+    bool isTrainMainRed;
+    bool isBreakMainRed;
     #endregion
 
 
@@ -124,10 +122,12 @@
         showFuncBtn.AddListener(() =>
         {
             funcForm.SetActive(true);
+            UIManager.Instance.GetUI<HeroTrainBaseWin>().GetCanvasGroup().alpha = 1;
         });
         seeLhBtn.AddListener(() =>
         {
             funcForm.SetActive(false);
+            UIManager.Instance.GetUI<HeroTrainBaseWin>().GetCanvasGroup().alpha = 0;
         });
         closeBtn.AddListener(CloseWindow);
         rightBtn.AddListener(() =>
@@ -205,25 +205,13 @@
             freezeTipGo.SetActive(!freezeTipGo.activeSelf);
         });
 
-        trainMainButton.AddListener(() =>
-        {
-            functionOrder = 0;
-            DisplayTrainOrBreak(hero);
-            ForceRefreshLayout();
-        });
-
-        breakMainButton.AddListener(() =>
-        {
-            functionOrder = 1;
-            DisplayTrainOrBreak(hero);
-            unfoldState = false;
-            RefreshFoldState();
-        });
     }
 
 
     protected override void OnPreOpen()
     {
+   
+
         PackManager.Instance.RefreshItemLockEvent += RefreshItemLockEvent;
         HeroManager.Instance.onHeroChangeEvent += RefreshHeroEvent;
         UIManager.Instance.OnCloseWindow += OnCloseWindow;
@@ -232,10 +220,25 @@
 
         guid = HeroUIManager.Instance.selectHeroGuid;
         hero = HeroManager.Instance.GetHero(guid);
+
+        if (functionOrder == 0)
+        {
+            DisplayTrainOrBreak(hero);
+            ForceRefreshLayout();
+        }
+        else if (functionOrder == 1)
+        {
+            DisplayTrainOrBreak(hero);
+            unfoldState = false;
+            RefreshFoldState();
+        }
+
+
         unfoldState = false;
         addPerObject.SetActive(false);
         allAttrScroll.verticalNormalizedPosition = 1;
         Display();
+        HeroUIManager.Instance.PlayerLHSound(hero.SkinID);
     }
 
 
@@ -263,8 +266,9 @@
 
     public void Display()
     {
-        bgTexture.SetTexture2D("countryBG" + hero.heroConfig.Country);
+        bgTexture.SetTexture2D(HeroUIManager.Instance.GetBGName(hero.SkinID, hero.heroConfig.Country));
         roleLhModel.Create(hero.SkinID, 1, motionName: "", isLh: true);
+        
         roleXsModel.Create(hero.SkinID, 1);
         jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(hero.heroConfig.Class));
         jobPosNameText.text = HeroUIManager.Instance.GetJobName(hero.heroConfig.Class);
@@ -295,6 +299,8 @@
         RefreshAwake();
         RefreshFreeze();
         RefreshRedImg();
+        HeroUIManager.Instance.UpdateTheHeroCardRedpoint(isTrainMainRed, isBreakMainRed,
+            HeroUIManager.Instance.HeroAllSkinStateForRedpoint(hero.heroId) > 0);
         DisplayTrainOrBreak(hero);
         ShowDeleteTip();
 
@@ -393,9 +399,18 @@
         {
             resultIndex = 0;
         }
-        guid = HeroUIManager.Instance.heroSortList[resultIndex];
+        guid = HeroUIManager.Instance.selectHeroGuid = HeroUIManager.Instance.heroSortList[resultIndex];
         hero = HeroManager.Instance.GetHero(guid);
         Display();
+
+        HeroUIManager.Instance.PlayerLHSound(hero.SkinID);
+
+        //鎺у埗涓�绾у姛鑳界晫闈㈢殑鐨偆鎸夐挳
+        var ui = UIManager.Instance.GetUI<HeroTrainBaseWin>();
+        if (ui != null)
+        {
+            ui.ShowSkinBtn();
+        }
     }
 
 
@@ -877,8 +892,8 @@
         redpointAwake.SetActive(false);
         redpointGift.SetActive(false);
         redpointLVUP.SetActive(false);
-        trainMainRedImg.SetActive(false);
-        breakMainRedImg.SetActive(false);
+        isTrainMainRed = false;
+        isBreakMainRed = false;
         redpointBreakLVUP.SetActive(false);
 
 
@@ -889,7 +904,7 @@
         if (heroCnt > 1 && hero.heroStar < hero.GetCurMaxStar())
         {
             redpointGift.SetActive(true);
-            trainMainRedImg.SetActive(true);
+            isTrainMainRed = true;
         }
 
 
@@ -900,7 +915,7 @@
             if (itemPack.GetCountById(lvupConfig.UPCostItem[0]) >= lvupConfig.UPCostItem[1])
             {
                 redpointLVUP.SetActive(true);
-                trainMainRedImg.SetActive(true);
+                isTrainMainRed = true;
             }
         }
 
@@ -922,7 +937,7 @@
                 if (itemPack.GetCountById(config.UPCostItem[0]) >= config.UPCostItem[1])
                 {
                     redpointAwake.SetActive(true);
-                    trainMainRedImg.SetActive(true);
+                    isTrainMainRed = true;
                 }
             }
         }
@@ -930,7 +945,7 @@
         if (HeroUIManager.Instance.IsCanBreak(hero))
         {
             redpointBreakLVUP.SetActive(true);
-            breakMainRedImg.SetActive(true);
+            isBreakMainRed = true;
         }
 
     }
@@ -945,7 +960,6 @@
             heroLVBreakCell.SetActive(false);
             allAttrScroll.SetActive(true);
             attrBtn.SetActive(true);
-            trainMainButton.SelectBtn();
         }
         else
         {
@@ -954,7 +968,6 @@
             attrBtn.SetActive(false);
 
             heroLVBreakCell.Display(hero);
-            breakMainButton.SelectBtn();
         }
     }
 
diff --git a/Main/System/HeroUI/HeroUIManager.Collect.cs b/Main/System/HeroUI/HeroUIManager.Collect.cs
index 03caf26..924e3a2 100644
--- a/Main/System/HeroUI/HeroUIManager.Collect.cs
+++ b/Main/System/HeroUI/HeroUIManager.Collect.cs
@@ -22,18 +22,93 @@
 
     // public int allHeroBookPer; //鍏ㄤ綋姝﹀皢鐨勫浘閴存縺娲荤櫨鍒嗘瘮
     public event Action OnHeroCollectEvent;
-
+    public event Action<int, int, int> OnHeroSkinStateChanged;// 鐨偆鐘舵�佸彉鍖栦簨浠� (鍙傛暟: HeroID, SkinID, 鏂扮殑State)
     public void UpdateHeroCollectInfo(HB122_tagSCHeroInfo netPack)
     {
         for (int i = 0; i < netPack.HeroCnt; i++)
         {
-            heroCollectInfoDic[(int)netPack.HeroInfoList[i].HeroID] = netPack.HeroInfoList[i];
+            var newHeroData = netPack.HeroInfoList[i];
+            int heroID = (int)newHeroData.HeroID;
+
+            // 1. 璋冪敤灏佽濂界殑鏂规硶锛氭娴嬪苟瑙﹀彂鏂扮毊鑲や簨浠�
+            CheckAndTriggerNewSkinEvents(heroID, newHeroData);
+
+            // 2. 鏇存柊瀛楀吀涓烘渶鏂扮殑缃戠粶鍖呮暟鎹�
+            heroCollectInfoDic[heroID] = newHeroData;
         }
+
         // allHeroBookPer = GetHeroCollectBookPer();
-        OnHeroCollectEvent?.Invoke();
         UpdateHeroBookRedpoint();
+        RefreshAllSkinAttr();
+        UpdateHeroCardSkinRedpoint();
+        UpdateHeroBookRedpoint();
+        OnHeroCollectEvent?.Invoke();
     }
 
+    public event Action<int, int> OnNewSkinAcquired;// 褰撶帺瀹惰幏寰楁柊鐨偆锛堟縺娲荤毊鑲わ級鏃惰Е鍙戠殑浜嬩欢 HeroID SkinID
+
+    /// <summary>
+    /// 妫�鏌ュ苟瑙﹀彂鑾峰緱鏂扮毊鑲ょ殑浜嬩欢
+    /// </summary>
+    private void CheckAndTriggerNewSkinEvents(int heroID, HB122_tagSCHeroInfo.tagSCHero newHeroData)
+    {
+        // 濡傛灉鏂版暟鎹腑娌℃湁鐨偆淇℃伅锛岀洿鎺ヨ繑鍥�
+        if (newHeroData?.SkinList == null || newHeroData?.SkinCnt <= 0) return;
+
+        // 灏濊瘯鑾峰彇鏃ф暟鎹�
+        bool isOldHeroExist = heroCollectInfoDic.TryGetValue(heroID, out var oldHeroData);
+
+        for (int j = 0; j < newHeroData.SkinCnt; j++)
+        {
+            var newSkin = newHeroData.SkinList[j];
+            
+            // 濡傛灉鏂扮毊鑲ゆ湭婵�娲伙紝鐩存帴璺宠繃褰撳墠寰幆锛屾鏌ヤ笅涓�涓毊鑲�
+            if (newSkin.State <= 0) continue;
+
+            bool isNewlyAcquired = false;
+
+            if (!isOldHeroExist)
+            {
+                // 鍦烘櫙A锛氳繖鏄竴涓叏鏂扮殑姝﹀皢锛屼笖鑷甫浜嗗凡婵�娲荤殑闈為粯璁ょ毊鑲�
+                isNewlyAcquired = true;
+            }
+            else
+            {
+                // 鍦烘櫙B锛氬凡鏈夌殑鑰佹灏嗭紝闇�瑕佸姣旀棫鏁版嵁鐪嬭繖涓毊鑲ゆ槸涓嶆槸鍒氬垰鎵嶈幏寰楃殑
+                bool foundOldSkin = false;
+
+                if (oldHeroData.SkinList != null)
+                {
+                    for (int k = 0; k < oldHeroData.SkinCnt; k++)
+                    {
+                        var oldSkin = oldHeroData.SkinList[k];
+                        if (oldSkin.SkinID == newSkin.SkinID)
+                        {
+                            foundOldSkin = true;
+                            // 濡傛灉鏃ф暟鎹腑璇ョ毊鑲ゆ湭婵�娲� (State == 0)锛岀幇鍦ㄦ縺娲讳簡锛岀畻浣滆幏寰楁柊鐨偆
+                            if (oldSkin.State == 0)
+                            {
+                                isNewlyAcquired = true;
+                            }
+                            break; 
+                        }
+                    }
+                }
+
+                // 濡傛灉鏃ф灏嗘暟鎹噷鍘嬫牴娌℃湁杩欎釜鐨偆鐨勬暟鎹紙鐜板湪鏄縺娲荤姸鎬侊級锛屼篃绠椾綔鑾峰緱鏂扮毊鑲�
+                if (!foundOldSkin)
+                {
+                    isNewlyAcquired = true;
+                }
+            }
+
+            // 濡傛灉鏈�缁堝垽瀹氫负鈥滃叏鏂拌幏寰椻�濈殑鐨偆锛屽垯瑙﹀彂浜嬩欢
+            if (isNewlyAcquired)
+            {
+                OnNewSkinAcquired?.Invoke(heroID, (int)newSkin.SkinID);
+            }
+        }
+    }
 
     // public int GetHeroCollectBookPer()
     // {
@@ -87,6 +162,9 @@
             HeroConfig heroConfig = HeroConfig.Get(heroID);
             if (heroConfig.PlayerCanUse == 0)
                 continue;
+            // 鏂板锛氬紑鏈嶇x澶╂樉绀哄浘閴达紝0琛ㄧず涓嶉檺鍒跺紑鏈嶅ぉ
+            if (heroConfig.OpenCollectionDay > 0 && TimeUtility.OpenDay + 1 < heroConfig.OpenCollectionDay)
+                continue;
             if (!heroCollectDict.ContainsKey(heroConfig.Quality))
             {
                 heroCollectDict[heroConfig.Quality] = new List<int>();
@@ -135,34 +213,40 @@
         _list.Reverse();
         foreach (var quality in _list)
         {
+            // 鎺掑簭閫昏緫锛氫紭鍏堟寜闃佃惀鍒嗙粍鎺掑簭锛屽悓闃佃惀涓寜寮�鏈嶅ぉ鏁伴檷搴忔帓搴忥紝鏈�鍚庢寜姝﹀皢ID鎺掑簭
+            heroCollectDict[quality].Sort((a, b) =>
+            {
+                var cfgA = HeroConfig.Get(a);
+                var cfgB = HeroConfig.Get(b);
+
+                // 1. 鎸夐樀钀�(鍥藉)鎺掑簭
+                if (cfgA.Country != cfgB.Country)
+                {
+                    return cfgA.Country.CompareTo(cfgB.Country);
+                }
+
+                // 2. 鍚岄樀钀ヤ腑锛屽紑鏈嶅ぉ鏁拌秺澶х殑鎺掑簭瓒婇潬鍓� (闄嶅簭)
+                if (cfgA.OpenCollectionDay != cfgB.OpenCollectionDay)
+                {
+                    return cfgB.OpenCollectionDay.CompareTo(cfgA.OpenCollectionDay);
+                }
+
+                // 3. 鍏朵粬鏉′欢涓�鑷存椂锛岄粯璁ゆ寜姝﹀皢ID鍗囧簭
+                return a.CompareTo(b);
+            });
+            
             heroCollectList.AddRange(heroCollectDict[quality]);
         }
     }
 
-    //鍥鹃壌鎬讳笂闄愮瓑绾� = 鍥鹃壌鏄熺骇涓婇檺 + 鍥鹃壌绐佺牬涓婇檺
-    public int GetHeroBookMaxLevel(int heroID, int quality)
-    {
-        return GetMaxStarCount(heroID, quality) + HeroBreakConfig.GetMaxBreakLv(heroID);
-    }
 
-    public int GetHeroBookLevel(int heroID)
-    {
-        if (heroCollectInfoDic.ContainsKey(heroID))
-        {
-            return heroCollectInfoDic[heroID].BookStarLV + heroCollectInfoDic[heroID].BookBreakLV;
-        }
-        return 0;
-    }
-
-    //鍒嗕负0鏈幏寰椼��1鍙縺娲汇��2甯歌銆�3绐佺牬鍗囩骇銆�4銆佹槦鍗囩骇銆�5宸叉弧绾�
+    //鍒嗕负0鏈幏寰椼��1鍙縺娲汇��2甯歌銆侊紙3绐佺牬鍗囩骇銆�4銆佹槦鍗囩骇銆�5宸叉弧绾� 搴熷純鍔熻兘淇濈暀閫昏緫锛�
     public int GetHeroBookState(int heroID, int quality)
     {
         int funcState = 0;
 
         HB122_tagSCHeroInfo.tagSCHero colData;
         TryGetHeroBookInfo(heroID, out colData);
-        // int maxBreakLV = colData.BookBreakLVH; //鍘嗗彶鏈�楂樼獊鐮寸瓑绾�
-        // int maxStarLV = colData.BookStarLVH;  //鍘嗗彶鏈�楂樻槦绾�
 
         if (colData.BookInitState == 0)
         {
@@ -231,5 +315,105 @@
     //     }
     //     return config.BookInitAddPer + heroData.BookStarLV * config.BookStarAddPer + heroData.BookBreakLV * config.BookBreakLVAddPer;
     // }
+
+    #region 鐨偆
+    //绛栧垝鍘婚櫎浜嗗崌鏄熷姛鑳�
+    //灞炴�у垎绌挎埓(姝﹀皢涓綋)鍜屽叏浣�
+    public Dictionary<int, long> allSkinAttrDic = new Dictionary<int, long>();
+    int m_selectSkinIndex = -1;
+    public event Action OnSkinIndexChanged;
+    public int selectSkinIndex
+    {
+        get { return m_selectSkinIndex; }
+        set
+        {
+            m_selectSkinIndex = value;
+            OnSkinIndexChanged?.Invoke();
+        }
+    }
+
+    //鍏ㄤ綋灞炴��
+    public void RefreshAllSkinAttr()
+    {
+        allSkinAttrDic.Clear();
+        foreach (var config in HeroSkinAttrConfig.GetValues())
+        {
+            var heroID = HeroConfig.GetHeroIDBySkinID(config.SkinID);
+            if (heroID == 0)
+            {
+                Debug.LogError("涓嶅瓨鍦ㄧ殑鐨偆 鐨偆灞炴�ц〃閰嶇疆閿欒 锛�" + config.SkinID);
+                continue;
+            }
+            if (!IsHeroSkinActive(heroID, config.SkinID))
+            {
+                continue;
+            }
+            for (int i = 0; i < config.RoleAttrIDList.Length; i++)
+            {
+                if (!allSkinAttrDic.ContainsKey(config.RoleAttrIDList[i]))
+                {
+                    allSkinAttrDic[config.RoleAttrIDList[i]] = 0;
+                }
+                allSkinAttrDic[config.RoleAttrIDList[i]] += config.RoleAttrValueList[i];
+            }
+        }
+
+    }
+
+    public bool IsHeroSkinActive(int heroID, int skinID)
+    {
+        //榛樿鐨偆杩斿洖true
+        if (HeroConfig.Get(heroID).SkinIDList[0] == skinID)
+        {
+            return true;
+        }
+        HB122_tagSCHeroInfo.tagSCHero colData;
+        TryGetHeroBookInfo(heroID, out colData);
+
+        if (colData != null && colData.SkinList != null)
+        {
+            foreach (var data in colData.SkinList)
+            {
+                if (data.SkinID != skinID)
+                {
+                    continue;
+                }
+                return data.State == 1;
+            }
+        }
+
+        return false;
+    }
+
+    public long GetSkinAttrValue(int attrID)
+    {
+        allSkinAttrDic.TryGetValue(attrID, out long value);
+        return value;
+    }
+
+    public int GetSkinAttrPer(int attrID)
+    {
+        if (PlayerPropertyConfig.baseAttr2perDict.ContainsKey(attrID))
+        {
+            var pertype = PlayerPropertyConfig.baseAttr2perDict[attrID];
+            allSkinAttrDic.TryGetValue(pertype, out long value);
+            return (int)(value);
+        }
+        return 0;
+    }
+
+    //鎿嶄綔 1-婵�娲伙紱2-閫夋嫨褰㈣薄锛�4-閫夋嫨灞炴��
+    public void SendSkinOP(int heroID, int skinID, int opType, int itemIndex = 0)
+    {
+        var pack = new CB236_tagCSHeroSkinOP();
+        pack.HeroID = (uint)heroID;
+        pack.SkinID = (uint)skinID;
+        pack.OPType = (byte)opType;
+        pack.ItemIndex = (ushort)itemIndex;
+        GameNetSystem.Instance.SendInfo(pack);
+
+    }
+
+    #endregion
 }
 
diff --git a/Main/System/HeroUI/HeroUIManager.cs b/Main/System/HeroUI/HeroUIManager.cs
index af0421a..da04202 100644
--- a/Main/System/HeroUI/HeroUIManager.cs
+++ b/Main/System/HeroUI/HeroUIManager.cs
@@ -112,6 +112,7 @@
     void OnLoginLoadOK()
     {
         UpdateHeroCardRedpoint();
+        UpdateHeroCardSkinRedpoint();
     }
 
     private void OnHeroChangeEvent(HeroInfo hero)
@@ -178,6 +179,17 @@
     }
 
     #region 姝﹀皢UI甯哥敤鎺ュ彛
+
+    //鑾峰緱姝﹀皢鑳屾櫙鍥剧墖鍚嶏紝濡傛灉娌℃湁閰嶇疆榛樿鐢ㄩ樀钀ュ浘
+    public string GetBGName(int skinID, int conutry)
+    {
+        var config = HeroSkinConfig.Get(skinID);
+        if (config != null && !string.IsNullOrEmpty(config.BG))
+        {
+            return config.BG;
+        }
+        return "countryBG" + conutry;
+    }
     public string GetCountryName(int index)
     {
         return RichTextMsgReplaceConfig.GetRichReplace("Country", index);
@@ -258,6 +270,19 @@
             }
         }
         return per;
+    }
+
+    public void PlayerLHSound(int skinID)
+    {
+        if (NewBieCenter.Instance.inGuiding)
+        {
+            return;
+        }
+        var audioID = HeroSkinConfig.Get(skinID).AudioID;
+        if (audioID > 0)
+        {
+            SoundPlayer.Instance.PlayNpcAudio(HeroSkinConfig.Get(skinID).AudioID);
+        }
     }
 
     #endregion
@@ -476,7 +501,7 @@
                 {
                     continue;
                 }
-                
+
                 heroCallSortList.Add(item);
             }
         }
@@ -561,7 +586,7 @@
         }
         return 0;
     }
-    
+
 
     #region 绾㈢偣
 
@@ -573,6 +598,8 @@
     Redpoint heroEatRedPoint = new Redpoint(MainRedDot.HeroCardRedpoint, MainRedDot.HeroCardRedpoint * 10 + 8);
     //鏂版爣璇嗙殑绾㈢偣 鎵�鏈夋灏嗙粺涓�涓�
     Redpoint newMarkRedPoint = new Redpoint(MainRedDot.HeroCardRedpoint, MainRedDot.HeroCardRedpoint * 10 + 9);
+    //鎵�鏈夋灏嗙殑鐨偆鍔熻兘涓�涓孩鐐�
+    Redpoint skinRedPoint = new Redpoint(MainRedDot.HeroCardRedpoint, MainRedDot.HeroCardRedpoint * 10 + 7);
     void InitHeroOnTeamRedpointList()
     {
         heroOnTeamRedpointList.Clear();
@@ -641,6 +668,26 @@
 
     }
 
+    //姝﹀皢鍒楄〃鐨勭毊鑲ょ孩鐐癸紝鍥鹃壌鐨偆绾㈢偣鍙﹀鍑芥暟鍒锋柊
+    void UpdateHeroCardSkinRedpoint()
+    {
+        skinRedPoint.state = RedPointState.None;
+        var _list = HeroManager.Instance.GetHeroList();
+        foreach (var hero in _list)
+        {
+            if (!hero.isAttrActive)
+            {
+                continue;
+            }
+
+            if (HeroAllSkinStateForRedpoint(hero.heroId) == 1)
+            {
+                skinRedPoint.state = RedPointState.Simple;
+                break;
+            }
+        }
+    }
+
 
     void InitHerosData()
     {
@@ -680,6 +727,12 @@
         {
             return true;
         }
+
+        if (HeroAllSkinStateForRedpoint(heroID, true) == 2)
+        {
+            return true;
+        }
+
         return false;
     }
 
@@ -697,6 +750,13 @@
                 redpoint.state = RedPointState.Simple;
                 continue;
             }
+
+            if (HeroAllSkinStateForRedpoint(heroID, true) == 2)
+            {
+                redpoint.state = RedPointState.Simple;
+                continue;
+            }
+
             redpoint.state = RedPointState.None;
         }
     }
@@ -720,6 +780,13 @@
         {
             refreshRedPoint = true;
         }
+
+        if (HeroSkinAttrConfig.itemIdToSkinIDDict.ContainsKey(itemID))
+        {
+            UpdateHeroCardSkinRedpoint();
+            UpdateHeroBookRedpoint();
+        }
+
     }
 
     void OnTeamChangeEvent(int teamType)
@@ -729,7 +796,83 @@
             refreshRedPoint = true;
         }
     }
+
+
+    //鍗曟灏嗙孩鐐� 鍙敤浜庣晫闈㈡墦寮�鐨勬椂鍊欑嫭绔嬩娇鐢�
+    public Redpoint trainRedpoint = new Redpoint(MainRedDot.HeroCardRedpoint * 100 + 1);
+    public Redpoint breakRedpoint = new Redpoint(MainRedDot.HeroCardRedpoint * 100 + 2);
+    public Redpoint skinRedpoint = new Redpoint(MainRedDot.HeroCardRedpoint * 100 + 3);
+
+    //寮�鍩瑰吇/鍥鹃壌鐣岄潰鍚庣殑绾㈢偣
+    public void UpdateTheHeroCardRedpoint(bool isTrainRed, bool isBreakRed, bool isSkinRed)
+    {
+        trainRedpoint.state = isTrainRed ? RedPointState.Simple :RedPointState.None;
+        breakRedpoint.state = isBreakRed ? RedPointState.Simple : RedPointState.None;
+        skinRedpoint.state = isSkinRed ? RedPointState.Simple : RedPointState.None;
+    }
+
+    //鎸囧畾鐨偆绾㈢偣鐘舵�� 0-鏃� 1-鏈夋灏嗙孩鐐瑰奖鍝嶆灏嗗垪琛ㄧ孩鐐癸紙鍋囩孩鐐癸級 2-鏃犳灏嗙孩鐐瑰奖鍝嶅浘閴寸晫闈㈢孩鐐�
+    public int HeroSkinStateForRedpoint(int skinID, bool isBook = false)
+    {
+        HeroSkinAttrConfig skinAttrConfig = HeroSkinAttrConfig.Get(skinID);
+        if (skinAttrConfig == null)
+        {
+            return 0;
+        }
+        var heroID = HeroConfig.GetHeroIDBySkinID(skinAttrConfig.SkinID);
+        HB122_tagSCHeroInfo.tagSCHero colData;
+        TryGetHeroBookInfo(heroID, out colData);
+
+        if (colData != null && colData.SkinList != null)
+        {
+            foreach (var data in colData.SkinList)
+            {
+                if (data.State != 0 && data.SkinID == skinAttrConfig.SkinID && data.Star >= skinAttrConfig.StarMax)
+                {
+                    //婊℃槦
+                    return 0;
+                }
+            }
+        }
+        if (PackManager.Instance.GetItemCountByID(PackType.Item, skinAttrConfig.NeedItemID) == 0)
+        {
+            return 0;
+        }
+        if (!isBook)
+        {
+            //闈炲浘閴磋皟鐢ㄧ殑鏃跺��
+            return 1;
+        }
+        if (HeroManager.Instance.GetHeroByID(heroID) != null)
+        {
+            return 1;
+        }
+        return 2;
+    }
+
+    //鎸囧畾姝﹀皢鐨勬墍鏈夌毊鑲ょ孩鐐圭姸鎬� 0-鏃� 1-鏈夋灏嗙孩鐐瑰奖鍝嶆灏嗗垪琛ㄧ孩鐐癸紙鍋囩孩鐐癸級 2-鏃犳灏嗙孩鐐瑰奖鍝嶅浘閴寸晫闈㈢孩鐐�
+    public int HeroAllSkinStateForRedpoint(int heroID, bool isBook = false)
+    {
+        var config = HeroConfig.Get(heroID);
+        for (int i = 0; i < config.SkinIDList.Length; i++)
+        {
+            var state = HeroSkinStateForRedpoint(config.SkinIDList[i], isBook);
+            if (isBook && state == 2)
+            {
+                return state;
+            }
+            else if (!isBook && state == 1)
+            {
+                return state;
+            }
+        }
+        return 0;
+    }
+
+
     #endregion
+
+
 }
 
 #region 绛夊緟鏈嶅姟绔搷搴�
diff --git a/Main/System/Horse/HorseController.cs b/Main/System/Horse/HorseController.cs
index 6605e3b..9d5dfbb 100644
--- a/Main/System/Horse/HorseController.cs
+++ b/Main/System/Horse/HorseController.cs
@@ -1,6 +1,5 @@
 
 using System;
-using Cysharp.Threading.Tasks;
 using Spine.Unity;
 using UnityEngine;
 using UnityEngine.UI;
@@ -21,9 +20,10 @@
 	private bool isHeroShowBefore = false;
 
 	// 鍒涘缓鍧愰獞 锛歩d涓�0绌哄潗楠戜篃鏈夐厤缃�
-	public async UniTask Create(int _skinID, int _heroSkinID = 0, float scale = 1f, Action _onComplete = null, string motionName = "idle")
+	//_skinID 鍧愰獞鐨勭毊鑲D
+	public void Create(int _skinID, int _heroSkinID = 0, float scale = 1f, Action _onComplete = null, string motionName = "idle")
 	{
-		pool = GameObjectPoolManager.Instance.GetPool(await UILoader.LoadPrefabAsync("UIHorse"));
+		pool = GameObjectPoolManager.Instance.GetPool(UILoader.LoadPrefab("UIHorse"));
 		if (instanceGO == null)
 		{
 			instanceGO = pool.Request();
@@ -70,85 +70,7 @@
 			return;
 		}
 
-		skeletonGraphic.skeletonDataAsset = await ResManager.Instance.LoadAssetAsync<SkeletonDataAsset>("UIEffect/Spine/Horse", skinConfig.Spine);
-		if (skeletonGraphic.skeletonDataAsset == null)
-		{
-
-			transform.SetActive(false);
-			if (pool != null)
-				pool.Release(instanceGO);
-			skeletonGraphic = null;
-			Destroy(instanceGO);
-			Debug.LogError("鏈厤缃畇pine");
-			return;
-		}
-		skeletonGraphic.enabled = true;
-		skeletonGraphic.Initialize(true);
-
-		skeletonGraphic.transform.localPosition = new Vector3(skinConfig.Poses[0], skinConfig.Poses[1], 0);
-		isHeroShowBefore = skinConfig.heroFirst == 1;
-		spineAnimationState = skeletonGraphic.AnimationState;
-		spineAnimationState.Data.DefaultMix = 0f;
-		if (motionName == "")
-			motionName = GetFistSpineAnim();
-		PlayAnimation(motionName, true);
-		CreateHero(_heroSkinID, scale);
-		spineAnimationState.Complete -= OnAnimationComplete;
-		spineAnimationState.Complete += OnAnimationComplete;
-	}
-
-	// 鍒涘缓鍧愰獞寮傛鐗堟湰
-	public async UniTask CreateAsync(int _skinID, int _heroSkinID = 0, float scale = 1f, Action _onComplete = null, string motionName = "idle")
-	{
-		pool = GameObjectPoolManager.Instance.GetPool(await UILoader.LoadPrefabAsync("UIHorse"));
-		if (this == null) return;
-		if (instanceGO == null)
-		{
-			instanceGO = pool.Request();
-			instanceGO.transform.SetParent(transform);
-			//transform 鐨凱ivot Y鏄�0锛岃instanceGO 灞呬腑
-			instanceGO.transform.localPosition = new Vector3(0, instanceGO.GetComponent<RectTransform>().sizeDelta.y * 0.5f);
-
-			//instanceGO.transform.localPosition = Vector3.zero;
-			instanceGO.transform.localScale = Vector3.one;
-			instanceGO.transform.localRotation = Quaternion.identity;
-		}
-		skeletonGraphic = instanceGO.transform.Find("Horse").GetComponent<SkeletonGraphic>();
-
-		if (skinID == _skinID)
-		{
-			if (skinID == 0)
-			{
-				skeletonGraphic.enabled = false;
-			}
-			CreateHero(_heroSkinID, scale);
-			//閬垮厤閲嶅鍒涘缓
-			return;
-		}
-
-		skinID = _skinID;
-		var skinConfig = HorseSkinConfig.Get(skinID);
-
-		this.transform.localScale = Vector3.one * scale;
-
-		onComplete = _onComplete;
-
-		if (!transform.gameObject.activeSelf)
-		{
-			transform.SetActive(true);
-		}
-
-
-		if (skinConfig == null || string.IsNullOrEmpty(skinConfig.Spine))
-		{
-			//鍗镐笅鍧愰獞鐨勬儏鍐�
-			skeletonGraphic.enabled = false;
-			spineAnimationState = null;
-			CreateHero(_heroSkinID, scale);
-			return;
-		}
-
-		skeletonGraphic.skeletonDataAsset = await ResManager.Instance.LoadAssetAsync<SkeletonDataAsset>("UIEffect/Spine/Horse", skinConfig.Spine);
+		skeletonGraphic.skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("UIEffect/Spine/Horse", skinConfig.Spine);
 		if (skeletonGraphic.skeletonDataAsset == null)
 		{
 
diff --git a/Main/System/InternalAffairs/GoldRushAutoBuyWin.cs b/Main/System/InternalAffairs/GoldRushAutoBuyWin.cs
index 383b1be..a36dc81 100644
--- a/Main/System/InternalAffairs/GoldRushAutoBuyWin.cs
+++ b/Main/System/InternalAffairs/GoldRushAutoBuyWin.cs
@@ -38,7 +38,7 @@
             //缁垂
             buyTipsText.text = Language.Get("GoldRush45", GoldRushManager.Instance.buyAutoDaysList[0]);
             RechargeManager.Instance.TryGetOrderInfo(GoldRushManager.Instance.buyAutoCTGIDList[0], out var orderInfo);
-            buyText.text = Language.Get("PayMoneyNum", orderInfo.PayRMBNumOnSale);
+            buyText.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfo.PayRMBNumOnSale));
             timeText.text = Language.Get("GoldRush48") + TimeUtility.SecondsToShortDHMS(endTime - TimeUtility.AllSeconds);
         }
     }
diff --git a/Main/System/InternalAffairs/GoldRushAutoWin.cs b/Main/System/InternalAffairs/GoldRushAutoWin.cs
index 467b3df..3004fae 100644
--- a/Main/System/InternalAffairs/GoldRushAutoWin.cs
+++ b/Main/System/InternalAffairs/GoldRushAutoWin.cs
@@ -95,7 +95,7 @@
             buyBtn.SetActive(true);
             buyTipsText.text = Language.Get("GoldRush45", GoldRushManager.Instance.buyAutoDaysList[0]);
             RechargeManager.Instance.TryGetOrderInfo(GoldRushManager.Instance.buyAutoCTGIDList[0], out var orderInfo);
-            buyText.text = Language.Get("PayMoneyNum", orderInfo.PayRMBNumOnSale);
+            buyText.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfo.PayRMBNumOnSale));
             autoBtn.SetActive(false);
         }
         else
diff --git a/Main/System/InternalAffairs/GoldRushRefreshWin.cs b/Main/System/InternalAffairs/GoldRushRefreshWin.cs
index c9da8d5..f34747a 100644
--- a/Main/System/InternalAffairs/GoldRushRefreshWin.cs
+++ b/Main/System/InternalAffairs/GoldRushRefreshWin.cs
@@ -238,6 +238,9 @@
         if (GoldRushManager.Instance.SendGoldRushOP(1, GoldRushManager.Instance.selectCampID, 0))
         {
             SysNotifyMgr.Instance.ShowTip("GoldRush4");
+            SysNotifyMgr.Instance.ShowStringTip(Language.Get("CostItemTip",
+                UIHelper.GetIconNameWithMoneyType(GoldRushManager.Instance.refreshMoneyType),
+                GoldRushManager.Instance.GetRefreshMoney(GoldRushManager.Instance.selectCampID)));
         }
 
     }
diff --git a/Main/System/Invest/InvestModel.cs b/Main/System/Invest/InvestModel.cs
index a8bb58c..378a301 100644
--- a/Main/System/Invest/InvestModel.cs
+++ b/Main/System/Invest/InvestModel.cs
@@ -4,7 +4,7 @@
 using UnityEngine.UI;
 using System.Linq;
 using LitJson;
-using Cysharp.Threading.Tasks;
+using UnityEngine;
 
 public class InvestModel : GameSystemManager<InvestModel>
 {
@@ -16,6 +16,9 @@
     Dictionary<int, int[][]> m_InvestItems = new Dictionary<int, int[][]>();
     Dictionary<int, int> m_InvestDays = new Dictionary<int, int>(); //鎶曡祫瀵瑰簲澶╂暟
     Dictionary<int, int> m_InvestMaxDays = new Dictionary<int, int>();  //鎶曡祫瀵瑰簲鏈�澶ц喘涔扮疮鍔犲ぉ鏁�
+
+    public Dictionary<int, int[]> textColors = new();
+    public Dictionary<int, int[]> outlineColors = new();
 
     //鎶曡祫瀵瑰簲鍏呭�糏D
     Dictionary<int, int[]> m_InvestRechargeIds = new Dictionary<int, int[]>();
@@ -43,7 +46,7 @@
     Dictionary<int, int> m_PrivilegeFightSpeed = new Dictionary<int, int>();
     // 鑻遍泟绉垎鎷涘嫙寮�鍚殑鐗规潈绫诲瀷
     int[] heroScoreCallOpenType;
-        
+
 
     public event Action<int> onInvestUpdate;
 
@@ -73,13 +76,25 @@
         return FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.PrivilegeCard);
     }
 
-    
+
     public void OnBeforePlayerDataInitialize()
     {
         m_InvestInfos.Clear();
         lastTotalBuyCountDict.Clear();
     }
 
+
+
+    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),
+        };
+    }
 
 
     void ParseConfig()
@@ -96,7 +111,6 @@
         m_InvestMaxDays = ConfigParse.ParseIntDict(funcConfig.Numerical2);
         m_InvestItems = ConfigParse.ParseIntArray2Dict(funcConfig.Numerical3);
 
-
         funcConfig = FuncConfigConfig.Get("InvestPower");
         m_InvestAddFBCount = ConfigParse.ParseDictInDict(funcConfig.Numerical1);
         m_InvestFreeFBID = ConfigParse.ParseIntArrayDict(funcConfig.Numerical2);
@@ -108,7 +122,27 @@
         m_PrivilegeLins = ConfigParse.ParseIntDict(funcConfig.Numerical1);
         m_PrivilegeFightSpeed = ConfigParse.ParseIntDict(funcConfig.Numerical2);
         heroScoreCallOpenType = JsonMapper.ToObject<int[]>(funcConfig.Numerical3);
-        
+        textColors = ConfigParse.ParseIntArrayDict(funcConfig.Numerical4);
+        outlineColors = ConfigParse.ParseIntArrayDict(funcConfig.Numerical5);
+
+    }
+
+    public Color32 GetTextColor(int vipLevel)
+    {
+        if (textColors.ContainsKey(vipLevel))
+        {
+            return ParseColor32(textColors[vipLevel]);
+        }
+        return Color.white;
+    }
+
+    public Color32 GetOutlineColor(int vipLevel)
+    {
+        if (outlineColors.ContainsKey(vipLevel))
+        {
+            return ParseColor32(outlineColors[vipLevel]);
+        }
+        return Color.white;
     }
 
     Dictionary<int, int> lastTotalBuyCountDict = new Dictionary<int, int>();
@@ -129,7 +163,7 @@
             if (count < rechargeCount.totalCount)
             {
                 lastTotalBuyCountDict[type] = rechargeCount.totalCount;
-                UIManager.Instance.OpenWindowAsync<PrivilegeActiveCardWin>(type).Forget();
+                UIManager.Instance.OpenWindow<PrivilegeActiveCardWin>(type);
             }
         }
     }
@@ -176,7 +210,7 @@
             //鏈堝崱 闄愭椂绫诲瀷鐨勬姇璧� 鏈埌鏈熷氨绠楁姇璧�
             return m_InvestInfos[type].InvestEndTime > 0 && m_InvestInfos[type].InvestEndTime > TimeUtility.AllSeconds;
         }
-        
+
         //姘镐箙绫诲瀷鐨勬姇璧� 鍙璐拱浜嗗氨绠楁姇璧�
         return m_InvestInfos[type].InvestBuyTime > 0;
     }
diff --git a/Main/System/ItemTip/BoxGetItemModel.cs b/Main/System/ItemTip/BoxGetItemModel.cs
index f044c67..b4fc9ec 100644
--- a/Main/System/ItemTip/BoxGetItemModel.cs
+++ b/Main/System/ItemTip/BoxGetItemModel.cs
@@ -39,21 +39,39 @@
             long expValue = netPack.Exp + netPack.ExpPoint * Constants.ExpPointValue;
             showItems.Add(new Item(GeneralDefine.expDisplayId, expValue));
         }
+
+        bool isMergeItem = true; //鍚屾牱鐨勭墿鍝佹槸鍚﹀悎骞舵樉绀猴紝姣斿棰濆鑾峰緱鍋氳〃鐜板垎寮�鏄剧ず
+
+        //鐗规畩澶勭悊锛屾椂瑁呮湁琚垎瑙f垚璐у竵鐨勬儏鍐碉紝闇�瑕佸悎骞跺悗鍘婚櫎鍘熸椂瑁呯殑鏄剧ず
+        List<int> deleteItemIDs = new List<int>();
         if (netPack.MoneyList.Length != 0)
         {
             for (int i = 0; i < netPack.MoneyLen; i++)
             {
                 var moneyType = netPack.MoneyList[i].MoneyType;
+                if (moneyType == 58 && !string.IsNullOrEmpty(netPack.DataEx))
+                {
+                    //鏃惰璐у竵
+                    int deleteID;
+                    int.TryParse(netPack.DataEx, out deleteID);
+                    if (deleteID != 0)
+                    {
+                        deleteItemIDs.Add(int.Parse(netPack.DataEx));
+                    }
+                }
                 if (GeneralDefine.MoneyDisplayModel.ContainsKey(moneyType) && netPack.MoneyList[i].MoneyValue != 0)
                 {
-                    showItems.Add(new Item(GeneralDefine.MoneyDisplayModel[moneyType], netPack.MoneyList[i].MoneyValue));
+                    showItems.Add(new Item(GeneralDefine.MoneyDisplayModel[moneyType], netPack.MoneyList[i].MoneyValue, netPack.MoneyList[i].IsBind));
+                    if (netPack.MoneyList[i].IsBind >= 10)
+                    {
+                        isMergeItem = false;
+                    }
                 }
-
             }
         }
 
-        bool isMergeItem = true;
-        //绾﹀畾IsBind=10 涓哄彜瀹濋澶栧鍔�
+        
+        //绾﹀畾IsBind 涓鸿鏍囩殑鐗规畩鏄剧ず 鍙傝�僆tem鐨剈seType瀹氫箟
         if (netPack.ItemList.Length != 0)
         {
             for (int i = 0; i < netPack.ItemLen; i++)
@@ -76,7 +94,7 @@
         if (showItems.Count == 0)
             return;
 
-        ItemLogicUtility.Instance.ShowGetItem(showItems, eventName, isMergeItem:isMergeItem);
+        ItemLogicUtility.Instance.ShowGetItem(showItems, eventName, isMergeItem:isMergeItem, deleteItemIDs:deleteItemIDs);
     }
 
 
diff --git a/Main/System/ItemTip/ItemTipWayWin.cs b/Main/System/ItemTip/ItemTipWayWin.cs
index 90d1726..ff5f6ea 100644
--- a/Main/System/ItemTip/ItemTipWayWin.cs
+++ b/Main/System/ItemTip/ItemTipWayWin.cs
@@ -3,7 +3,6 @@
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
-using Cysharp.Threading.Tasks;
 
 public class ItemTipWayWin : UIBase
 {
@@ -103,7 +102,7 @@
                 if (StoreModel.Instance.CheckPopBuyWin(shopID))
                 {
                     StoreModel.Instance.buyShopID = shopID;
-                    UIManager.Instance.OpenWindowAsync<BuyItemWin>().Forget();
+                    UIManager.Instance.OpenWindow<BuyItemWin>();
                 }
                 break;
             case 2:
@@ -113,11 +112,11 @@
                 RechargeManager.Instance.selectTabIndex = index;
                 if (UIManager.Instance.IsOpened<StoreBaseWin>())
                 {
-                    UIManager.Instance.GetUI<StoreBaseWin>().ClickFuncBtn(1);
+                    UIManager.Instance.GetUI<StoreBaseWin>().ClickFuncBtn(2);
                 }
                 else
                 {
-                    UIManager.Instance.OpenWindowAsync<StoreBaseWin>(1).Forget();
+                    UIManager.Instance.OpenWindow<StoreBaseWin>(2);
                 }
                 break;
             case 3:
@@ -128,7 +127,7 @@
                 }
                 if (!UIManager.Instance.IsOpened<TimingGiftWin>())
                 {
-                    UIManager.Instance.OpenWindowAsync<TimingGiftWin>(int.Parse(way.CustomValue)).Forget();
+                    UIManager.Instance.OpenWindow<TimingGiftWin>(int.Parse(way.CustomValue));
                 }
                 break;
             case 0:
diff --git a/Main/System/ItemTip/OwnMoneyCell.cs b/Main/System/ItemTip/OwnMoneyCell.cs
index 50ee91f..d94f028 100644
--- a/Main/System/ItemTip/OwnMoneyCell.cs
+++ b/Main/System/ItemTip/OwnMoneyCell.cs
@@ -1,6 +1,5 @@
 锘縰sing UnityEngine;
 using UnityEngine.UI;
-using Cysharp.Threading.Tasks;
 
 //鎷ユ湁鐨勮揣甯侊細鏁伴噺鏄剧ず锛岀偣鍑绘寜閽墦寮�瀵瑰簲鑾峰彇鐣岄潰
 public class OwnMoneyCell : MonoBehaviour
@@ -28,11 +27,11 @@
                                 RechargeManager.Instance.selectTabIndex = 1;
                                 if (UIManager.Instance.IsOpened<StoreBaseWin>())
                                 {
-                                    UIManager.Instance.GetUI<StoreBaseWin>().ClickFuncBtn(1);
+                                    UIManager.Instance.GetUI<StoreBaseWin>().ClickFuncBtn(2);
                                 }
                                 else
                                 {
-                                    UIManager.Instance.OpenWindowAsync<StoreBaseWin>(1).Forget();
+                                    UIManager.Instance.OpenWindow<StoreBaseWin>(2);
                                 }
                             }
                         }
@@ -44,11 +43,11 @@
                                 RechargeManager.Instance.selectTabIndex = 0;
                                 if (UIManager.Instance.IsOpened<StoreBaseWin>())
                                 {
-                                    UIManager.Instance.GetUI<StoreBaseWin>().ClickFuncBtn(1);
+                                    UIManager.Instance.GetUI<StoreBaseWin>().ClickFuncBtn(2);
                                 }
                                 else
                                 {
-                                    UIManager.Instance.OpenWindowAsync<StoreBaseWin>(1).Forget();
+                                    UIManager.Instance.OpenWindow<StoreBaseWin>(2);
                                 }
                             }
                         }
diff --git a/Main/System/KnapSack/BackpackData.cs b/Main/System/KnapSack/BackpackData.cs
index fd66a36..c454b70 100644
--- a/Main/System/KnapSack/BackpackData.cs
+++ b/Main/System/KnapSack/BackpackData.cs
@@ -11,7 +11,8 @@
     public int id;
     public long countEx;   
     public int quality;
-    public int useType;    //鐢ㄩ�斿畾涔夛細0 鏃� 1 棰勭暀 2 绾㈤澧炲姞 10 鍙ゅ疂澧炲姞
+    public int useType;    //鐢ㄩ�斿畾涔夛細0  榛樿鏃� 10 - 鍙ゅ疂 20 - 绾㈤ 30 - 绉板彿 40 -鍒嗚В
+    public string dataEx;
 
     public Item(int _id, long _count)
     {
@@ -19,17 +20,19 @@
         this.quality = 0;
         this.useType = 0;
         this.countEx = _count;
+        this.dataEx = "";
     }
     
 
 
 
-    public Item(int _id, long _count, int _useType = 0, int _quality = 0)
+    public Item(int _id, long _count, int _useType = 0, int _quality = 0, string _dataEx = "")
     {
         this.id = _id;
         this.quality = _quality;
         this.useType = _useType;
         this.countEx = _count;
+        this.dataEx = _dataEx;
     }
 
     
diff --git a/Main/System/KnapSack/Logic/CommonGetItemWin.cs b/Main/System/KnapSack/Logic/CommonGetItemWin.cs
index 417f20f..4727a84 100644
--- a/Main/System/KnapSack/Logic/CommonGetItemWin.cs
+++ b/Main/System/KnapSack/Logic/CommonGetItemWin.cs
@@ -35,7 +35,8 @@
         ItemLogicUtility.Instance.OnGetItemShowEvent -= OnGetItemShowEvent;
         scroller.OnRefreshCell -= OnRefreshCell;
         ItemLogicUtility.Instance.ClearGetItem();
-
+        ItemLogicUtility.Instance.totalShowItems.Clear();
+        ItemLogicUtility.Instance.totalDeleteItemIDs.Clear();
     }
 
     List<Item> showItems = new List<Item>();
diff --git a/Main/System/KnapSack/Logic/ItemLogicUtility.cs b/Main/System/KnapSack/Logic/ItemLogicUtility.cs
index dc726dd..1cf247b 100644
--- a/Main/System/KnapSack/Logic/ItemLogicUtility.cs
+++ b/Main/System/KnapSack/Logic/ItemLogicUtility.cs
@@ -127,29 +127,46 @@
 
     // 濡傛灉鍚屾椂鏈夊绉嶅鍔卞皝鍖咃紝鍚屼竴涓簨浠跺綊闆嗭紝涓嶅悓浜嬩欢鐩存帴椤舵帀鏄剧ず鏈�鏂�
     public Dictionary<Int2, Item> totalShowItems = new Dictionary<Int2, Item>();    //Int2 鐗╁搧ID+useType
+    public List<int> totalDeleteItemIDs = new List<int>();    //鍒犻櫎鐨勭墿鍝両D
     public event Action OnGetItemShowEvent;
     public string getItemEventName;
     public string sourceTip;    //棰嗗鍘熷洜
 
     // isMergeItem 鏄惁鍚堝苟鐩稿悓ID鐨勭墿鍝� 榛樿鍚堝苟
     // 閫氱敤鏄剧ず鑾峰緱鐨勭墿鍝�
-    public void ShowGetItem(List<Item> items, string eventName = "default", bool isNameShow = true, bool isMergeItem = true)
+    public void ShowGetItem(List<Item> items, string eventName = "default", bool isNameShow = true,
+        bool isMergeItem = true, List<int> deleteItemIDs = null)
     {
         if (getItemEventName != eventName)
         {
             if (UIManager.Instance.IsOpenedInList<CommonGetItemWin>())
             {
-                //----------------------璁板緱鏀圭珛鍗冲叧闂�
+                //绔嬪嵆鍏抽棴
                 UIManager.Instance.CloseWindow<CommonGetItemWin>();
             }
             totalShowItems.Clear();
+            totalDeleteItemIDs.Clear();
             getItemEventName = eventName;
+        }
+        if (!deleteItemIDs.IsNullOrEmpty())
+        {
+            for (int i = 0; i < deleteItemIDs.Count; i++)
+            {
+                if (!totalDeleteItemIDs.Contains(deleteItemIDs[i]))
+                {
+                    totalDeleteItemIDs.Add(deleteItemIDs[i]);
+                }
+            }
         }
 
         //鐩稿悓ID 鍚堝苟鏁伴噺鏄剧ず
         for (int i = 0; i < items.Count; i++)
         {
             var id = items[i].id;
+            if (totalDeleteItemIDs.Contains(id))
+            {
+                continue;
+            }
 
             var useType = isMergeItem ? 0 : items[i].useType;
             Int2 idInfo = new Int2(id, useType);
diff --git a/Main/System/KnapSack/Logic/RolePackWin.cs b/Main/System/KnapSack/Logic/RolePackWin.cs
index 9f43b88..572eb1c 100644
--- a/Main/System/KnapSack/Logic/RolePackWin.cs
+++ b/Main/System/KnapSack/Logic/RolePackWin.cs
@@ -169,6 +169,7 @@
             }
         }
         packScroller.Restart();
+        packScroller.lockType = EnhanceLockType.KeepVertical;
     }
 
     void CreateComposeScroller()
@@ -186,6 +187,7 @@
             }
         }
         composeScroller.Restart();
+        composeScroller.lockType = EnhanceLockType.KeepVertical;
     }
 
     void RefreshPackCell(ScrollerDataType type, CellView cell)
diff --git a/Main/System/Language/Language.cs b/Main/System/Language/Language.cs
index 9eb65ec..3507c37 100644
--- a/Main/System/Language/Language.cs
+++ b/Main/System/Language/Language.cs
@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System;
 using UnityEngine;
+using LitJson;
 
 
 public static class Language
@@ -22,38 +23,78 @@
         }
     }
 
+    public static Dictionary<string, string> languageShowDict = new Dictionary<string, string>();//鐣岄潰鏄剧ず鐨勫璇█鐗堟湰
+
+    //鍚姩澶氳瑷�鐨勬笭閬�,濡倇appid:[榛樿璇█鏍囪瘑,鏄惁棣栨瀹夎寮哄埗鎸囧畾璇█,鍙寘鍚摢浜涜瑷�鐗堟湰]}
+    // 濡倇"sghy":["en","0","en,zh,ft"]}锛屽瓧绗�0浠h〃闅忕郴缁熼�夋嫨濡傛灉鎵句笉鍒板垯鐢ㄩ粯璁わ紝閰�1鍒欎笉妫�鏌ョ郴缁熺洿鎺ョ敤榛樿
+    //涓轰簡鍚屼唬鐮佺増鏈悓琛ㄧ淮鎶わ紝淇濇寔閰嶇疆涓�鑷存寜appid鍖哄垎锛屽彧鍋氱炕璇戝鐞�
+    public static Dictionary<string, string[]> languageStartDict = new Dictionary<string, string[]>();//鍚姩澶氳瑷�鐨勬笭閬�
+    static Dictionary<string, string> languageDict = new Dictionary<string, string>();// unity璇█閰嶇疆瀵瑰簲鐨勭害瀹氬瓧绗� 鎵句笉鍒扮敤榛樿
 
     /// <summary>
-    /// 鏍规嵁绯荤粺璇█鑷姩璁剧疆榛樿璇█
+    /// 鏈己鍒惰瑷�鐨� 鏍规嵁绯荤粺璇█鑷姩璁剧疆榛樿璇█ 绛夋儏鍐�
     /// </summary>
     public static void InitDefaultLanguage()
     {
-        var config = InitialFunctionConfig.Get("Language").Numerical1;
-        Debug.LogFormat("绯荤粺璇█锛歿0} {1}", Application.systemLanguage, config);
-        if (string.IsNullOrEmpty(config))
+        //鍒濆鍖�, 璇ヨ〃鏄殢鍖呭畨瑁呯殑濡傛灉鐑洿闇�瑕佷簩娆℃墠鐢熸晥
+        var config = InitialFunctionConfig.Get("LanguageEx");
+        if (config.Numerical1 == null || config.Numerical2 == null || config.Numerical3 == null)
+        {
             return;
+        }      
+        
+        languageShowDict = JsonMapper.ToObject<Dictionary<string, string>>(config.Numerical1);
+        languageStartDict = JsonMapper.ToObject<Dictionary<string, string[]>>(config.Numerical2);
+        languageDict = JsonMapper.ToObject<Dictionary<string, string>>(config.Numerical3);
+
+        if (languageStartDict == null || !languageStartDict.ContainsKey(VersionConfigEx.Get().appId))
+        {
+            //妫�鏌ユ湁娌″璇█
+            Debug.Log("褰撳墠娓犻亾鏈紑鍚璇█:" + VersionConfigEx.Get().appId);
+            return;
+        }
+
+        Debug.LogFormat("绯荤粺璇█锛歿0} {1}", Application.systemLanguage, config.Numerical1);
+
         var id = LocalSave.GetString("LANGUAGE_ID1");
         if (!string.IsNullOrEmpty(id))
-            return;
-
-        switch (Application.systemLanguage)
         {
-            case SystemLanguage.Chinese:
-            case SystemLanguage.ChineseSimplified:
-            case SystemLanguage.ChineseTraditional:
-                {
-                    id = "zh";
-                    break;
-                }
+            //鐜╁宸茬粡閫夋嫨杩囪瑷�锛屼笉鍋氬鐞�
+            Debug.Log("褰撳墠閫夋嫨璇█锛�" + id);
+            return;
         }
-        var json = LitJson.JsonMapper.ToObject(config);
-        if (json.Keys.Contains(id))
-            Id = id;
+
+        var defaultCfg = languageStartDict[VersionConfigEx.Get().appId];
+        string languageMark;
+        if (defaultCfg[1] == "0")
+        {
+            //闅忕郴缁熼�夋嫨
+            languageMark = ((int)Application.systemLanguage).ToString();
+            if (languageDict.ContainsKey(languageMark))
+            {
+                id = languageDict[languageMark];
+                var lanArr = defaultCfg[2].Split(',');
+                if (Array.IndexOf(lanArr, id) == -1)
+                {
+                    //涓嶅寘鍚殑璇█ 鐢ㄩ粯璁�
+                    id = defaultCfg[0];
+                }
+
+            }
+            else
+            {
+                //榛樿
+                id = defaultCfg[0];
+            }
+        }
         else
         {
-            //寮�鍚殑鎯呭喌涓嬪繀椤昏鏈変釜榛樿鍊�
-            Id = InitialFunctionConfig.Get("Language").Numerical2;
+            //寮哄埗鎸囧畾榛樿
+            id = defaultCfg[0];
         }
+
+        Id = id;
+        Debug.LogFormat("绯荤粺璇█锛歿0} 璁剧疆涓簕1}", Application.systemLanguage, Id);
     }
 
     /// <summary>
@@ -64,9 +105,14 @@
     {
         get
         {
-            var config = InitialFunctionConfig.Get("Language").Numerical1;
-            if (string.IsNullOrEmpty(config))
+            if (languageStartDict == null || languageStartDict.Count == 0)
+            {
                 return "";
+            }
+            if (!languageStartDict.ContainsKey(VersionConfigEx.Get().appId))
+            {
+                return "";
+            }
             return LocalSave.GetString("LANGUAGE_ID1");
         }
         set
@@ -75,6 +121,7 @@
         }
     }
 
+    //澶氳瑷�鐨勮矾寰�
     //榛樿璺緞涓嶉檮鍔犲湴鍧�锛孖d涓嶄负绌烘椂闄勫姞Id
     public static string fixPath
     {
@@ -86,6 +133,17 @@
         }
     }
 
+
+    // 鑾峰彇璇█閫夐」
+    public static string[] GetLanguages()
+    {
+        if (languageStartDict == null || !languageStartDict.ContainsKey(VersionConfig.Get().appId))
+        {
+            return null;
+        }
+        return languageStartDict[VersionConfig.Get().appId][2].Split(',');
+    }
+
     public static string Get(string _id)
     {
         // return string.Empty;
diff --git a/Main/System/LineupRecommend/LineupRecommendItem.cs b/Main/System/LineupRecommend/LineupRecommendItem.cs
index 4a89907..ff71c0a 100644
--- a/Main/System/LineupRecommend/LineupRecommendItem.cs
+++ b/Main/System/LineupRecommend/LineupRecommendItem.cs
@@ -1,5 +1,4 @@
-锘縰sing UnityEngine;
-using Cysharp.Threading.Tasks;
+using UnityEngine;
 
 public class LineupRecommendItem : MonoBehaviour
 {
@@ -30,55 +29,7 @@
         if (!manager.TryGetHeroSkinConfig(heroID, out HeroSkinConfig heroSkinConfig))
             return;
 
-        UILoader.LoadSprite("HeroHead", heroSkinConfig.SquareIcon, imgHeroHead, "herohead_default").Forget();
-
-        imgSquareIcon.SetSprite("heroheadBG" + heroConfig.Quality);
-        imgCountry.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
-        txtName.text = heroConfig.Name;
-        txtDesc.text = heroConfig.Desc;
-        imgJob.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class));
-
-        LineupRecommendHeroState heroState = manager.GetHeroState(recommendID, index);
-        imgMask.SetActive(heroState != LineupRecommendHeroState.ActivateAndHave);
-        txtNoHave.SetActive(heroState == LineupRecommendHeroState.ActivateButNoHave);
-        imgMoney.SetActive(heroState == LineupRecommendHeroState.NoActivate || heroState == LineupRecommendHeroState.CanActivate);
-        txtMoney.SetActive(heroState == LineupRecommendHeroState.NoActivate || heroState == LineupRecommendHeroState.CanActivate);
-        imgRed.SetActive(heroState == LineupRecommendHeroState.CanActivate);
-
-        imgMoney.SetIconWithMoneyType(moneyType);
-        imgMoney.gray = heroState == LineupRecommendHeroState.NoActivate;
-        txtMoney.text = moneyNeedCnt.ToString();
-        txtMoney.color = heroState == LineupRecommendHeroState.NoActivate ? colMoneyNoActivate : colMoneyCanActivate;
-
-        btnClick.SetListener(() =>
-        {
-            if (heroState == LineupRecommendHeroState.CanActivate)
-            {
-                manager.SendGetReward(recommendID, index);
-            }
-            else
-            {
-                HeroUIManager.Instance.selectForPreviewHeroID = heroConfig.HeroID;
-                UIManager.Instance.OpenWindowAsync<HeroBestWin>().Forget();
-            }
-        });
-
-    }
-
-    public async UniTask DisplayAsync(int recommendID, int index)
-    {
-        if (!manager.TryGetHeroConfigByIndex(recommendID, index, out HeroConfig heroConfig))
-            return;
-
-        if (!manager.TryGetMoneyInfo(recommendID, index, out int moneyType, out int moneyNeedCnt))
-            return;
-
-        int heroID = heroConfig.HeroID;
-        if (!manager.TryGetHeroSkinConfig(heroID, out HeroSkinConfig heroSkinConfig))
-            return;
-
-        var sprite = await UILoader.LoadSpriteAsync("HeroHead", heroSkinConfig.SquareIcon);
-        if (this == null) return;
+        var sprite = UILoader.LoadSprite("HeroHead", heroSkinConfig.SquareIcon);
         if (sprite == null)
         {
             imgHeroHead.SetSprite("herohead_default");
@@ -115,7 +66,7 @@
             else
             {
                 HeroUIManager.Instance.selectForPreviewHeroID = heroConfig.HeroID;
-                UIManager.Instance.OpenWindowAsync<HeroBestWin>().Forget();
+                UIManager.Instance.OpenWindow<HeroBestBaseWin>();
             }
         });
 
diff --git a/Main/System/Login/LoginManager.cs b/Main/System/Login/LoginManager.cs
index 37da50d..298f406 100644
--- a/Main/System/Login/LoginManager.cs
+++ b/Main/System/Login/LoginManager.cs
@@ -405,7 +405,7 @@
                 send.ServerID = (uint)ServerListCenter.Instance.currentServer.region_flag;
                 send.Adult = 1;
                 send.ExtraLen = 0;
-                send.Extra = "";
+                send.Extra = "test|0|1|2|1.1.1";
                 break;
             case VersionAuthority.Release:
                 {
diff --git a/Main/System/Login/LoginWin.cs b/Main/System/Login/LoginWin.cs
index a49c133..2c2710c 100644
--- a/Main/System/Login/LoginWin.cs
+++ b/Main/System/Login/LoginWin.cs
@@ -220,6 +220,7 @@
     private void OnServerChange()
     {
         ChangeServerInfo(ServerListCenter.Instance.currentServer);
+        SDKUtils.Instance.SendTraceEvent(1);
     }
 
     // private void OnLoginBtnClick()
diff --git a/Main/System/Login/ServerBehaviour.cs b/Main/System/Login/ServerBehaviour.cs
index 928704a..8867d44 100644
--- a/Main/System/Login/ServerBehaviour.cs
+++ b/Main/System/Login/ServerBehaviour.cs
@@ -53,7 +53,7 @@
 
                 // avatarCell.InitUI(AvatarHelper.GetDefaultAvatarModel(job));
                 m_RoleName.text = _serverData.roleid;
-                m_RoleLevel.text = Language.Get("Z1024", _serverData.level);
+                m_RoleLevel.text = Language.Get("L1094") + _serverData.level;
             }
             else
             {
diff --git a/Main/System/Login/ServerListParser.cs b/Main/System/Login/ServerListParser.cs
index e1daf9e..9cddb14 100644
--- a/Main/System/Login/ServerListParser.cs
+++ b/Main/System/Login/ServerListParser.cs
@@ -33,7 +33,12 @@
             return;
         JsonData RankArr = JsonMapper.ToObject(content);
         if (RankArr["player"]["group_list"].Count == 0)
-            return;
+        {
+            if (!RankArr.ContainsKey("gametest"))
+            {
+                return;
+            }
+        }
 
         ParsePlayerServerListAsync(content).Forget();
     }
diff --git a/Main/System/Mail/MailCell.cs b/Main/System/Mail/MailCell.cs
index 60fa97e..bcfabe9 100644
--- a/Main/System/Mail/MailCell.cs
+++ b/Main/System/Mail/MailCell.cs
@@ -1,16 +1,18 @@
 锘縰sing System;
+using Cysharp.Threading.Tasks;
 using UnityEngine;
 using UnityEngine.UI;
 using Cysharp.Threading.Tasks;
 
 public class MailCell : CellView
 {
+    [SerializeField] Transform layout;
     [SerializeField] Button btnMail;
     [SerializeField] ImageEx imgMask;
     [SerializeField] ImageEx imgRed;
     [SerializeField] ImageEx imgRead;
     [SerializeField] ImageEx imgHasAward;
-    [SerializeField] TextEx txtTitle;
+    [SerializeField] RichText txtTitle;
     [SerializeField] TextEx txtDate;
     MailManager model { get { return MailManager.Instance; } }
     string uuid = string.Empty;
@@ -30,7 +32,7 @@
         imgMask.SetActive(false);
         if (mailData.IsTemplateMail() && MailConfig.HasKey(mailData.GetTemplateKey()))
         {
-            txtTitle.text = MailConfig.Get(mailData.GetTemplateKey()).Title;
+            txtTitle.text = string.Format(MailConfig.Get(mailData.GetTemplateKey()).Title, mailData.GetTemplateParams().ToArray());
         }
         else
         {
@@ -39,6 +41,7 @@
 
         txtDate.text = model.FormatMailExpiryDays(mailData.CreateDateTime, mailData.LimitDays);
         btnMail.SetListener(OnClickButtonMail);
+        UIUtility.ForceRefreshLayout(layout).Forget();
     }
 
     private void OnClickButtonMail()
diff --git a/Main/System/Mail/MailInfoWin.cs b/Main/System/Mail/MailInfoWin.cs
index df2f89a..9152c3b 100644
--- a/Main/System/Mail/MailInfoWin.cs
+++ b/Main/System/Mail/MailInfoWin.cs
@@ -3,7 +3,7 @@
 public class MailInfoWin : UIBase
 {
     [SerializeField] TextEx txtDate;
-    [SerializeField] TextEx txtTitle;
+    [SerializeField] RichText txtTitle;
     [SerializeField] Transform transNoAward;
     [SerializeField] RichText txtNoAwardInfo;
     [SerializeField] Transform transAward;
@@ -127,7 +127,7 @@
                 string content = string.Format(config.Content, templateParams.ToArray());
                 txtNoAwardInfo.text = content;
                 txtAwardInfo.text = content;
-                txtTitle.text = config.Title;
+                txtTitle.text = string.Format(config.Title, templateParams.ToArray());
             }
             catch (System.Exception ex)
             {
diff --git a/Main/System/Main/FightPowerFormula.cs b/Main/System/Main/FightPowerFormula.cs
index fa2e92e..4d22fb5 100644
--- a/Main/System/Main/FightPowerFormula.cs
+++ b/Main/System/Main/FightPowerFormula.cs
@@ -13,6 +13,7 @@
     private const string HORSEVALUE_VALUE = "horseValue";
     private const string BEAUTYVALUE_VALUE = "beautyValue";
     private const string FATESVALUE_VALUE = "fatesValue";
+    private const string SKINVALUE_VALUE = "skinValue";
     private const string DINGJUNGEVALUE_VALUE = "dingjungeValue";
     private const string MINGGEVALUE_VALUE = "minggeValue";
     private const string LINEUPHALOPER_VALUE = "lineupHaloPer";
@@ -22,6 +23,7 @@
     private const string HORSEPER_VALUE = "horsePer";
     private const string BEAUTYPER_VALUE = "beautyPer";
     private const string FATESPER_VALUE = "fatesPer";
+    private const string SKINPER_VALUE = "skinPer";
     private const string CARDPER_VALUE = "cardPer";
     private const string MINGGEPER_VALUE = "minggePer";
     private const string INHERITPER_VALUE = "inheritPer";
@@ -32,6 +34,7 @@
     private const string DINGJUNGEPER_VALUE = "dingjungePer";
     private const string HEROSELFVALUE_VALUE = "heroSelfValue";
     private const string HEROLVVALUE_VALUE = "heroLVValue";
+    private const string HEROSKINVALUE_VALUE = "heroSkinValue";
     private const string LINEUPHALOVALUE_VALUE = "lineupHaloValue";
     private const string STARTALENTVALUE_VALUE = "starTalentValue";
     private const string BREAKLVVALUE_VALUE = "breakLVValue";
@@ -137,9 +140,9 @@
     private const string OFFICIALLV_VALUE = "OfficialLV";
 
     // 鍩虹灞炴�у叕寮�
-    // (lvValue+equipValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue+fatesValue+dingjungeValue+minggeValue)*(1+lineupHaloPer+realmPer+gubaoPer+hjgPer+horsePer+beautyPer+fatesPer+cardPer+minggePer)*(inheritPer+fetterPer+starTalentPer+breakLVPer+awakeTalentPer)*(1+dingjungePer)+heroSelfValue+heroLVValue
+    // (lvValue+equipValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue+fatesValue+skinValue+dingjungeValue+minggeValue)*(1+lineupHaloPer+realmPer+gubaoPer+hjgPer+horsePer+beautyPer+fatesPer+skinPer+cardPer+minggePer)*(inheritPer+fetterPer+starTalentPer+breakLVPer+awakeTalentPer)*(1+dingjungePer)+heroSelfValue+heroLVValue+heroSkinValue
     // 鎴樻枟灞炴�у叕寮�
-    // (lvValue+equipValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue+fatesValue+dingjungeValue+minggeValue)+(heroSelfValue+lineupHaloValue+starTalentValue+breakLVValue+awakeTalentValue)+fetterValue
+    // (lvValue+equipValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue+fatesValue+dingjungeValue+minggeValue)+(heroSelfValue+heroSkinValue+lineupHaloValue+starTalentValue+breakLVValue+awakeTalentValue)+fetterValue
     // 鎴樻枟鍔涘叕寮�
     // long(Atk*AtkRatio+MaxHP*MaxHPRatio+Def*DefRatio+AtkSpeed*AtkSpeedRatio+(StunRate*StunRateRatio+SuperHitRate*SuperHitRateRatio+ComboRate*ComboRateRatio+MissRate*MissRateRatio+ParryRate*ParryRateRatio+SuckHPPer*SuckHPPerRatio+StunRateDef*StunRateDefRatio+SuperHitRateDef*SuperHitRateDefRatio+ComboRateDef*ComboRateDefRatio+MissRateDef*MissRateDefRatio+ParryRateDef*ParryRateDefRatio+SuckHPPerDef*SuckHPPerDefRatio+FinalDamPer*FinalDamPerRatio+FinalDamPerDef*FinalDamPerDefRatio+PhyDamPer*PhyDamPerRatio+PhyDamPerDef*PhyDamPerDefRatio+MagDamPer*MagDamPerRatio+MagDamPerDef*MagDamPerDefRatio+NormalSkillPer*NormalSkillPerRatio+NormalSkillPerDef*NormalSkillPerDefRatio+AngerSkillPer*AngerSkillPerRatio+AngerSkillPerDef*AngerSkillPerDefRatio+SuperDamPer*SuperDamPerRatio+SuperDamPerDef*SuperDamPerDefRatio+CurePer*CurePerRatio+CurePerDef*CurePerDefRatio+ShieldPer*ShieldPerRatio+ShieldPerDef*ShieldPerDefRatio+DOTPer*DOTPerRatio+DOTPerDef*DOTPerDefRatio+WeiFinalDamPer*WeiFinalDamPerRatio+WeiFinalDamPerDef*WeiFinalDamPerDefRatio+ShuFinalDamPer*ShuFinalDamPerRatio+ShuFinalDamPerDef*ShuFinalDamPerDefRatio+WuFinalDamPer*WuFinalDamPerRatio+WuFinalDamPerDef*WuFinalDamPerDefRatio+QunFinalDamPer*QunFinalDamPerRatio+QunFinalDamPerDef*QunFinalDamPerDefRatio+PVPDamPer*PVPDamPerRatio+PVPDamPerDef*PVPDamPerDefRatio+Guanchuan*GuanchuanRatio+GuanchuanDef*GuanchuanDefRatio+Zhaojia*ZhaojiaRatio+ZhaojiaDef*ZhaojiaDefRatio)/100.0-55000)
     // 鎶�鑳芥垬鏂楀姏鍏紡
@@ -155,6 +158,7 @@
         double horseValue = variables[HORSEVALUE_VALUE];
         double beautyValue = variables[BEAUTYVALUE_VALUE];
         double fatesValue = variables[FATESVALUE_VALUE];
+        double skinValue = variables[SKINVALUE_VALUE];
         double dingjungeValue = variables[DINGJUNGEVALUE_VALUE];
         double minggeValue = variables[MINGGEVALUE_VALUE];
         double lineupHaloPer = variables[LINEUPHALOPER_VALUE];
@@ -164,6 +168,7 @@
         double horsePer = variables[HORSEPER_VALUE];
         double beautyPer = variables[BEAUTYPER_VALUE];
         double fatesPer = variables[FATESPER_VALUE];
+        double skinPer = variables[SKINPER_VALUE];
         double cardPer = variables[CARDPER_VALUE];
         double minggePer = variables[MINGGEPER_VALUE];
         double inheritPer = variables[INHERITPER_VALUE];
@@ -174,8 +179,9 @@
         double dingjungePer = variables[DINGJUNGEPER_VALUE];
         double heroSelfValue = variables[HEROSELFVALUE_VALUE];
         double heroLVValue = variables[HEROLVVALUE_VALUE];
+        double heroSkinValue = variables[HEROSKINVALUE_VALUE];
 
-        return (lvValue+equipValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue+fatesValue+dingjungeValue+minggeValue)*(1+lineupHaloPer+realmPer+gubaoPer+hjgPer+horsePer+beautyPer+fatesPer+cardPer+minggePer)*(inheritPer+fetterPer+starTalentPer+breakLVPer+awakeTalentPer)*(1+dingjungePer)+heroSelfValue+heroLVValue;
+        return (lvValue+equipValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue+fatesValue+skinValue+dingjungeValue+minggeValue)*(1+lineupHaloPer+realmPer+gubaoPer+hjgPer+horsePer+beautyPer+fatesPer+skinPer+cardPer+minggePer)*(inheritPer+fetterPer+starTalentPer+breakLVPer+awakeTalentPer)*(1+dingjungePer)+heroSelfValue+heroLVValue+heroSkinValue;
     }
 
     public static double GetFightAttr(Dictionary<string, double> variables)
@@ -191,13 +197,14 @@
         double dingjungeValue = variables[DINGJUNGEVALUE_VALUE];
         double minggeValue = variables[MINGGEVALUE_VALUE];
         double heroSelfValue = variables[HEROSELFVALUE_VALUE];
+        double heroSkinValue = variables[HEROSKINVALUE_VALUE];
         double lineupHaloValue = variables[LINEUPHALOVALUE_VALUE];
         double starTalentValue = variables[STARTALENTVALUE_VALUE];
         double breakLVValue = variables[BREAKLVVALUE_VALUE];
         double awakeTalentValue = variables[AWAKETALENTVALUE_VALUE];
         double fetterValue = variables[FETTERVALUE_VALUE];
 
-        return (lvValue+equipValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue+fatesValue+dingjungeValue+minggeValue)+(heroSelfValue+lineupHaloValue+starTalentValue+breakLVValue+awakeTalentValue)+fetterValue;
+        return (lvValue+equipValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue+fatesValue+dingjungeValue+minggeValue)+(heroSelfValue+heroSkinValue+lineupHaloValue+starTalentValue+breakLVValue+awakeTalentValue)+fetterValue;
     }
 
     public static double GetFightPower(Dictionary<string, double> variables)
diff --git a/Main/System/Main/FightPowerManager.cs b/Main/System/Main/FightPowerManager.cs
index b376955..8713b32 100644
--- a/Main/System/Main/FightPowerManager.cs
+++ b/Main/System/Main/FightPowerManager.cs
@@ -363,9 +363,15 @@
         var awakeTalentPer = hero.GetAwakeAttrPer(attrType) / 10000.0;
         var fetterPer = hero.GetFetterAttrPer(attrType) / 10000.0;
         var heroLVValue = hero.GetHeroLVValue(attrType);
-        
-        double value = (lvValue+equipValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue+fatesValue+dingjungeValue+minggeValue)*(1+lineupHaloPer+realmPer+gubaoPer+hjgPer+horsePer+beautyPer+fatesPer+cardPer+minggePer)*(inheritPer+fetterPer+starTalentPer+breakLVPer+awakeTalentPer)*(1+dingjungePer)+heroSelfValue+heroLVValue;
 
+        //姝﹀皢鐨偆
+        var skinValue = HeroUIManager.Instance.GetSkinAttrValue(attrType);
+        var skinPer = HeroUIManager.Instance.GetSkinAttrPer(attrType) / 10000.0;
+        var heroSkinValue = hero.GetHeroSkinValue(attrType);
+
+        
+        double value = (lvValue+equipValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue+fatesValue+skinValue+dingjungeValue+minggeValue)*(1+lineupHaloPer+realmPer+gubaoPer+hjgPer+horsePer+beautyPer+fatesPer+skinPer+cardPer+minggePer)*(inheritPer+fetterPer+starTalentPer+breakLVPer+awakeTalentPer)*(1+dingjungePer)+heroSelfValue+heroLVValue+heroSkinValue;
+    
         //淇濈暀2浣嶅皬鏁� 
         value = Math.Round(value, 2);
         
@@ -404,8 +410,11 @@
         var awakeTalentValue = hero.GetAwakeAttrValue(attrType);
         var fetterValue = hero.GetFetterAttrValue(attrType);
 
-        double value = (lvValue + equipValue + realmValue + gubaoValue + hjgValue + horseValue + beautyValue + fatesValue + dingjungeValue + minggeValue) + (heroSelfValue + lineupHaloValue + starTalentValue + breakLVValue + awakeTalentValue) + fetterValue;
+        //姝﹀皢鐨偆
+        var heroSkinValue = hero.GetHeroSkinValue(attrType);
 
+        double value = (lvValue+equipValue+realmValue+gubaoValue+hjgValue+horseValue+beautyValue+fatesValue+dingjungeValue+minggeValue)+(heroSelfValue+heroSkinValue+lineupHaloValue+starTalentValue+breakLVValue+awakeTalentValue)+fetterValue;
+  
         //淇濈暀2浣嶅皬鏁� 
         value = Math.Round(value, 2);
 
diff --git a/Main/System/Main/HeroFightingCardCell.cs b/Main/System/Main/HeroFightingCardCell.cs
index 1981f33..1a797c7 100644
--- a/Main/System/Main/HeroFightingCardCell.cs
+++ b/Main/System/Main/HeroFightingCardCell.cs
@@ -1,7 +1,6 @@
 锘縰sing UnityEngine;
 using UnityEngine.UI;
 using System.Collections.Generic;
-using Cysharp.Threading.Tasks;
 
 //涓荤晫闈㈠崱鐗�
 public class HeroFightingCardCell : MonoBehaviour
@@ -24,6 +23,7 @@
     [SerializeField] Image emptyLockImg;
     [SerializeField] Image redPointImg;
     [SerializeField] UIEffectPlayer unlockEffect;
+    [SerializeField] GameObject onTip;  //涓婇樀鎻愮ず
 
     void OnEnable()
     {
@@ -64,85 +64,26 @@
                     redPointImg.SetActive(HeroUIManager.Instance.CanUnLock(HeroUIManager.Instance.lockIndexList[lockIndex]));
                 }
             }
-
-            return;
-        }
-        else
-        {
-            clickHeroBtn.SetActive(true);
-            clickEmptyBtn.SetActive(false);
-        }
-
-        var hero = HeroManager.Instance.GetHero(guid);
-        var heroID = hero.heroId;
-        var star = hero.heroStar;
-        clickHeroBtn.AddListener(ClickHero);
-        var heroConfig = HeroConfig.Get(heroID);
-        qualityBG.SetSprite("herocBG" + heroConfig.Quality);
-
-        UILoader.LoadSprite("HeroHead", HeroSkinConfig.Get(hero.SkinID).RectangleIcon, heroIcon, "herohead_big_default").Forget();
-
-
-        if (star == 0)
-        {
-            starRect.SetActive(false);
-        }
-        else
-        {
-            starRect.SetActive(true);
-            for (int i = 0; i < starsImg.Count; i++)
+            if (onTip != null)
             {
-                if ((star - 1) % starsImg.Count >= i)
+                if (PlayerDatas.Instance.baseData.ExAttr1 / 100 < 601 && HeroManager.Instance.GetHeroCount() > index && index < 3)
                 {
-                    starsImg[i].SetActive(true);
-                    starsImg[i].SetSprite("herostar" + (((star - 1) / starsImg.Count) + 1) * starsImg.Count);
+                    //鏂版墜鏈� 鍙兘鍥犱负涓�浜涙搷浣滃師鍥犳病涓婇樀鑻遍泟
+                    onTip.SetActive(true);
                 }
                 else
                 {
-                    starsImg[i].SetActive(false);
+                    onTip.SetActive(false);
                 }
             }
-        }
-
-        countryImg.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
-        lvText.text = hero.heroLevel == 0 ? "" : Language.Get("L1094") + hero.heroLevel;
-
-        // RefreshFightIng(false);
-
-    }
-
-    public async UniTask DisplayAsync(int index, List<TeamHero> heros)
-    {
-        TeamHero teamHero = null;
-        if (index < heros.Count)
-        {
-            teamHero = heros[index];
-        }
-        guid = teamHero != null ? teamHero.guid : "";
-        if (guid == "")
-        {
-            clickHeroBtn.SetActive(false);
-            clickEmptyBtn.SetActive(true);
-            clickEmptyBtn.AddListener(ClickEmpty);
-            emptyLockImg.SetActive(false);
-            redPointImg.SetActive(false);
-
-            int lockCnt = HeroUIManager.Instance.lockIndexList.Count;
-            //鏍规嵁閿佹暟閲� 鍊掑簭鍒ゆ柇閿佷綇
-            if (lockCnt > 0)
-            {
-                lockIndex = lockCnt - (TeamConst.MaxTeamHeroCount - 1 - index) - 1;
-                if (lockIndex >= 0 && lockIndex < lockCnt)
-                {
-                    emptyLockImg.SetActive(true);
-                    redPointImg.SetActive(HeroUIManager.Instance.CanUnLock(HeroUIManager.Instance.lockIndexList[lockIndex]));
-                }
-            }
-
             return;
         }
         else
         {
+            if (onTip != null)
+            {
+                onTip.SetActive(false);
+            }
             clickHeroBtn.SetActive(true);
             clickEmptyBtn.SetActive(false);
         }
@@ -154,8 +95,7 @@
         var heroConfig = HeroConfig.Get(heroID);
         qualityBG.SetSprite("herocBG" + heroConfig.Quality);
 
-        var sprite = await UILoader.LoadSpriteAsync("HeroHead", HeroSkinConfig.Get(hero.SkinID).RectangleIcon);
-        if (this == null) return;
+        var sprite = UILoader.LoadSprite("HeroHead", HeroSkinConfig.Get(hero.SkinID).RectangleIcon);
         if (sprite == null)
         {
             // 鍐呯綉鏈厤缃椂
@@ -199,7 +139,7 @@
     {
         HeroUIManager.Instance.SortHeroList();
         HeroUIManager.Instance.selectHeroGuid = guid;
-        UIManager.Instance.OpenWindowAsync<HeroTrainWin>().Forget();
+        UIManager.Instance.OpenWindow<HeroTrainBaseWin>();
     }
 
     void ClickEmpty()
@@ -218,7 +158,7 @@
             }
             return;
         }
-        UIManager.Instance.OpenWindowAsync<HeroPosWin>().Forget();
+        UIManager.Instance.OpenWindow<HeroPosWin>();
     }
     void OnSkillCast(bool isfighting)
     {
diff --git a/Main/System/Main/HomeGridLayout.cs b/Main/System/Main/HomeGridLayout.cs
new file mode 100644
index 0000000..5d5f533
--- /dev/null
+++ b/Main/System/Main/HomeGridLayout.cs
@@ -0,0 +1,178 @@
+using UnityEngine;
+using System.Collections.Generic;
+
+[ExecuteAlways]
+[RequireComponent(typeof(RectTransform))]
+public class HomeGridLayout : MonoBehaviour
+{
+    public RectOffset padding = new RectOffset();      // 杈硅窛
+    public Vector2 cellSize = new Vector2(100f, 100f); // 鍗曞厓鏍煎ぇ灏�
+    public Vector2 spacing = new Vector2(10f, 10f);    // 鍏冪礌闂磋窛
+    public int rows = 7; // 鍥哄畾琛屾暟
+
+    private bool _isDirty = true; //浼樺寲鏂板锛氳剰鏍囪涓庤鏃跺櫒  鍒濆璁句负 true锛岀‘淇濈涓�甯т細鎺掔増
+    private float _checkTimer = 0f;
+    private const float CHECK_INTERVAL = 0.1f; // 100ms 妫�鏌ラ棿闅�
+
+    /// <summary>
+    /// 渚涘閮ㄦ垨瀛愬厓绱犺皟鐢紝鏍囪褰撳墠缃戞牸闇�瑕侀噸鏂版帓鐗�
+    /// </summary>
+    public void MarkAsDirty()
+    {
+        _isDirty = true;
+    }
+
+    // 灏哄鎴栧瓙鑺傜偣鏁伴噺鍙戠敓鍙樺寲鏃讹紝鍚屾牱鍙墦涓婅剰鏍囪
+    private void OnRectTransformDimensionsChange() => MarkAsDirty();
+    private void OnTransformChildrenChanged() => MarkAsDirty();
+
+    private void Update()
+    {
+#if UNITY_EDITOR
+        // 缂栬緫鍣ㄩ潪杩愯鐘舵�佷笅锛圗dit Mode锛塙pdate 甯х巼涓嶇ǔ瀹氾紝涓轰簡鏂逛究鎷栨嫿棰勮锛屼緷鐒舵湁鑴忔爣璁板氨绔嬪嵆鏇存柊
+        if (!Application.isPlaying)
+        {
+            if (_isDirty)
+            {
+                UpdateLayout();
+                _isDirty = false;
+            }
+            return;
+        }
+#endif
+
+        // 杩愯鏃讹紙Play Mode锛夋瘡 100ms 杞涓�娆�
+        _checkTimer += Time.deltaTime;
+        if (_checkTimer >= CHECK_INTERVAL)
+        {
+            if (_isDirty)
+            {
+                UpdateLayout();
+                _isDirty = false; // 鎺掔増瀹屾垚鍚庯紝娓呴櫎鏍囧織浣�
+            }
+            _checkTimer = 0f; // 閲嶇疆璁℃椂鍣�
+        }
+    }
+
+    public void UpdateLayout()
+    {
+        if (rows <= 0 || transform.childCount == 0) return;
+
+        List<RectTransform> flowChildren = new List<RectTransform>();
+        List<RectTransform> fixedChildren = new List<RectTransform>();
+
+        // 1. 閬嶅巻鏀堕泦骞跺垎绫绘墍鏈夋縺娲荤殑瀛愮墿浣�
+        for (int i = 0; i < transform.childCount; i++)
+        {
+            RectTransform child = transform.GetChild(i) as RectTransform;
+            if (child == null || !child.gameObject.activeSelf) continue;
+
+            HomeGridLayoutCell cell = child.GetComponent<HomeGridLayoutCell>();
+            
+            if (cell != null && cell.isFixedPosition)
+                fixedChildren.Add(child);
+            else
+                flowChildren.Add(child);
+        }
+
+        // 2. 鎺掑簭娴佸姩鐗╀綋 (鎸� sortIndex)
+        flowChildren.Sort((a, b) =>
+        {
+            var cellA = a.GetComponent<HomeGridLayoutCell>();
+            var cellB = b.GetComponent<HomeGridLayoutCell>();
+            int indexA = cellA != null ? cellA.sortIndex : int.MaxValue;
+            int indexB = cellB != null ? cellB.sortIndex : int.MaxValue;
+            return indexA.CompareTo(indexB);
+        });
+
+        // 3. 鎺掑簭鍥哄畾鐗╀綋 (浼樺厛 sortIndex锛屽叾娆� subSortIndex)
+        fixedChildren.Sort((a, b) =>
+        {
+            var cellA = a.GetComponent<HomeGridLayoutCell>();
+            var cellB = b.GetComponent<HomeGridLayoutCell>();
+            
+            int sortA = cellA != null ? cellA.sortIndex : int.MaxValue;
+            int sortB = cellB != null ? cellB.sortIndex : int.MaxValue;
+            
+            if (sortA != sortB) return sortA.CompareTo(sortB);
+
+            int subA = cellA != null ? cellA.subSortIndex : int.MaxValue;
+            int subB = cellB != null ? cellB.subSortIndex : int.MaxValue;
+            return subA.CompareTo(subB);
+        });
+
+        // 4. 寮�濮嬪垎閰嶇綉鏍� (鏍稿績浼樺寲閮ㄥ垎)
+        int currentGridIndex = 0; // 褰撳墠鎺ㄦ紨鍒扮殑鐪熷疄缃戞牸鍧戜綅
+        int flowIndex = 0;
+        int fixedIndex = 0;
+        int totalValidChildren = flowChildren.Count + fixedChildren.Count;
+
+        for (int i = 0; i < totalValidChildren; i++)
+        {
+            RectTransform targetChild = null;
+            HomeGridLayoutCell nextFixedCell = null;
+
+            if (fixedIndex < fixedChildren.Count)
+            {
+                nextFixedCell = fixedChildren[fixedIndex].GetComponent<HomeGridLayoutCell>();
+            }
+
+            // 鍒嗘敮 A锛氬浐瀹氱墿浣撳凡缁忓埌浜嗗畠鏈熸湜鐨勭綉鏍间綅缃紙鎴栧凡缁忚鍓嶉潰鐨勫厓绱犳尋鍒颁簡褰撳墠浣嶇疆锛�
+            if (nextFixedCell != null && nextFixedCell.sortIndex <= currentGridIndex)
+            {
+                targetChild = fixedChildren[fixedIndex];
+                fixedIndex++;
+            }
+            // 鍒嗘敮 B锛氬綋鍓嶄綅缃病鏈夊浐瀹氱墿浣撴姠鍗狅紝涓旇繕鏈夋祦鍔ㄧ墿浣撴帓闃燂紝璁╂祦鍔ㄧ墿浣撳~琛ョ┖缂�
+            else if (flowIndex < flowChildren.Count)
+            {
+                targetChild = flowChildren[flowIndex];
+                flowIndex++;
+            }
+            // 鍒嗘敮 C锛氭病鏈夋祦鍔ㄧ墿浣撳~琛ョ┖缂轰簡锛岀洿鎺ヨ缃戞牸绱㈠紩鈥滃揩杩涒�濆埌涓嬩竴涓浐瀹氱墿浣撶殑浣嶇疆
+            else if (nextFixedCell != null)
+            {
+                currentGridIndex = nextFixedCell.sortIndex; // 蹇繘璺宠繃涓棿鐨勬墍鏈夌┖鐧芥牸瀛�
+                targetChild = fixedChildren[fixedIndex];
+                fixedIndex++;
+            }
+
+            // 搴旂敤璁$畻濂界殑缃戞牸鍧愭爣
+            if (targetChild != null)
+            {
+                SetChildTransform(targetChild, currentGridIndex);
+                currentGridIndex++; // 鍗犱綅鎴愬姛锛屽潙浣嶅悗绉�
+            }
+        }
+    }
+
+   /// <summary>
+    /// 灏嗗瓙鐗╀綋鏀剧疆鍒版寚瀹氱殑缃戞牸绱㈠紩浣嶇疆
+    /// </summary>
+    private void SetChildTransform(RectTransform child, int gridIndex)
+    {
+        int col = gridIndex / rows;
+        int row = gridIndex % rows;
+
+        // 1. 鍏堣绠楀嚭濡傛灉杞村績鍦ㄥ彸涓婅鏃剁殑鐞嗚杈圭紭鍧愭爣
+        float edgeXPos = -padding.right - col * (cellSize.x + spacing.x);
+        float edgeYPos = -padding.top - row * (cellSize.y + spacing.y);
+
+        // 2. 涓轰簡娑堥櫎鍥㈤槦娼滆鍒欙紝鎴戜滑灏嗘牸瀛愮殑杞村績鏀瑰洖姝d腑蹇� (0.5, 0.5)
+        // 鍥犳瀹為檯鍧愭爣闇�瑕佸悜宸︺�佸悜涓嬪啀鍋忕Щ鍗婁釜鍗曞厓鏍肩殑澶у皬
+        float centerXPos = edgeXPos - (cellSize.x * 0.5f);
+        float centerYPos = edgeYPos - (cellSize.y * 0.5f);
+
+        // 缁熶竴閿氱偣涓哄彸涓婅 (1, 1)
+        child.anchorMin = new Vector2(1, 1);
+        child.anchorMax = new Vector2(1, 1);
+        
+        // 杞村績锛圥ivot锛夋敼涓烘涓績锛�
+        child.pivot = new Vector2(0.5f, 0.5f); 
+        
+        child.sizeDelta = cellSize;
+        
+        // 璧嬩簣涓績鍧愭爣
+        child.anchoredPosition = new Vector2(centerXPos, centerYPos);
+    }
+}
\ No newline at end of file
diff --git a/Main/System/Main/HomeGridLayout.cs.meta b/Main/System/Main/HomeGridLayout.cs.meta
new file mode 100644
index 0000000..0839346
--- /dev/null
+++ b/Main/System/Main/HomeGridLayout.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b7ec546648dc7bc4297af70316bca133
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Main/HomeGridLayoutCell.cs b/Main/System/Main/HomeGridLayoutCell.cs
new file mode 100644
index 0000000..54ba05b
--- /dev/null
+++ b/Main/System/Main/HomeGridLayoutCell.cs
@@ -0,0 +1,42 @@
+using UnityEngine;
+
+public class HomeGridLayoutCell : MonoBehaviour
+{
+    [Header("妯″紡")]
+    [Tooltip("鍕鹃�夊垯鍥哄畾鍦ㄧ洰鏍囨牸瀛愪笂鍗犱綅锛涗笉鍕惧垯浣滀负娴佹按鍏冪礌鑷姩濉┖銆�")]
+    public bool isFixedPosition;
+
+    [Header("鎺掑簭")]
+    [Tooltip("鍐冲畾鍥哄畾鍏冪礌鐨勬墍鍦ㄦ牸瀛�,鎴栨祦姘村厓绱犵殑鍑哄満椤哄簭(娉ㄦ剰浠�0寮�濮嬭)銆�")]
+    public int sortIndex;
+
+    [Tooltip("褰撳涓厓绱犳姠鍗犲悓涓�涓牸瀛愭垨鎺掑簭鐩稿悓鏃讹紝璇ュ�艰秺灏忚秺浼樺厛銆�")]
+    public int subSortIndex;
+
+    private void OnEnable()
+    {
+        NotifyParentToUpdate();
+    }
+
+    private void OnDisable()
+    {
+        NotifyParentToUpdate();
+    }
+
+    /// <summary>
+    /// 閫氱煡鐖剁骇鐨勭綉鏍艰剼鏈仛鈥滆剰鏍囪鈥濓紝绛夊緟涓嬩竴娆¤疆璇㈡椂閲嶆柊鎺掔増
+    /// </summary>
+    private void NotifyParentToUpdate()
+    {
+        // 濡傛灉鐗╀綋琚攢姣佹垨鑰呮病鏈夌埗绾т簡锛屽氨涓嶇浜�
+        if (transform.parent == null)
+            return;
+
+        HomeGridLayout layout = transform.parent.GetComponent<HomeGridLayout>();
+        if (layout != null)
+        {
+            // 鏀逛负浠呬粎璁剧疆鏍囧織浣嶏紝涓嶅啀绔嬪嵆瑙﹀彂
+            layout.MarkAsDirty(); 
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/System/Main/HomeGridLayoutCell.cs.meta b/Main/System/Main/HomeGridLayoutCell.cs.meta
new file mode 100644
index 0000000..cb587da
--- /dev/null
+++ b/Main/System/Main/HomeGridLayoutCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 28e84dc55c523d64bbeb2631a3355c73
+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 0cbe97f..831a9d6 100644
--- a/Main/System/Main/HomeWin.cs
+++ b/Main/System/Main/HomeWin.cs
@@ -67,8 +67,12 @@
     [SerializeField] Button osMainLevelBtn;
     [SerializeField] Button osHeroCallBtn;
     [SerializeField] Button osGalaBtn;
+    [SerializeField] Button osHeroTrainBtn;
+    [SerializeField] Button osBeautyMMBtn;
     [SerializeField] TimingGiftCell timingGiftCell;
+    [SerializeField] Button osMinggeBtn;
     [SerializeField] TimeRushCell timeRushCell;
+    [SerializeField] HeroDebutCell heroDebutCell;
 
     //鍧愰獞
     [SerializeField] Image horseBGImg;
@@ -211,7 +215,18 @@
         {
             UIManager.Instance.OpenWindowAsync<OSGalaBaseWin>().Forget();
         });
-
+        osBeautyMMBtn.AddListener(() =>
+        {
+            UIManager.Instance.OpenWindow<OSBeautyMMBaseWin>();
+        });
+        osHeroTrainBtn.AddListener(() =>
+        {
+            UIManager.Instance.OpenWindow<OSHeroTrainBaseWin>();
+        });
+        osMinggeBtn.AddListener(() =>
+        {
+            UIManager.Instance.OpenWindow<OSMinggeBaseWin>();
+        });
         DailySpecialsBtns.AddListener(() =>
         {
             UIManager.Instance.OpenWindowAsync<DailySpecialsBaseWin>().Forget();
@@ -233,7 +248,7 @@
         DisplayLevel();
         DisplayRestState();
 
-        funcColBtn.SetActive(FuncOpen.Instance.IsFuncOpen(GeneralDefine.mainRightFuncOpenFuncID));
+        funcColBtn.SetActive(FuncOpen.Instance.IsFuncOpen(GeneralDefine.mainRightFuncOpenFuncID) || SmallFuncManager.Instance.IsReviewOpen());
         officialTip.SetActive(OfficialRankManager.Instance.CanOfficialLVUP());
 
         DisplayHorse();
@@ -272,6 +287,7 @@
         UIManager.Instance.OnOpenWindow += OnOpenWindow;
         TimingGiftManager.Instance.OnShowGiftIdListAddEvent += OnShowGiftIdListAddEvent;
         OpenServerActivityCenter.Instance.openServerActivityStateChange += OpenServerActivityStateChange;
+        OperationTimeHepler.Instance.operationTimeUpdateEvent += OnOperationTimeUpdateEvent;
         TryPlayAutoFightBoss();
         Display();
         DisplayFirstChargeBtn();
@@ -279,7 +295,7 @@
         timingGiftCell.InitUI().Forget();
 
         DisplayTimeRush();
-
+        DisplayHeroDebut();
         DelayPlayMusic().Forget();
 
     }
@@ -309,13 +325,24 @@
         UIManager.Instance.OnOpenWindow -= OnOpenWindow;
         TimingGiftManager.Instance.OnShowGiftIdListAddEvent -= OnShowGiftIdListAddEvent;
         OpenServerActivityCenter.Instance.openServerActivityStateChange -= OpenServerActivityStateChange;
+        OperationTimeHepler.Instance.operationTimeUpdateEvent -= OnOperationTimeUpdateEvent;
         //  鍏抽棴鐨勬椂鍊欐妸鎴樻枟鐣岄潰涔熺粰鍏充簡 铏界劧鏄湪澶栭潰寮�鐨�
         UIManager.Instance.CloseWindow<BattleWin>();
+    }
+
+    private void OnOperationTimeUpdateEvent(OperationType type)
+    {
+        if (type == OperationType.HeroDebut)
+        {
+            DisplayHeroDebut();
+        }
+
     }
 
     private void OpenServerActivityStateChange()
     {
         DisplayTimeRush();
+        DisplayHeroDebut();
     }
 
     private void OnShowGiftIdListAddEvent()
@@ -349,8 +376,7 @@
 
     private void OnClickChatBtn()
     {
-        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Chat, true))
-            return;
+
 
         //transFastChat.SetActive(true);
         // transChatInfo.SetActive(false);
@@ -359,7 +385,7 @@
         bool hasLastTalkData = ChatManager.Instance.TryGetLastTalkData(out ChatChannel type, out TalkData data);
         if (!hasLastTalkData)
         {
-            ChatManager.Instance.nowChatTab = ChatTab.World;
+            ChatManager.Instance.nowChatTab = ChatChannel.World;
             ChatManager.Instance.nowChatChannel = ChatChannel.World;
         }
         else
@@ -368,15 +394,15 @@
             {
                 case ChatChannel.World:
                 default:
-                    ChatManager.Instance.nowChatTab = ChatTab.World;
+                    ChatManager.Instance.nowChatTab = ChatChannel.World;
                     ChatManager.Instance.nowChatChannel = ChatChannel.World;
                     break;
                 case ChatChannel.Guild:
-                    ChatManager.Instance.nowChatTab = ChatTab.Guild;
+                    ChatManager.Instance.nowChatTab = ChatChannel.Guild;
                     ChatManager.Instance.nowChatChannel = ChatChannel.Guild;
                     break;
                 case ChatChannel.CrossServer:
-                    ChatManager.Instance.nowChatTab = ChatTab.CrossServer;
+                    ChatManager.Instance.nowChatTab = ChatChannel.CrossServer;
                     ChatManager.Instance.nowChatChannel = ChatChannel.CrossServer;
                     break;
             }
@@ -439,7 +465,7 @@
         }
     }
 
-    private void OnChatTabChangeEvent(ChatTab tab)
+    private void OnChatTabChangeEvent(ChatChannel tab)
     {
         //UpdateChat(tab);
     }
@@ -678,7 +704,7 @@
     private void OnCloseWindow(UIBase closeUI)
     {
         //鍏朵粬姝﹀皢鍔熻兘浜х敓鏁版嵁鍙樺寲锛岄渶瑕佸埛鏂版灏嗗垪琛�
-        if (closeUI is HeroTrainWin)
+        if (closeUI is HeroTrainBaseWin)
         {
             DisplayCard(TeamManager.Instance.GetMainTeamID());
         }
@@ -814,7 +840,8 @@
             DisplayHorse();
         }
         else if (funcId == (int)FuncOpenEnum.OSMainLevl || funcId == (int)FuncOpenEnum.OSHeroCall
-        || funcId == (int)FuncOpenEnum.OSGala)
+        || funcId == (int)FuncOpenEnum.OSGala|| funcId == (int)FuncOpenEnum.OSHeroTrain
+        || funcId == (int)FuncOpenEnum.OSBeautyMM  || funcId == (int)FuncOpenEnum.OSMingge)
         {
             DisplayOSActivity();
         }
@@ -829,6 +856,10 @@
         else if (funcId == (int)FuncOpenEnum.TimeRush)
         {
             DisplayTimeRush();
+        }
+        else if (funcId == (int)FuncOpenEnum.HeroDebut)
+        {
+            DisplayHeroDebut();
         }
     }
 
@@ -877,6 +908,9 @@
     {
         osMainLevelBtn.SetActive(OSActivityManager.Instance.IsOpened(3));
         osHeroCallBtn.SetActive(OSActivityManager.Instance.IsOpened(4));
+        osHeroTrainBtn.SetActive(OSActivityManager.Instance.IsOpened(7));
+        osBeautyMMBtn.SetActive(OSActivityManager.Instance.IsOpened(8));
+        osMinggeBtn.SetActive(OSActivityManager.Instance.IsOpened(9));
         osGalaBtn.SetActive(OSActivityManager.Instance.IsOpenedOSGala());
     }
 
@@ -894,6 +928,15 @@
             return;
         timeRushCell.InitUI();
     }
+
+    void DisplayHeroDebut()
+    {
+        bool isOpen = HeroDebutManager.Instance.IsHeroDebutOpen();
+        heroDebutCell.SetActive(isOpen);
+        if (!isOpen)
+            return;
+        heroDebutCell.Display();
+    }
 }
 
 
diff --git a/Main/System/Main/RightFuncInHome.cs b/Main/System/Main/RightFuncInHome.cs
index 7b28b8c..e302d0b 100644
--- a/Main/System/Main/RightFuncInHome.cs
+++ b/Main/System/Main/RightFuncInHome.cs
@@ -19,6 +19,7 @@
     [SerializeField] Button llmjBtn; //鍘嗙粌绉樼瑘
     [SerializeField] Button signBtn;
     [SerializeField] Button previewBtn;
+    [SerializeField] Button reviewBtn; //濂借瘎
 
     static string listenWindowName = "";   //鐩戝惉鍏抽棴鏃跺啀鏄剧ず
 
@@ -40,6 +41,7 @@
 
         clickScreenOtherSpaceEvent.AddListener(() =>
         {
+            if (NewBieCenter.Instance.inGuiding) return;
             if (isShow)
             {
                 isShow = !isShow;
@@ -88,6 +90,10 @@
             ListenWindow("FunctionPreviewWin");
             UIManager.Instance.OpenWindowAsync<FunctionPreviewWin>().Forget();
         });
+        reviewBtn.AddListener(() =>
+        {
+            UIManager.Instance.OpenWindow<GoodReviewWin>();
+        });
     }
     
     void OnDestroy()
@@ -105,6 +111,7 @@
         signBtn.SetActive(FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.DaySign));
         monthCardBtn.SetActive(FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.PrivilegeCard));
         previewBtn.SetActive(FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.FunctionPreview));
+        reviewBtn.SetActive(SmallFuncManager.Instance.IsReviewOpen());
     }
 
 
diff --git a/Main/System/MainLevel/MainBossEnterWin.cs b/Main/System/MainLevel/MainBossEnterWin.cs
index 474a644..3b9b017 100644
--- a/Main/System/MainLevel/MainBossEnterWin.cs
+++ b/Main/System/MainLevel/MainBossEnterWin.cs
@@ -8,7 +8,6 @@
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
-using Cysharp.Threading.Tasks;
 
 
 public class MainBossEnterWin : UIBase
@@ -34,9 +33,8 @@
         CloseBtn.AddListener(CloseWindow);
         rankBtn.AddListener(() =>
         {
-            RankModel.Instance.ResetQueryParam();
-            RankModel.Instance.QueryRankByPage(0, watchID: (int)PlayerDatas.Instance.baseData.PlayerID);
-            UIManager.Instance.OpenWindowAsync<PlayerRankWin>(0).Forget();
+
+            UIManager.Instance.OpenWindow<PlayerRankWin>(0);
 
         });
 
@@ -44,7 +42,7 @@
 
         heroRoadBtn.AddListener(() =>
         {
-            UIManager.Instance.OpenWindowAsync<DayMissionBaseWin>(2).Forget();
+            UIManager.Instance.OpenWindow<DayMissionBaseWin>(2);
         });
 
         funPresetBtn.AddListener(()=>
@@ -105,8 +103,8 @@
                     SmallTipWin.showText = Language.Get("SmallTipFomat",SkillConfig.Get(skillID)?.SkillName, SkillConfig.Get(skillID)?.Description) ;
                     SmallTipWin.worldPos = CameraManager.uiCamera.ScreenToWorldPoint(Input.mousePosition);
                     SmallTipWin.isDownShow = true;
-                    UIManager.Instance.OpenWindowAsync<SmallTipWin>().Forget();
-                }).Forget();
+                    UIManager.Instance.OpenWindow<SmallTipWin>();
+                });
             }
             else
             {
diff --git a/Main/System/Message/RichTableEvent.cs b/Main/System/Message/RichTableEvent.cs
index f5a3271..6816622 100644
--- a/Main/System/Message/RichTableEvent.cs
+++ b/Main/System/Message/RichTableEvent.cs
@@ -378,7 +378,7 @@
                                                     break;
                                                 }
                                             }
-                                            goodsName = Language.Get("DayGoods_1", UIHelper.GetMoneyFormat(orderInfo.PayRMBNum));
+                                            goodsName = Language.Get("DayGoods_1", UIHelper.GetMoneyFormat(orderInfo.PayRMBNumOnSale));
                                         }
 
                                         return goodsName;
diff --git a/Main/System/Message/RichText.cs b/Main/System/Message/RichText.cs
index a77d2c9..4c81467 100644
--- a/Main/System/Message/RichText.cs
+++ b/Main/System/Message/RichText.cs
@@ -688,6 +688,12 @@
     #region 鎵ц浜嬩欢
     public void OnPointerClick(PointerEventData eventData)
     {
+        // 妫�鏌ョ粍浠舵槸鍚﹀凡绂佺敤鎴栭攢姣侊紝閬垮厤绌烘寚閽堣В寮曠敤
+        if (!this.isActiveAndEnabled)
+        {
+            return;
+        }
+
         OnClick?.Invoke();
         if (HrefClick)
         {
@@ -738,6 +744,13 @@
     // 瀛楃瀹藉害缂撳瓨锛岄伩鍏嶉噸澶嶈绠楃浉鍚屽瓧绗�
     private Dictionary<string, float> charWidthCache = new Dictionary<string, float>();
 
+    protected override void OnDisable()
+    {
+        base.OnDisable();
+        // 缁勪欢绂佺敤鏃舵竻绌虹紦瀛橈紝闃叉鍐呭瓨娉勬紡
+        charWidthCache.Clear();
+    }
+
     private bool IsModifySize(int _index,out int _size)
     {
         _size = 0;
diff --git a/Main/System/Message/RichTextMgr.cs b/Main/System/Message/RichTextMgr.cs
index b566100..438de3e 100644
--- a/Main/System/Message/RichTextMgr.cs
+++ b/Main/System/Message/RichTextMgr.cs
@@ -152,7 +152,20 @@
 
     public bool ExecuteEvent(RichTextEventEnum type,HrefInfo href)
     {
-        return m_RichEvents[type].Execute(type,href);
+        if (m_RichEvents == null || !m_RichEvents.ContainsKey(type))
+        {
+            Debug.LogWarning($"RichTextMgr: Event type {type} not registered");
+            return false;
+        }
+
+        var evt = m_RichEvents[type];
+        if (evt == null)
+        {
+            Debug.LogWarning($"RichTextMgr: Event handler for {type} is null");
+            return false;
+        }
+
+        return evt.Execute(type, href);
     }
 
     public string GetDisplay(RichTextEventEnum type,Dictionary<string,string> dic)
diff --git a/Main/System/NewBieGuidance/NewBieCenter.cs b/Main/System/NewBieGuidance/NewBieCenter.cs
index 6b4c30d..2098441 100644
--- a/Main/System/NewBieGuidance/NewBieCenter.cs
+++ b/Main/System/NewBieGuidance/NewBieCenter.cs
@@ -378,6 +378,10 @@
             send.GuideIndex = (byte)_id;
             send.IsOK = 1;
             GameNetSystem.Instance.SendInfo(send);
+            if (guideRecord == 16)
+            {
+                SDKUtils.Instance.SendTraceEvent(7);
+            }
         }
 
         if (guideCompletedEvent != null)
@@ -423,6 +427,10 @@
             send.GuideIndex = (byte)guideRecord;
             send.IsOK = 1;
             GameNetSystem.Instance.SendInfo(send);
+            if (guideRecord == 16)
+            {
+                SDKUtils.Instance.SendTraceEvent(7);
+            }
         }
 
         if (guideCompletedEvent != null)
diff --git a/Main/System/OSActivity/OSActivityBaseWin.cs b/Main/System/OSActivity/OSActivityBaseWin.cs
new file mode 100644
index 0000000..cbe44d6
--- /dev/null
+++ b/Main/System/OSActivity/OSActivityBaseWin.cs
@@ -0,0 +1,41 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+public abstract class OSActivityBaseWin : FunctionsBaseWin
+{
+    [SerializeField] protected Button closBtn;
+
+    protected override void InitComponent()
+    {
+        base.InitComponent();
+        if (closBtn != null)
+        {
+            closBtn.AddListener(CloseWindow);
+        }
+    }
+
+    // 鐢卞瓙绫诲疄鐜帮細褰撳墠娲诲姩鐨� RankType 
+    protected abstract int GetRankType();
+    
+    // 鐢卞瓙绫诲疄鐜帮細瀹炰緥鍖栧搴旂殑涓変釜瀛愮獥鍙�
+    protected abstract UIBase GetRankWin();
+    protected abstract UIBase GetAwardWin();
+    protected abstract UIBase GetGiftWin();
+
+    protected override void OpenSubUIByTabIndex()
+    {
+        switch (functionOrder)
+        {
+            case 0:
+                currentSubUI = GetRankWin();
+                break;
+            case 1:
+                currentSubUI = GetAwardWin();
+                break;
+            case 2:
+                // 濡傛灉鍚庣画鏈夋椿鍔ㄦ病鏈夌ぜ鍖呴〉绛撅紝鍙渶鍦ㄥ瓙绫婚噷杩斿洖 null 鎴栦笉璋冪敤鍗冲彲
+                currentSubUI = GetGiftWin();
+                break;
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSActivityBaseWin.cs.meta b/Main/System/OSActivity/OSActivityBaseWin.cs.meta
new file mode 100644
index 0000000..55cf809
--- /dev/null
+++ b/Main/System/OSActivity/OSActivityBaseWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 39e79ce497558694689712020f566c86
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSActivityManager.cs b/Main/System/OSActivity/OSActivityManager.cs
index ea5464a..c2ca0a3 100644
--- a/Main/System/OSActivity/OSActivityManager.cs
+++ b/Main/System/OSActivity/OSActivityManager.cs
@@ -10,14 +10,23 @@
     Dictionary<int, int[]> rankOpenDays = new Dictionary<int, int[]>();  //鎺掕姒滅被鍨嬶細銆愬紑濮嬪紑鏈嶅ぉ, 缁撴潫寮�鏈嶅ぉ銆�
     public Dictionary<int, int[][]> mainLevelRankAwards = new Dictionary<int, int[][]>();  //涓荤嚎鍏冲崱鍚嶆锛氬鍔�
     public Dictionary<int, int[][]> heroCallRankAwards = new Dictionary<int, int[][]>();  //姝﹀皢鎷涘嫙鍚嶆锛氬鍔�
+    public Dictionary<int, int[][]> beautyMMRankAwards = new Dictionary<int, int[][]>();  //绾㈤鍐叉鍚嶆锛氬鍔�
+    public Dictionary<int, int[][]> heroTrainRankAwards = new Dictionary<int, int[][]>();  //姝﹀皢鍐叉鍚嶆锛氬鍔�
+    public Dictionary<int, int[][]> minggeRankAwards = new Dictionary<int, int[][]>();  //鍛芥牸鍐叉锛氬鍔�
 
     public List<int> osHeroCallGiftSortList = new List<int>();    //寮�鏈嶆嫑鍕熺ぜ鍖� 鍏呭�糏D + 100000000
+    public List<int> osBeautyMMGiftSortList = new List<int>();    //绾㈤鍐叉绀煎寘 鍏呭�糏D + 100000000
+    public List<int> osHeroTrainGiftSortList = new List<int>();    //姝﹀皢鍐叉绀煎寘 鍏呭�糏D + 100000000
+    public List<int> osMinggeGiftSortList = new List<int>();    //鍛芥牸鍐叉绀煎寘 鍏呭�糏D + 100000000
 
     //寮�鏈嶆瀵瑰簲鐨勫姛鑳絀D
     Dictionary<int, int> rankTypeToFuncID = new Dictionary<int, int>()
     {
         {3, 45},
         {4, 46},
+        {7, 59},
+        {8, 60},
+        {9, 61},
     };
 
 
@@ -51,6 +60,11 @@
         rankOpenDays = ConfigParse.ParseIntArrayDict(config.Numerical1);
         mainLevelRankAwards = ConfigParse.ParseIntArray2Dict(config.Numerical2);
         heroCallRankAwards = ConfigParse.ParseIntArray2Dict(config.Numerical3);
+        beautyMMRankAwards = ConfigParse.ParseIntArray2Dict(config.Numerical4);
+
+        config = FuncConfigConfig.Get("OSABillboardTrain");
+        heroTrainRankAwards = ConfigParse.ParseIntArray2Dict(config.Numerical3);
+        minggeRankAwards = ConfigParse.ParseIntArray2Dict(config.Numerical5);
 
         var list = StoreModel.Instance.storeTypeDict[(int)StoreFunc.OSHeroCall];
         var _list = RechargeManager.Instance.GetCTGIDListByType(18);
@@ -63,6 +77,45 @@
         for (int i = 0; i < _list.Count; i++)
         {
             osHeroCallGiftSortList.Add(_list[i] + 100000000);
+        }
+
+        list = StoreModel.Instance.storeTypeDict[(int)StoreFunc.OSBeautyMM];
+        _list = RechargeManager.Instance.GetCTGIDListByType(22);
+
+        for (int i = 0; i < list.Count; i++)
+        {
+            var item = list[i];
+            osBeautyMMGiftSortList.Add(item.shopId);
+        }
+        for (int i = 0; i < _list.Count; i++)
+        {
+            osBeautyMMGiftSortList.Add(_list[i] + 100000000);
+        }
+
+        list = StoreModel.Instance.storeTypeDict[(int)StoreFunc.OSHeroTrain];
+        _list = RechargeManager.Instance.GetCTGIDListByType(23);
+
+        for (int i = 0; i < list.Count; i++)
+        {
+            var item = list[i];
+            osHeroTrainGiftSortList.Add(item.shopId);
+        }
+        for (int i = 0; i < _list.Count; i++)
+        {
+            osHeroTrainGiftSortList.Add(_list[i] + 100000000);
+        }
+
+        list = StoreModel.Instance.storeTypeDict[(int)StoreFunc.OSMingge];
+        _list = RechargeManager.Instance.GetCTGIDListByType(24);
+
+        for (int i = 0; i < list.Count; i++)
+        {
+            var item = list[i];
+            osMinggeGiftSortList.Add(item.shopId);
+        }
+        for (int i = 0; i < _list.Count; i++)
+        {
+            osMinggeGiftSortList.Add(_list[i] + 100000000);
         }
 
         ParseOSGalaConfig();
@@ -159,6 +212,9 @@
     public void RefreshGiftSortList()
     {
         osHeroCallGiftSortList.Sort(CmpGift);
+        osBeautyMMGiftSortList.Sort(CmpGift);
+        osHeroTrainGiftSortList.Sort(CmpGift);
+        osMinggeGiftSortList.Sort(CmpGift);
     }
 
     void RefreshStore()
@@ -169,14 +225,23 @@
 
     Redpoint osMainLevelRedpoint = new Redpoint(MainRedDot.RedPoint_OSMainLevel);
     Redpoint osHeroCallRedpoint = new Redpoint(MainRedDot.RedPoint_OSHeroCard);
+    Redpoint osHeroTrainRedpoint = new Redpoint(MainRedDot.RedPoint_OSHeroTrain);
+    Redpoint osBeautyMMRedpoint = new Redpoint(MainRedDot.RedPoint_OSBeautyMM);
+    Redpoint osMinggeRedpoint = new Redpoint(MainRedDot.RedPoint_OSMingge);
 
     public void UpdateRedpoint()
     {
         osMainLevelRedpoint.state = !DayRemind.Instance.GetDayRemind(DayRemind.OSMainLevel) ? RedPointState.Simple : RedPointState.None;
         osGalaRedpoint2.state = !DayRemind.Instance.GetDayRemind(DayRemind.OSGalaChange) ? RedPointState.Simple : RedPointState.None;
-        
+        osHeroTrainRedpoint.state = !DayRemind.Instance.GetDayRemind(DayRemind.OSMainLevel) ? RedPointState.Simple : RedPointState.None;
+        osBeautyMMRedpoint.state = !DayRemind.Instance.GetDayRemind(DayRemind.OSMainLevel) ? RedPointState.Simple : RedPointState.None;
+        osMinggeRedpoint.state = !DayRemind.Instance.GetDayRemind(DayRemind.OSMainLevel) ? RedPointState.Simple : RedPointState.None;
+
         osHeroCallRedpoint.state = RedPointState.None;
         osGalaRedpoint3.state = RedPointState.None;
+        osHeroTrainRedpoint.state = RedPointState.None;
+        osBeautyMMRedpoint.state = RedPointState.None;
+        osMinggeRedpoint.state = RedPointState.None;
 
         if (StoreModel.Instance.freeShopDict.Count == 0) return;
 
@@ -211,6 +276,52 @@
                 }
             }
         }
+
+        if (StoreModel.Instance.freeShopDict.ContainsKey((int)StoreFunc.OSHeroTrain) && IsOpened(7, false))
+        {
+            var shopList = StoreModel.Instance.freeShopDict[(int)StoreFunc.OSHeroTrain];
+            for (int i = 0; i < shopList.Count; i++)
+            {
+                var shopID = shopList[i];
+                var config = StoreConfig.Get(shopID);
+                if (StoreModel.Instance.GetShopLimitBuyCount(shopID) < config.LimitCnt)
+                {
+                    osHeroTrainRedpoint.state = RedPointState.Simple;
+                    break;
+                }
+            }
+        }
+
+        if (StoreModel.Instance.freeShopDict.ContainsKey((int)StoreFunc.OSBeautyMM) && IsOpened(8, false))
+        {
+            var shopList = StoreModel.Instance.freeShopDict[(int)StoreFunc.OSBeautyMM];
+            for (int i = 0; i < shopList.Count; i++)
+            {
+                var shopID = shopList[i];
+                var config = StoreConfig.Get(shopID);
+                if (StoreModel.Instance.GetShopLimitBuyCount(shopID) < config.LimitCnt)
+                {
+                    osBeautyMMRedpoint.state = RedPointState.Simple;
+                    break;
+                }
+            }
+        }
+
+
+        if (StoreModel.Instance.freeShopDict.ContainsKey((int)StoreFunc.OSMingge) && IsOpened(9, false))
+        {
+            var shopList = StoreModel.Instance.freeShopDict[(int)StoreFunc.OSMingge];
+            for (int i = 0; i < shopList.Count; i++)
+            {
+                var shopID = shopList[i];
+                var config = StoreConfig.Get(shopID);
+                if (StoreModel.Instance.GetShopLimitBuyCount(shopID) < config.LimitCnt)
+                {
+                    osMinggeRedpoint.state = RedPointState.Simple;
+                    break;
+                }
+            }
+        }
     }
 
     private void FuncStateChange(int funcId)
@@ -219,6 +330,9 @@
         {
             case FuncOpenEnum.OSMainLevl:
             case FuncOpenEnum.OSHeroCall:
+            case FuncOpenEnum.OSHeroTrain:
+            case FuncOpenEnum.OSBeautyMM:
+            case FuncOpenEnum.OSMingge:
                 UpdateRedpoint();
                 break;
         }
diff --git a/Main/System/OSActivity/OSBeautyMMBaseWin.cs b/Main/System/OSActivity/OSBeautyMMBaseWin.cs
new file mode 100644
index 0000000..37f7d25
--- /dev/null
+++ b/Main/System/OSActivity/OSBeautyMMBaseWin.cs
@@ -0,0 +1,15 @@
+锘縰sing UnityEngine;
+using UnityEngine.UI;
+
+// 寮�鏈嶆椿鍔�-绾㈤鍐插埡娲诲姩
+public class OSBeautyMMBaseWin : OSActivityBaseWin
+{
+    // 绾㈤鍐叉瀵瑰簲鐨� RankType 涓� 8
+    protected override int GetRankType() => 8;
+
+    protected override UIBase GetRankWin() => UIManager.Instance.OpenWindow<OSRankBeautyMMWin>(8);
+    
+    protected override UIBase GetAwardWin() => UIManager.Instance.OpenWindow<OSRankBeautyMMAwardWin>();
+    
+    protected override UIBase GetGiftWin() => UIManager.Instance.OpenWindow<OSRankBeautyMMGiftWin>();
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSBeautyMMBaseWin.cs.meta b/Main/System/OSActivity/OSBeautyMMBaseWin.cs.meta
new file mode 100644
index 0000000..f8dcf9a
--- /dev/null
+++ b/Main/System/OSActivity/OSBeautyMMBaseWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5a76a8ddc6f4ac048970693981c9e681
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSGalaGiftCell.cs b/Main/System/OSActivity/OSGalaGiftCell.cs
index 47f3a28..f14a629 100644
--- a/Main/System/OSActivity/OSGalaGiftCell.cs
+++ b/Main/System/OSActivity/OSGalaGiftCell.cs
@@ -5,6 +5,11 @@
 
 public class OSGalaGiftCell : CellView
 {
+    [SerializeField] ImageEx vipImage;
+    [SerializeField] TextEx vipText;
+    [SerializeField] OutlineEx vipTextOutline;
+    [SerializeField] ImageEx rateImage;
+    [SerializeField] TextEx rateText;
     [SerializeField] Text nameText;
     [SerializeField] ItemCell[] itemCells;
     [SerializeField] Button buyBtn;
@@ -24,6 +29,18 @@
             id -= 100000000;
             var ctgConfig = CTGConfig.Get(id);
             nameText.text = ctgConfig.Title;
+
+            vipImage.SetActive(ctgConfig.VipLevel > 0);
+            if (ctgConfig.VipLevel > 0)
+            {
+                vipImage.SetSprite($"VipLevel{ctgConfig.VipLevel}");
+                vipText.text = Language.Get($"VipLevelInfo{ctgConfig.VipLevel}");
+                vipText.color = InvestModel.Instance.GetTextColor(ctgConfig.VipLevel);
+                vipTextOutline.OutlineColor = InvestModel.Instance.GetOutlineColor(ctgConfig.VipLevel);
+            }
+
+            rateImage.SetActive(true);
+            rateText.text = Language.Get("DailySpecials07", ctgConfig.Percentage);
             for (int i = 0; i < itemCells.Length; i++)
             {
                 var itemCell = itemCells[i];
@@ -53,12 +70,30 @@
                         SysNotifyMgr.Instance.ShowTip("ActivityOver");
                         return;
                     }
+                    if (ctgConfig.VipLevel > 0 && !FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.PrivilegeCard))
+                    {
+                        SysNotifyMgr.Instance.ShowTip("MinggeAuto8");
+                        return;
+                    }
+                    if (ctgConfig.VipLevel == 1 && !InvestModel.Instance.IsInvested(InvestModel.monthCardType))
+                    {
+                        SysNotifyMgr.Instance.ShowTip("MinggeAuto5");
+                        UIManager.Instance.OpenWindow<PrivilegeCardWin>();
+                        return;
+                    }
+                    if (ctgConfig.VipLevel == 2 && !InvestModel.Instance.IsInvested(InvestModel.foreverCardType))
+                    {
+                        SysNotifyMgr.Instance.ShowTip("MinggeAuto7");
+                        UIManager.Instance.OpenWindow<PrivilegeCardWin>();
+                        return;
+                    }
+
                     RechargeManager.Instance.CTG(id);
                 });
 
                 RechargeManager.Instance.TryGetOrderInfo(id, out var orderInfo);
 
-                moneyText.text = Language.Get("PayMoneyNum", orderInfo.PayRMBNumOnSale);
+                moneyText.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfo.PayRMBNumOnSale));
                 moneyIcon.SetActive(false);
             }
             else
@@ -73,6 +108,8 @@
         }
         else
         {
+            rateImage.SetActive(false);
+            vipImage.SetActive(false);
             //鍟嗗簵
             var storeConfig = StoreConfig.Get(id);
             nameText.text = storeConfig.Name;
@@ -118,9 +155,16 @@
                 });
                 moneyText.text = storeConfig.MoneyNum == 0 ? Language.Get("L1127") : storeConfig.MoneyNum.ToString();
                 moneyIcon.SetActive(storeConfig.MoneyNum != 0);
-                moneyIcon.SetIconWithMoneyType(storeConfig.MoneyType);
+                if (storeConfig.MoneyType <= 0)
+                {
+                    moneyIcon.SetItemSprite(storeConfig.CostItemID);
+                }
+                else
+                {
+                    moneyIcon.SetIconWithMoneyType(storeConfig.MoneyType);
+                }
                 redImg.SetActive(storeConfig.MoneyNum == 0);
-            }   
+            }
             var buyCnt = StoreModel.Instance.GetShopLimitBuyCount(id);
             buyLimitText.text = Language.Get("storename6", storeConfig.LimitCnt - buyCnt, storeConfig.LimitCnt);
 
diff --git a/Main/System/OSActivity/OSHeroCallBaseWin.cs b/Main/System/OSActivity/OSHeroCallBaseWin.cs
index 576006f..e67dfc3 100644
--- a/Main/System/OSActivity/OSHeroCallBaseWin.cs
+++ b/Main/System/OSActivity/OSHeroCallBaseWin.cs
@@ -7,7 +7,6 @@
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
-using Cysharp.Threading.Tasks;
 
 
 ////寮�鏈嶆椿鍔�-姝﹀皢鎷涘嫙娲诲姩
@@ -22,20 +21,18 @@
     }
     
 
-    protected override async void OpenSubUIByTabIndex()
+    protected override void OpenSubUIByTabIndex()
     {
         switch (functionOrder)
         {
             case 0:
-                RankModel.Instance.ResetQueryParam();
-                RankModel.Instance.QueryRankByPage(4, watchID: (int)PlayerDatas.Instance.baseData.PlayerID);
-                currentSubUI = await UIManager.Instance.OpenWindowAsync<OSRankWin>(4);
+                currentSubUI = UIManager.Instance.OpenWindow<OSRankWin>(4);
                 break;
             case 1:
-                currentSubUI = await UIManager.Instance.OpenWindowAsync<OSRankHeroCallAwardWin>();
+                currentSubUI = UIManager.Instance.OpenWindow<OSRankHeroCallAwardWin>();
                 break;
             case 2:
-                currentSubUI = await UIManager.Instance.OpenWindowAsync<OSRankHeroCallGiftWin>();
+                currentSubUI = UIManager.Instance.OpenWindow<OSRankHeroCallGiftWin>();
                 break;
         }
     }
diff --git a/Main/System/OSActivity/OSHeroTrainBaseWin.cs b/Main/System/OSActivity/OSHeroTrainBaseWin.cs
new file mode 100644
index 0000000..bbdc038
--- /dev/null
+++ b/Main/System/OSActivity/OSHeroTrainBaseWin.cs
@@ -0,0 +1,14 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+// 寮�鏈嶆椿鍔�-姝﹀皢鍐叉涓荤晫闈�
+public class OSHeroTrainBaseWin : OSActivityBaseWin
+{
+    protected override int GetRankType() => 7;
+
+    protected override UIBase GetRankWin() => UIManager.Instance.OpenWindow<OSRankHeroTrainWin>(7);
+    
+    protected override UIBase GetAwardWin() => UIManager.Instance.OpenWindow<OSRankHeroTrainAwardWin>();
+    
+    protected override UIBase GetGiftWin() => UIManager.Instance.OpenWindow<OSRankHeroTrainGiftWin>();
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSHeroTrainBaseWin.cs.meta b/Main/System/OSActivity/OSHeroTrainBaseWin.cs.meta
new file mode 100644
index 0000000..e7da08f
--- /dev/null
+++ b/Main/System/OSActivity/OSHeroTrainBaseWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 62c2161f6d4221e48aa134a1916f92e4
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSMainLevelBaseWin.cs b/Main/System/OSActivity/OSMainLevelBaseWin.cs
index 4d216c4..3d7989e 100644
--- a/Main/System/OSActivity/OSMainLevelBaseWin.cs
+++ b/Main/System/OSActivity/OSMainLevelBaseWin.cs
@@ -7,7 +7,6 @@
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
-using Cysharp.Threading.Tasks;
 
 
 ////寮�鏈嶆椿鍔�-涓荤嚎鍏冲崱娲诲姩
@@ -31,17 +30,15 @@
         }
     }
 
-    protected override async void OpenSubUIByTabIndex()
+    protected override void OpenSubUIByTabIndex()
     {
         switch (functionOrder)
         {
             case 0:
-                RankModel.Instance.ResetQueryParam();
-                RankModel.Instance.QueryRankByPage(3, watchID: (int)PlayerDatas.Instance.baseData.PlayerID);
-                currentSubUI = await UIManager.Instance.OpenWindowAsync<OSRankWin>(3);
+                currentSubUI = UIManager.Instance.OpenWindow<OSRankWin>(3);
                 break;
             case 1:
-                currentSubUI = await UIManager.Instance.OpenWindowAsync<OSRankMainLeveAwardWin>();
+                currentSubUI = UIManager.Instance.OpenWindow<OSRankMainLeveAwardWin>();
                 break;
         }
     }
diff --git a/Main/System/OSActivity/OSMinggeBaseWin.cs b/Main/System/OSActivity/OSMinggeBaseWin.cs
new file mode 100644
index 0000000..519fa70
--- /dev/null
+++ b/Main/System/OSActivity/OSMinggeBaseWin.cs
@@ -0,0 +1,14 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+// 寮�鏈嶆椿鍔�-鍛芥牸鍐叉涓荤晫闈�
+public class OSMinggeBaseWin : OSActivityBaseWin
+{
+    protected override int GetRankType() => 9;
+
+    protected override UIBase GetRankWin() => UIManager.Instance.OpenWindow<OSRankMinggeWin>(9);
+    
+    protected override UIBase GetAwardWin() => UIManager.Instance.OpenWindow<OSRankMinggeAwardWin>();
+    
+    protected override UIBase GetGiftWin() => UIManager.Instance.OpenWindow<OSRankMinggeGiftWin>();
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSMinggeBaseWin.cs.meta b/Main/System/OSActivity/OSMinggeBaseWin.cs.meta
new file mode 100644
index 0000000..a402f63
--- /dev/null
+++ b/Main/System/OSActivity/OSMinggeBaseWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d9768976d78a97e41b67c00ea082085c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankAwardBaseCell.cs b/Main/System/OSActivity/OSRankAwardBaseCell.cs
new file mode 100644
index 0000000..11b4272
--- /dev/null
+++ b/Main/System/OSActivity/OSRankAwardBaseCell.cs
@@ -0,0 +1,63 @@
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.UI;
+
+public abstract class OSRankAwardBaseCell : CellView
+{
+    [SerializeField] protected Text rankText;
+    [SerializeField] protected Image rankImg;
+    [SerializeField] protected ItemCell[] itemCells;
+
+    // 鐢卞瓙绫绘彁渚涘綋鍓嶇晫闈㈠搴旂殑濂栧姳瀛楀吀鏁版嵁
+    protected abstract Dictionary<int, int[][]> GetRankAwards();
+
+    public void Display(int index)
+    {
+        var rankAwards = GetRankAwards();
+        var rank = index + 1;
+        
+        if (index < 3)
+        {
+            rankImg.SetActive(true);
+            rankText.SetActive(false);
+            rankImg.SetSprite($"Rank{index + 1}");
+        }
+        else
+        {
+            rankImg.SetActive(false);
+            rankText.SetActive(true);
+            var keys = rankAwards.Keys.ToList();
+            keys.Sort();
+            var startRank = keys[index - 1] + 1;
+            var endRank = keys[index];
+            rank = endRank;
+            
+            if (startRank == endRank)
+            {
+                rankText.text = startRank.ToString();
+            }
+            else
+            {
+                rankText.text = startRank + "-" + endRank;
+            }
+        }
+
+        var award = rankAwards[rank];
+        for (int i = 0; i < itemCells.Length; i++)
+        {
+            var itemCell = itemCells[i];
+            if (i < award.Length)
+            {
+                itemCell.SetActive(true);
+                int itemID = award[i][0];
+                itemCell.Init(new ItemCellModel(itemID, true, award[i][1]));
+                itemCell.button.SetListener(() => ItemTipUtility.Show(itemID));
+            }
+            else
+            {
+                itemCell.SetActive(false);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankAwardBaseCell.cs.meta b/Main/System/OSActivity/OSRankAwardBaseCell.cs.meta
new file mode 100644
index 0000000..b6e93e1
--- /dev/null
+++ b/Main/System/OSActivity/OSRankAwardBaseCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5c40df973d5ace349ade9c111bb96722
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankAwardBaseWin.cs b/Main/System/OSActivity/OSRankAwardBaseWin.cs
new file mode 100644
index 0000000..d535189
--- /dev/null
+++ b/Main/System/OSActivity/OSRankAwardBaseWin.cs
@@ -0,0 +1,56 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+public abstract class OSRankAwardBaseWin : UIBase
+{
+    [SerializeField] protected ScrollerController scrollerController;
+    [SerializeField] protected Text myRankText;
+    [SerializeField] protected Text myRankValueText;
+
+    protected override void OnPreOpen()
+    {
+        scrollerController.OnRefreshCell += OnRefreshCell;
+        CreateScroller();
+        DisplayMyRank(GetRankType());
+    }
+
+    protected override void OnPreClose()
+    {
+        scrollerController.OnRefreshCell -= OnRefreshCell;
+    }
+
+    // 鐢卞瓙绫诲疄鐜帮細褰撳墠鐣岄潰鐨勬帓鍚嶇被鍨� (渚嬪 4 鏄嫑鍕熸, 8 鏄孩棰滄)
+    protected abstract int GetRankType();
+    // 鐢卞瓙绫诲疄鐜帮細褰撳墠鐣岄潰鐨勫鍔� Keys 闆嗗悎
+    protected abstract ICollection<int> GetAwardKeys();
+    // 鐢卞瓙绫诲疄鐜帮細缁戝畾瀵瑰簲鐨� Cell
+    protected abstract void OnRefreshCell(ScrollerDataType type, CellView cell);
+
+    protected void CreateScroller()
+    {
+        var keys = GetAwardKeys();
+        scrollerController.Refresh();
+        int count = keys == null ? 0 : keys.Count;
+        for (int i = 0; i < count; i++)
+        {
+            scrollerController.AddCell(ScrollerDataType.Header, i);
+        }
+        scrollerController.Restart();
+    }
+
+    public void DisplayMyRank(int rankType)
+    {
+        RankData rankData = RankModel.Instance.GetMyRank(rankType);
+        if (rankData == null)
+        {
+            myRankText.text = Language.Get("L1045");
+            myRankValueText.text = "";
+            return;
+        }
+
+        int rank = rankData.rank;
+        myRankValueText.text = RankModel.Instance.GetCmpValueStr(rankType, rankData.cmpValue);
+        myRankText.text = Language.Get("L1126") + Language.Get("L1096") + rank.ToString();
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankAwardBaseWin.cs.meta b/Main/System/OSActivity/OSRankAwardBaseWin.cs.meta
new file mode 100644
index 0000000..567e6e0
--- /dev/null
+++ b/Main/System/OSActivity/OSRankAwardBaseWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 01d872416a4fa8b45a660c56ed4c759f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankBaseWin.cs b/Main/System/OSActivity/OSRankBaseWin.cs
new file mode 100644
index 0000000..9637112
--- /dev/null
+++ b/Main/System/OSActivity/OSRankBaseWin.cs
@@ -0,0 +1,42 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+public abstract class OSRankBaseWin : PlayerRankWin
+{
+    [SerializeField] protected Text timeText;
+    [SerializeField] protected Text overTimeText;
+
+    protected override void OnPreOpen()
+    {
+        base.OnPreOpen();
+        GlobalTimeEvent.Instance.secondEvent += OnSecond;
+        ShowTime();
+    }
+
+    protected void ShowTime()
+    {
+        var seconds = OSActivityManager.Instance.GetEndTime(rankType);
+        if (seconds > 0)
+        {
+            timeText.SetActive(true);
+            overTimeText.SetActive(false);
+            timeText.text = TimeUtility.SecondsToShortDHMS(seconds);
+        }
+        else
+        {
+            timeText.SetActive(false);
+            overTimeText.SetActive(true);
+        }
+    }
+
+    protected override void OnPreClose()
+    {
+        base.OnPreClose();
+        GlobalTimeEvent.Instance.secondEvent -= OnSecond;
+    }
+
+    protected void OnSecond()
+    {
+        ShowTime();
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankBaseWin.cs.meta b/Main/System/OSActivity/OSRankBaseWin.cs.meta
new file mode 100644
index 0000000..120d38e
--- /dev/null
+++ b/Main/System/OSActivity/OSRankBaseWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3c869a53bb8b01141823913926a5b2b9
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankBeautyMMAwardCell.cs b/Main/System/OSActivity/OSRankBeautyMMAwardCell.cs
new file mode 100644
index 0000000..0f03e2f
--- /dev/null
+++ b/Main/System/OSActivity/OSRankBeautyMMAwardCell.cs
@@ -0,0 +1,12 @@
+锘縰sing System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class OSRankBeautyMMAwardCell : OSRankAwardBaseCell
+{
+    // 杩斿洖绾㈤鍐叉涓撳睘鐨勫鍔卞瓧鍏革紝渚涘熀绫绘覆鏌�
+    protected override Dictionary<int, int[][]> GetRankAwards()
+    {
+        return OSActivityManager.Instance.beautyMMRankAwards;
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankBeautyMMAwardCell.cs.meta b/Main/System/OSActivity/OSRankBeautyMMAwardCell.cs.meta
new file mode 100644
index 0000000..4a3cecd
--- /dev/null
+++ b/Main/System/OSActivity/OSRankBeautyMMAwardCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 647885ec6817f1342867bca550f5f5dc
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankBeautyMMAwardWin.cs b/Main/System/OSActivity/OSRankBeautyMMAwardWin.cs
new file mode 100644
index 0000000..b86009a
--- /dev/null
+++ b/Main/System/OSActivity/OSRankBeautyMMAwardWin.cs
@@ -0,0 +1,18 @@
+锘縰sing System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+// 寮�鏈嶆椿鍔�-绾㈤鍐叉鎺掕濂栧姳
+public class OSRankBeautyMMAwardWin : OSRankAwardBaseWin
+{
+    protected override int GetRankType() => 8; // 8瀵瑰簲绾㈤鍐叉
+    
+    // 鎻愪緵绾㈤姒滅殑濂栧姳瀛楀吀 Key
+    protected override ICollection<int> GetAwardKeys() => OSActivityManager.Instance.beautyMMRankAwards.Keys;
+
+    protected override void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell.GetComponent<OSRankBeautyMMAwardCell>();
+        _cell.Display(cell.index);
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankBeautyMMAwardWin.cs.meta b/Main/System/OSActivity/OSRankBeautyMMAwardWin.cs.meta
new file mode 100644
index 0000000..87ea82f
--- /dev/null
+++ b/Main/System/OSActivity/OSRankBeautyMMAwardWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e232ad2734808eb408390dd9059e49c9
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankBeautyMMGiftCell.cs b/Main/System/OSActivity/OSRankBeautyMMGiftCell.cs
new file mode 100644
index 0000000..07cdc8c
--- /dev/null
+++ b/Main/System/OSActivity/OSRankBeautyMMGiftCell.cs
@@ -0,0 +1,11 @@
+锘縰sing UnityEngine;
+using UnityEngine.UI;
+
+public class OSRankBeautyMMGiftCell : OSRankGiftBaseCell
+{
+    // 浠� Manager 鑾峰彇褰撳墠 Index 瀵瑰簲鐨勭孩棰滅ぜ鍖� ID
+    protected override int GetGiftId(int index) => OSActivityManager.Instance.osBeautyMMGiftSortList[index];
+    
+    // 渚涘熀绫婚獙璇佹椿鍔ㄦ槸鍚﹁繃鏈熸椂浣跨敤锛岀孩棰滃啿姒滃搴旂殑 RankType 涓� 8
+    protected override int GetActivityFuncId() => 8; 
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankBeautyMMGiftCell.cs.meta b/Main/System/OSActivity/OSRankBeautyMMGiftCell.cs.meta
new file mode 100644
index 0000000..f2b80e6
--- /dev/null
+++ b/Main/System/OSActivity/OSRankBeautyMMGiftCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f90bbd7114f1139429d631eed6cab562
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankBeautyMMGiftWin.cs b/Main/System/OSActivity/OSRankBeautyMMGiftWin.cs
new file mode 100644
index 0000000..b5adebb
--- /dev/null
+++ b/Main/System/OSActivity/OSRankBeautyMMGiftWin.cs
@@ -0,0 +1,19 @@
+锘縰sing System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+// 寮�鏈嶆椿鍔�-绾㈤鍐插埡绀煎寘
+public class OSRankBeautyMMGiftWin : OSRankGiftBaseWin
+{
+    // 璋冪敤 Manager 鍒锋柊绀煎寘鎺掑簭
+    protected override void RefreshManagerSortList() => OSActivityManager.Instance.RefreshGiftSortList();
+    
+    // 鎻愪緵绾㈤鍐插埡涓撶敤鐨勭ぜ鍖呭垪琛�
+    protected override IList<int> GetGiftSortList() => OSActivityManager.Instance.osBeautyMMGiftSortList;
+
+    protected override void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as OSRankBeautyMMGiftCell;
+        _cell.Display(cell.index);
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankBeautyMMGiftWin.cs.meta b/Main/System/OSActivity/OSRankBeautyMMGiftWin.cs.meta
new file mode 100644
index 0000000..c9331f5
--- /dev/null
+++ b/Main/System/OSActivity/OSRankBeautyMMGiftWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d22a6513bbd196d41bffe0cfce5efd6c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankBeautyMMWin.cs b/Main/System/OSActivity/OSRankBeautyMMWin.cs
new file mode 100644
index 0000000..d05c521
--- /dev/null
+++ b/Main/System/OSActivity/OSRankBeautyMMWin.cs
@@ -0,0 +1,8 @@
+锘縰sing UnityEngine;
+using UnityEngine.UI;
+
+// 寮�鏈嶆椿鍔�-绾㈤鍐插埡鎺掕姒�
+public class OSRankBeautyMMWin : OSRankBaseWin
+{
+
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankBeautyMMWin.cs.meta b/Main/System/OSActivity/OSRankBeautyMMWin.cs.meta
new file mode 100644
index 0000000..7d0ab85
--- /dev/null
+++ b/Main/System/OSActivity/OSRankBeautyMMWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 482be961781f5cc44959db7fa28e59cf
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankGiftBaseCell.cs b/Main/System/OSActivity/OSRankGiftBaseCell.cs
new file mode 100644
index 0000000..ddfd7e5
--- /dev/null
+++ b/Main/System/OSActivity/OSRankGiftBaseCell.cs
@@ -0,0 +1,176 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+public abstract class OSRankGiftBaseCell : CellView
+{
+    [SerializeField] protected ImageEx vipImage;
+    [SerializeField] protected TextEx vipText;
+    [SerializeField] protected OutlineEx vipTextOutline;
+    [SerializeField] protected ImageEx rateImage;
+    [SerializeField] protected TextEx rateText;
+    [SerializeField] protected Text nameText;
+    [SerializeField] protected ItemCell[] itemCells;
+    [SerializeField] protected Button buyBtn;
+    [SerializeField] protected Text moneyText;
+    [SerializeField] protected Image moneyIcon;
+    [SerializeField] protected Transform saleOutRect;
+    [SerializeField] protected Image redImg;
+    [SerializeField] protected Text buyLimitText;
+    [SerializeField] protected Image maskImg;
+
+    // 鐢卞瓙绫诲疄鐜帮細鑾峰彇绀煎寘ID
+    protected abstract int GetGiftId(int index);
+    // 鐢卞瓙绫诲疄鐜帮細鑾峰彇楠岃瘉娲诲姩鏄惁缁撴潫鎵�闇�鐨勬椿鍔‵uncID
+    protected abstract int GetActivityFuncId();
+
+    public void Display(int index)
+    {
+        var id = GetGiftId(index);
+        if (id > 100000000)
+        {
+            // 鍏呭�肩ぜ鍖�
+            id -= 100000000;
+            var ctgConfig = CTGConfig.Get(id);
+            nameText.text = ctgConfig.Title;
+
+            vipImage.SetActive(ctgConfig.VipLevel > 0);
+            if (ctgConfig.VipLevel > 0)
+            {
+                vipImage.SetSprite($"VipLevel{ctgConfig.VipLevel}");
+                vipText.text = Language.Get($"VipLevelInfo{ctgConfig.VipLevel}");
+                vipText.color = InvestModel.Instance.GetTextColor(ctgConfig.VipLevel);
+                vipTextOutline.OutlineColor = InvestModel.Instance.GetOutlineColor(ctgConfig.VipLevel);
+            }
+
+            rateImage.SetActive(true);
+            rateText.text = Language.Get("DailySpecials07", ctgConfig.Percentage);
+            for (int i = 0; i < itemCells.Length; i++)
+            {
+                var itemCell = itemCells[i];
+                if (i < ctgConfig.GainItemList.Length)
+                {
+                    itemCell.SetActive(true);
+                    int itemID = ctgConfig.GainItemList[i][0];
+                    itemCell.Init(new ItemCellModel(itemID, true, ctgConfig.GainItemList[i][1]));
+                    itemCell.button.SetListener(() => ItemTipUtility.Show(itemID));
+                }
+                else
+                {
+                    itemCell.SetActive(false);
+                }
+            }
+
+            RechargeManager.Instance.TryGetRechargeCount(id, out var rechargeCount);
+            var limitCnt = ctgConfig.DailyBuyCount;
+            if (rechargeCount.todayCount < limitCnt)
+            {
+                saleOutRect.SetActive(false);
+                maskImg.SetActive(false);
+                buyBtn.SetActive(true);
+                buyBtn.SetListener(() =>
+                {
+                    if (!OSActivityManager.Instance.IsOpened(GetActivityFuncId(), false))
+                    {
+                        SysNotifyMgr.Instance.ShowTip("ActivityOver");
+                        return;
+                    }
+
+                    if (ctgConfig.VipLevel > 0 && !FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.PrivilegeCard))
+                    {
+                        SysNotifyMgr.Instance.ShowTip("MinggeAuto8");
+                        return;
+                    }
+                    if (ctgConfig.VipLevel == 1 && !InvestModel.Instance.IsInvested(InvestModel.monthCardType))
+                    {
+                        SysNotifyMgr.Instance.ShowTip("MinggeAuto5");
+                        UIManager.Instance.OpenWindow<PrivilegeCardWin>();
+                        return;
+                    }
+                    if (ctgConfig.VipLevel == 2 && !InvestModel.Instance.IsInvested(InvestModel.foreverCardType))
+                    {
+                        SysNotifyMgr.Instance.ShowTip("MinggeAuto7");
+                        UIManager.Instance.OpenWindow<PrivilegeCardWin>();
+                        return;
+                    }
+
+                    RechargeManager.Instance.CTG(id);
+                });
+
+                RechargeManager.Instance.TryGetOrderInfo(id, out var orderInfo);
+
+                moneyText.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfo.PayRMBNumOnSale));
+                moneyIcon.SetActive(false);
+            }
+            else
+            {
+                saleOutRect.SetActive(true);
+                maskImg.SetActive(true);
+                buyBtn.SetActive(false);
+            }
+            buyLimitText.text = Language.Get("storename6", limitCnt - rechargeCount.todayCount, limitCnt);
+            redImg.SetActive(false);
+        }
+        else
+        {
+            rateImage.SetActive(false);
+            vipImage.SetActive(false);
+            // 鍟嗗簵鐗╁搧
+            var storeConfig = StoreConfig.Get(id);
+            nameText.text = storeConfig.Name;
+            var awards = StoreModel.Instance.GetShopItemlistEx(storeConfig);
+            for (int i = 0; i < itemCells.Length; i++)
+            {
+                var itemCell = itemCells[i];
+                if (i < awards.Count)
+                {
+                    itemCell.SetActive(true);
+                    int itemID = awards[i][0];
+                    itemCell.Init(new ItemCellModel(itemID, true, awards[i][1]));
+                    itemCell.button.SetListener(() => ItemTipUtility.Show(itemID));
+                }
+                else
+                {
+                    itemCell.SetActive(false);
+                }
+            }
+
+            var state = StoreModel.Instance.GetShopIDState(id);
+            if (state == 1)
+            {
+                saleOutRect.SetActive(true);
+                maskImg.SetActive(true);
+                buyBtn.SetActive(false);
+                redImg.SetActive(false);
+            }
+            else
+            {
+                saleOutRect.SetActive(false);
+                maskImg.SetActive(false);
+                buyBtn.SetActive(true);
+                buyBtn.SetListener(() =>
+                {
+                    if (!OSActivityManager.Instance.IsOpened(GetActivityFuncId(), false))
+                    {
+                        SysNotifyMgr.Instance.ShowTip("ActivityOver");
+                        return;
+                    }
+
+                    StoreModel.Instance.SendBuyShopItemWithPopCheck(storeConfig, 1);
+                });
+                moneyText.text = storeConfig.MoneyNum == 0 ? Language.Get("L1127") : storeConfig.MoneyNum.ToString();
+                moneyIcon.SetActive(storeConfig.MoneyNum != 0);
+                if (storeConfig.MoneyType <= 0)
+                {
+                    moneyIcon.SetItemSprite(storeConfig.CostItemID);
+                }
+                else
+                {
+                    moneyIcon.SetIconWithMoneyType(storeConfig.MoneyType);
+                }
+                redImg.SetActive(storeConfig.MoneyNum == 0);
+            }
+            var buyCnt = StoreModel.Instance.GetShopLimitBuyCount(id);
+            buyLimitText.text = Language.Get("storename6", storeConfig.LimitCnt - buyCnt, storeConfig.LimitCnt);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankGiftBaseCell.cs.meta b/Main/System/OSActivity/OSRankGiftBaseCell.cs.meta
new file mode 100644
index 0000000..163e33d
--- /dev/null
+++ b/Main/System/OSActivity/OSRankGiftBaseCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8fbb7021663b5294594aac0a985165da
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankGiftBaseWin.cs b/Main/System/OSActivity/OSRankGiftBaseWin.cs
new file mode 100644
index 0000000..657ea67
--- /dev/null
+++ b/Main/System/OSActivity/OSRankGiftBaseWin.cs
@@ -0,0 +1,48 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public abstract class OSRankGiftBaseWin : UIBase
+{
+    [SerializeField] protected ScrollerController scrollerController;
+
+    protected override void OnPreOpen()
+    {
+        scrollerController.OnRefreshCell += OnRefreshCell;
+        StoreModel.Instance.RefreshBuyShopLimitEvent += RefreshStore;
+        RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent;
+        RefreshManagerSortList();
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        scrollerController.OnRefreshCell -= OnRefreshCell;
+        StoreModel.Instance.RefreshBuyShopLimitEvent -= RefreshStore;
+        RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent;
+    }
+
+    protected abstract void RefreshManagerSortList();
+    protected abstract IList<int> GetGiftSortList();
+    protected abstract void OnRefreshCell(ScrollerDataType type, CellView cell);
+
+    protected void Display()
+    {
+        scrollerController.Refresh();
+        var list = GetGiftSortList();
+        for (int i = 0; i < list.Count; i++)
+        {
+            scrollerController.AddCell(ScrollerDataType.Header, i);
+        }
+        scrollerController.Restart();
+    }
+
+    protected void RefreshStore()
+    {
+        scrollerController.m_Scorller.RefreshActiveCellViews();
+    }
+
+    protected void OnRechargeCountEvent(int id)
+    {
+        scrollerController.m_Scorller.RefreshActiveCellViews();
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankGiftBaseWin.cs.meta b/Main/System/OSActivity/OSRankGiftBaseWin.cs.meta
new file mode 100644
index 0000000..7e1d7f3
--- /dev/null
+++ b/Main/System/OSActivity/OSRankGiftBaseWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 86879ba6d3ff65a41b612365b69eae6e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankHeroCallGiftCell.cs b/Main/System/OSActivity/OSRankHeroCallGiftCell.cs
index df82579..2b23760 100644
--- a/Main/System/OSActivity/OSRankHeroCallGiftCell.cs
+++ b/Main/System/OSActivity/OSRankHeroCallGiftCell.cs
@@ -5,6 +5,11 @@
 
 public class OSRankHeroCallGiftCell : CellView
 {
+    [SerializeField] ImageEx vipImage;
+    [SerializeField] TextEx vipText;
+    [SerializeField] OutlineEx vipTextOutline;
+    [SerializeField] ImageEx rateImage;
+    [SerializeField] TextEx rateText;
     [SerializeField] Text nameText;
     [SerializeField] ItemCell[] itemCells;
     [SerializeField] Button buyBtn;
@@ -24,6 +29,18 @@
             id -= 100000000;
             var ctgConfig = CTGConfig.Get(id);
             nameText.text = ctgConfig.Title;
+
+            vipImage.SetActive(ctgConfig.VipLevel > 0);
+            if (ctgConfig.VipLevel > 0)
+            {
+                vipImage.SetSprite($"VipLevel{ctgConfig.VipLevel}");
+                vipText.text = Language.Get($"VipLevelInfo{ctgConfig.VipLevel}");
+                vipText.color = InvestModel.Instance.GetTextColor(ctgConfig.VipLevel);
+                vipTextOutline.OutlineColor = InvestModel.Instance.GetOutlineColor(ctgConfig.VipLevel);
+            }
+
+            rateImage.SetActive(true);
+            rateText.text = Language.Get("DailySpecials07", ctgConfig.Percentage);
             for (int i = 0; i < itemCells.Length; i++)
             {
                 var itemCell = itemCells[i];
@@ -53,13 +70,30 @@
                         SysNotifyMgr.Instance.ShowTip("ActivityOver");
                         return;
                     }
-                    
+                    if (ctgConfig.VipLevel > 0 && !FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.PrivilegeCard))
+                    {
+                        SysNotifyMgr.Instance.ShowTip("MinggeAuto8");
+                        return;
+                    }
+                    if (ctgConfig.VipLevel == 1 && !InvestModel.Instance.IsInvested(InvestModel.monthCardType))
+                    {
+                        SysNotifyMgr.Instance.ShowTip("MinggeAuto5");
+                        UIManager.Instance.OpenWindow<PrivilegeCardWin>();
+                        return;
+                    }
+                    if (ctgConfig.VipLevel == 2 && !InvestModel.Instance.IsInvested(InvestModel.foreverCardType))
+                    {
+                        SysNotifyMgr.Instance.ShowTip("MinggeAuto7");
+                        UIManager.Instance.OpenWindow<PrivilegeCardWin>();
+                        return;
+                    }
+
                     RechargeManager.Instance.CTG(id);
                 });
 
                 RechargeManager.Instance.TryGetOrderInfo(id, out var orderInfo);
 
-                moneyText.text = Language.Get("PayMoneyNum", orderInfo.PayRMBNumOnSale);
+                moneyText.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfo.PayRMBNumOnSale));
                 moneyIcon.SetActive(false);
             }
             else
@@ -74,6 +108,8 @@
         }
         else
         {
+            rateImage.SetActive(false);
+            vipImage.SetActive(false);
             //鍟嗗簵
             var storeConfig = StoreConfig.Get(id);
             nameText.text = storeConfig.Name;
@@ -119,9 +155,16 @@
                 });
                 moneyText.text = storeConfig.MoneyNum == 0 ? Language.Get("L1127") : storeConfig.MoneyNum.ToString();
                 moneyIcon.SetActive(storeConfig.MoneyNum != 0);
-                moneyIcon.SetIconWithMoneyType(storeConfig.MoneyType);
+                if (storeConfig.MoneyType <= 0)
+                {
+                    moneyIcon.SetItemSprite(storeConfig.CostItemID);
+                }
+                else
+                {
+                    moneyIcon.SetIconWithMoneyType(storeConfig.MoneyType);
+                }
                 redImg.SetActive(storeConfig.MoneyNum == 0);
-            }   
+            }
             var buyCnt = StoreModel.Instance.GetShopLimitBuyCount(id);
             buyLimitText.text = Language.Get("storename6", storeConfig.LimitCnt - buyCnt, storeConfig.LimitCnt);
 
diff --git a/Main/System/OSActivity/OSRankHeroTrainAwardCell.cs b/Main/System/OSActivity/OSRankHeroTrainAwardCell.cs
new file mode 100644
index 0000000..a8f5d7d
--- /dev/null
+++ b/Main/System/OSActivity/OSRankHeroTrainAwardCell.cs
@@ -0,0 +1,10 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class OSRankHeroTrainAwardCell : OSRankAwardBaseCell
+{
+    protected override Dictionary<int, int[][]> GetRankAwards()
+    {
+        return OSActivityManager.Instance.heroTrainRankAwards;
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankHeroTrainAwardCell.cs.meta b/Main/System/OSActivity/OSRankHeroTrainAwardCell.cs.meta
new file mode 100644
index 0000000..65b4d5b
--- /dev/null
+++ b/Main/System/OSActivity/OSRankHeroTrainAwardCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5cc407297dbf0a049bc7572140a7fc37
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankHeroTrainAwardWin.cs b/Main/System/OSActivity/OSRankHeroTrainAwardWin.cs
new file mode 100644
index 0000000..a04f696
--- /dev/null
+++ b/Main/System/OSActivity/OSRankHeroTrainAwardWin.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+// 寮�鏈嶆椿鍔�-姝﹀皢鍐叉 鎺掕濂栧姳
+public class OSRankHeroTrainAwardWin : OSRankAwardBaseWin
+{
+    protected override int GetRankType() => 7; 
+    
+    protected override ICollection<int> GetAwardKeys() => OSActivityManager.Instance.heroTrainRankAwards.Keys;
+
+    protected override void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell.GetComponent<OSRankHeroTrainAwardCell>();
+        _cell.Display(cell.index);
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankHeroTrainAwardWin.cs.meta b/Main/System/OSActivity/OSRankHeroTrainAwardWin.cs.meta
new file mode 100644
index 0000000..ccf7ac2
--- /dev/null
+++ b/Main/System/OSActivity/OSRankHeroTrainAwardWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5d0f7383e172ba1479bd29fa004f952f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankHeroTrainGiftCell.cs b/Main/System/OSActivity/OSRankHeroTrainGiftCell.cs
new file mode 100644
index 0000000..cb5f6cb
--- /dev/null
+++ b/Main/System/OSActivity/OSRankHeroTrainGiftCell.cs
@@ -0,0 +1,8 @@
+using UnityEngine;
+
+public class OSRankHeroTrainGiftCell : OSRankGiftBaseCell
+{
+    protected override int GetGiftId(int index) => OSActivityManager.Instance.osHeroTrainGiftSortList[index];
+    
+    protected override int GetActivityFuncId() => 7; 
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankHeroTrainGiftCell.cs.meta b/Main/System/OSActivity/OSRankHeroTrainGiftCell.cs.meta
new file mode 100644
index 0000000..97e4bc9
--- /dev/null
+++ b/Main/System/OSActivity/OSRankHeroTrainGiftCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 38e95d017835dd648afc115072b85c31
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankHeroTrainGiftWin.cs b/Main/System/OSActivity/OSRankHeroTrainGiftWin.cs
new file mode 100644
index 0000000..527e51c
--- /dev/null
+++ b/Main/System/OSActivity/OSRankHeroTrainGiftWin.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+// 寮�鏈嶆椿鍔�-姝﹀皢鍐叉 绀煎寘鐣岄潰
+public class OSRankHeroTrainGiftWin : OSRankGiftBaseWin
+{
+    protected override void RefreshManagerSortList() => OSActivityManager.Instance.RefreshGiftSortList();
+    
+    protected override IList<int> GetGiftSortList() => OSActivityManager.Instance.osHeroTrainGiftSortList;
+
+    protected override void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as OSRankHeroTrainGiftCell;
+        _cell.Display(cell.index);
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankHeroTrainGiftWin.cs.meta b/Main/System/OSActivity/OSRankHeroTrainGiftWin.cs.meta
new file mode 100644
index 0000000..370e1be
--- /dev/null
+++ b/Main/System/OSActivity/OSRankHeroTrainGiftWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 21d442383c4ea6846bca35096f7d38b5
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankHeroTrainWin.cs b/Main/System/OSActivity/OSRankHeroTrainWin.cs
new file mode 100644
index 0000000..893330f
--- /dev/null
+++ b/Main/System/OSActivity/OSRankHeroTrainWin.cs
@@ -0,0 +1,20 @@
+using UnityEngine;
+
+// 寮�鏈嶆椿鍔�-姝﹀皢鍐叉 鎺掕姒滅晫闈�
+public class OSRankHeroTrainWin : OSRankBaseWin
+{
+    [SerializeField] ButtonEx rule;
+    [SerializeField] TextEx title;
+
+    protected override void InitComponent()
+    {
+        base.InitComponent();
+        rule.AddListener(() =>
+        {
+            OSRankTipWin.infoTextKey = "OSActivityHeroTrainRankTip";
+            OSRankTipWin.isDownShow = true;
+            OSRankTipWin.worldPos = title.transform.position;
+            UIManager.Instance.OpenWindow<OSRankTipWin>();
+        });
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankHeroTrainWin.cs.meta b/Main/System/OSActivity/OSRankHeroTrainWin.cs.meta
new file mode 100644
index 0000000..c041cdb
--- /dev/null
+++ b/Main/System/OSActivity/OSRankHeroTrainWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f45bd7a3a06d7984db7e8be475988387
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankMinggeAwardCell.cs b/Main/System/OSActivity/OSRankMinggeAwardCell.cs
new file mode 100644
index 0000000..cd45eee
--- /dev/null
+++ b/Main/System/OSActivity/OSRankMinggeAwardCell.cs
@@ -0,0 +1,10 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class OSRankMinggeAwardCell : OSRankAwardBaseCell
+{
+    protected override Dictionary<int, int[][]> GetRankAwards()
+    {
+        return OSActivityManager.Instance.minggeRankAwards;
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankMinggeAwardCell.cs.meta b/Main/System/OSActivity/OSRankMinggeAwardCell.cs.meta
new file mode 100644
index 0000000..2ac590f
--- /dev/null
+++ b/Main/System/OSActivity/OSRankMinggeAwardCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 71ff4f534dbed074f8cb364e370af500
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankMinggeAwardWin.cs b/Main/System/OSActivity/OSRankMinggeAwardWin.cs
new file mode 100644
index 0000000..fe00b67
--- /dev/null
+++ b/Main/System/OSActivity/OSRankMinggeAwardWin.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+// 寮�鏈嶆椿鍔�-鍛芥牸鍐叉 鎺掕濂栧姳
+public class OSRankMinggeAwardWin : OSRankAwardBaseWin
+{
+    protected override int GetRankType() => 9; 
+    
+    protected override ICollection<int> GetAwardKeys() => OSActivityManager.Instance.minggeRankAwards.Keys;
+
+    protected override void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell.GetComponent<OSRankMinggeAwardCell>();
+        _cell.Display(cell.index);
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankMinggeAwardWin.cs.meta b/Main/System/OSActivity/OSRankMinggeAwardWin.cs.meta
new file mode 100644
index 0000000..9035783
--- /dev/null
+++ b/Main/System/OSActivity/OSRankMinggeAwardWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a231c309850cec941ae052a5b63759aa
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankMinggeGiftCell.cs b/Main/System/OSActivity/OSRankMinggeGiftCell.cs
new file mode 100644
index 0000000..2793205
--- /dev/null
+++ b/Main/System/OSActivity/OSRankMinggeGiftCell.cs
@@ -0,0 +1,8 @@
+using UnityEngine;
+
+public class OSRankMinggeGiftCell : OSRankGiftBaseCell
+{
+    protected override int GetGiftId(int index) => OSActivityManager.Instance.osMinggeGiftSortList[index];
+    
+    protected override int GetActivityFuncId() => 9; 
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankMinggeGiftCell.cs.meta b/Main/System/OSActivity/OSRankMinggeGiftCell.cs.meta
new file mode 100644
index 0000000..a0d8a05
--- /dev/null
+++ b/Main/System/OSActivity/OSRankMinggeGiftCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b76c8d10a8833af4283ec5019d7eb1a8
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankMinggeGiftWin.cs b/Main/System/OSActivity/OSRankMinggeGiftWin.cs
new file mode 100644
index 0000000..9ca5c2b
--- /dev/null
+++ b/Main/System/OSActivity/OSRankMinggeGiftWin.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+// 寮�鏈嶆椿鍔�-鍛芥牸鍐叉 绀煎寘鐣岄潰
+public class OSRankMinggeGiftWin : OSRankGiftBaseWin
+{
+    protected override void RefreshManagerSortList() => OSActivityManager.Instance.RefreshGiftSortList();
+    
+    protected override IList<int> GetGiftSortList() => OSActivityManager.Instance.osMinggeGiftSortList;
+
+    protected override void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as OSRankMinggeGiftCell;
+        _cell.Display(cell.index);
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankMinggeGiftWin.cs.meta b/Main/System/OSActivity/OSRankMinggeGiftWin.cs.meta
new file mode 100644
index 0000000..ae54344
--- /dev/null
+++ b/Main/System/OSActivity/OSRankMinggeGiftWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fef31dcb5d0ae29429d43002f1fc9127
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankMinggeWin.cs b/Main/System/OSActivity/OSRankMinggeWin.cs
new file mode 100644
index 0000000..fa89578
--- /dev/null
+++ b/Main/System/OSActivity/OSRankMinggeWin.cs
@@ -0,0 +1,20 @@
+using UnityEngine;
+
+// 寮�鏈嶆椿鍔�-鍛芥牸鍐叉 鎺掕姒滅晫闈�
+public class OSRankMinggeWin : OSRankBaseWin
+{
+    [SerializeField] ButtonEx rule;
+    [SerializeField] TextEx title;
+
+    protected override void InitComponent()
+    {
+        base.InitComponent();
+        rule.AddListener(() =>
+        {
+            OSRankTipWin.infoTextKey = "OSActivityMinggeRankTip";
+            OSRankTipWin.isDownShow = true;
+            OSRankTipWin.worldPos = title.transform.position;
+            UIManager.Instance.OpenWindow<OSRankTipWin>();
+        });
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankMinggeWin.cs.meta b/Main/System/OSActivity/OSRankMinggeWin.cs.meta
new file mode 100644
index 0000000..37e17ea
--- /dev/null
+++ b/Main/System/OSActivity/OSRankMinggeWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: aff3625b0c94913478e9bfffcedf3e86
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OSActivity/OSRankTipWin.cs b/Main/System/OSActivity/OSRankTipWin.cs
new file mode 100644
index 0000000..f801f92
--- /dev/null
+++ b/Main/System/OSActivity/OSRankTipWin.cs
@@ -0,0 +1,98 @@
+using System.Collections.Generic;
+using Cysharp.Threading.Tasks;
+using UnityEngine;
+
+public class OSRankTipWin : UIBase
+{
+
+    [SerializeField] RectTransform rectTransform;
+    [SerializeField] RectTransform arrowImage;
+    [SerializeField] RectTransform arrowUpImage;
+    [SerializeField] RichText txtInfo;
+
+    public static Vector3 worldPos; //涓栫晫鍧愭爣绯讳綅缃�
+    public static bool isDownShow = false;  // 鏄惁鍚戜笅鏄剧ず
+    public static string infoTextKey;
+    public const int rowCountMax = 4;
+    protected override void OnPreOpen()
+    {
+
+        rectTransform.position = new Vector3(100, 100, 100);   //鍒濆鍖栨椂锛屽睆骞曡寖鍥村
+        arrowImage.SetActive(!isDownShow);
+        arrowUpImage.SetActive(isDownShow);
+        txtInfo.text = Language.Get(infoTextKey);
+    }
+
+    protected override void OnPreClose()
+    {
+        isDownShow = false;
+    }
+
+    protected override void OnOpen()
+    {
+        UpdatePos().Forget();
+    }
+
+    async UniTask UpdatePos()
+    {
+        await UniTask.DelayFrame(3);
+        // 闄愬埗鍦ㄥ睆骞曡寖鍥村唴
+        Vector3[] corners = new Vector3[4];
+        rectTransform.GetWorldCorners(corners);
+
+        float minY = corners[0].y;
+        float maxY = corners[0].y;
+
+        for (int i = 1; i < corners.Length; i++)
+        {
+            if (corners[i].y < minY) minY = corners[i].y;
+            if (corners[i].y > maxY) maxY = corners[i].y;
+        }
+
+
+        float screenHeight = maxY - minY;
+        Vector2 adjustedPos = new Vector2(worldPos.x, worldPos.y + (!isDownShow ? screenHeight * 0.5f : -screenHeight * 0.5f));
+
+        Vector2 screenAdjustedPos = CameraManager.uiCamera.WorldToScreenPoint(adjustedPos);
+        var rectWidth = rectTransform.rect.width * Screen.width / canvasScaler.referenceResolution.x;
+        screenAdjustedPos.x = Mathf.Clamp(screenAdjustedPos.x, rectWidth * 0.5f, Screen.width - rectWidth * 0.5f);
+        screenAdjustedPos.y = Mathf.Clamp(screenAdjustedPos.y, rectTransform.rect.height * 0.5f, Screen.height - rectTransform.rect.height * 0.5f - 15);
+
+        adjustedPos = CameraManager.uiCamera.ScreenToWorldPoint(screenAdjustedPos);
+        rectTransform.position = adjustedPos;
+
+        if (!isDownShow)
+        {
+            rectTransform.localPosition = new Vector3(rectTransform.localPosition.x, rectTransform.localPosition.y + 15, rectTransform.localPosition.z);
+        }
+        else
+        {
+            rectTransform.localPosition = new Vector3(rectTransform.localPosition.x, rectTransform.localPosition.y - 15, rectTransform.localPosition.z);
+        }
+
+        rectTransform.GetWorldCorners(corners);
+        float minX = corners[0].x;
+        float maxX = corners[0].x;
+
+        for (int i = 1; i < corners.Length; i++)
+        {
+            if (corners[i].x < minX) minX = corners[i].x;
+            if (corners[i].x > maxX) maxX = corners[i].x;
+        }
+
+        //鏄剧ずarrowImage 鐨剎杞翠笂鐨勪綅缃紝鍜寃orldPos鍚屾锛屼絾涓嶈秴杩噈inX 鍜� maxX鑼冨洿
+        if (!isDownShow)
+        {
+            Vector3 arrowImagePosition = arrowImage.position;
+            arrowImagePosition.x = Mathf.Clamp(worldPos.x, minX, maxX);
+            arrowImage.position = arrowImagePosition;
+        }
+        else
+        {
+            Vector3 arrowUpImagePosition = arrowUpImage.position;
+            arrowUpImagePosition.x = Mathf.Clamp(worldPos.x, minX, maxX);
+            arrowUpImage.position = arrowUpImagePosition;
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OSActivity/OSRankTipWin.cs.meta b/Main/System/OSActivity/OSRankTipWin.cs.meta
new file mode 100644
index 0000000..a1041b1
--- /dev/null
+++ b/Main/System/OSActivity/OSRankTipWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d1b835694fcab6a4d886be2ee0b640d2
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OfficialRank/OfficialTitleCell.cs b/Main/System/OfficialRank/OfficialTitleCell.cs
index 916988a..b192d2c 100644
--- a/Main/System/OfficialRank/OfficialTitleCell.cs
+++ b/Main/System/OfficialRank/OfficialTitleCell.cs
@@ -1,5 +1,4 @@
 锘縰sing System.Collections.Generic;
-using Cysharp.Threading.Tasks;
 using UnityEngine;
 using UnityEngine.UI;
 
@@ -10,7 +9,7 @@
     private void Awake()
     {
         //濡傛灉鏈夐渶瑕佹寜閽偣鍑婚�昏緫锛屽湪澶栧眰鍒涘缓锛屾澶勪笉澶勭悊鐐瑰嚮閫昏緫
-        LoadPrefab().Forget();
+        LoadPrefab();
 
     }
 
@@ -87,7 +86,7 @@
     GameObject prefab;
 
 
-    protected async UniTask LoadPrefab()
+    protected void LoadPrefab()
     {
         if (prefab != null)
             return;
@@ -98,30 +97,16 @@
             prefab = tmp.gameObject;
             return;
         }
-        var inst = await UIUtility.CreateWidget("OfficialTitleCell", "OfficialTitleCell");
-
-        if (this == null)
-        {
-            if (inst != null) GameObject.DestroyImmediate(inst);
-            return;
-        }
-
-        if (prefab != null)
-        {
-            GameObject.DestroyImmediate(inst);
-            return;
-        }
-        prefab = inst;
+        prefab = UIUtility.CreateWidget("OfficialTitleCell", "OfficialTitleCell");
 
         prefab.transform.SetParentEx(this.transform, Vector3.zero, Quaternion.identity, Vector3.one);
         prefab.transform.SetAsFirstSibling();
 
     }
 
-    public async UniTask InitUI(int offcialRank, int titleID)
+    public void InitUI(int offcialRank, int titleID, float scale = 0.6f)
     {
-        await LoadPrefab();   //瀛樺湪琚嵏杞界殑鍙兘锛岄噸鏂板姞杞�
-        if (this == null) return;
+        LoadPrefab();   //瀛樺湪琚嵏杞界殑鍙兘锛岄噸鏂板姞杞�
         if (!TitleConfig.HasKey(titleID))
         {
             officialRankObj.SetActive(true);
@@ -140,7 +125,8 @@
 
             int resourceType = PhantasmPavilionManager.Instance.GetResourceType(PhantasmPavilionType.Title, titleID);
             string resourceValue = PhantasmPavilionManager.Instance.GetResourceValue(PhantasmPavilionType.Title, titleID);
-            PhantasmPavilionManager.Instance.Show(titleImage, effectPlayer, titleUIFrame, resourceType, resourceValue);
+            PhantasmPavilionManager.Instance.Show(PhantasmPavilionType.Title, titleImage, effectPlayer, titleUIFrame, resourceType, resourceValue);
+            titleImage.rectTransform.localScale = new Vector3(scale, scale, scale);
         }
     }
 
diff --git a/Main/System/OpenServerActivity/OpenServerActivityCenter.cs b/Main/System/OpenServerActivity/OpenServerActivityCenter.cs
index 2cdb0d0..079d10c 100644
--- a/Main/System/OpenServerActivity/OpenServerActivityCenter.cs
+++ b/Main/System/OpenServerActivity/OpenServerActivityCenter.cs
@@ -16,22 +16,7 @@
     public enum ActivityType
     {
         AT_JCHD = 0,    //绮惧僵娲诲姩
-        AT_JRZF,    //鑺傛棩绁濈
-        AT_HFHD,    //鍚堟湇娲诲姩
-        AT_Activity1,   //棰勫娲诲姩1
-        AT_Activity2,   //鏃ユ湡鍨嬫椿鍔�- 鎸夋棩鏈熷紑鏀剧殑鎺掕姒滅郴鍒楁椿鍔ㄧ浉鍏� id浠�200寮�濮嬶紙涓庡叾浠栨椿鍔ㄥ尯鍒嗭紝铏界劧id閲嶅骞舵病鏈夊叧绯伙級锛� 绫诲悓鑺傛棩娲诲姩
-        AT_Activity3,   //棰勫娲诲姩3
-        //鍚庣画IL寮�鍙戞坊鍔犻璁�
-        default1,
-        default2,
-        default3,
-        default4,
-        default5,
-        default6,
-        default7,
-        default8,
-        default9,
-        default10,
+        AT_DateActivity,   //鏃ユ湡鍨嬫椿鍔�- 鎸夋棩鏈熷紑鏀剧殑鎺掕姒滅郴鍒楁椿鍔ㄧ浉鍏� id浠�200寮�濮嬶紙涓庡叾浠栨椿鍔ㄥ尯鍒嗭紝铏界劧id閲嶅骞舵病鏈夊叧绯伙級锛� 绫诲悓鑺傛棩娲诲姩
     }
 
     public OpenServerActivityCenter()
diff --git a/Main/System/OpenServerActivity/OperationTimeHepler.cs b/Main/System/OpenServerActivity/OperationTimeHepler.cs
index 6e75950..b4ef7bc 100644
--- a/Main/System/OpenServerActivity/OperationTimeHepler.cs
+++ b/Main/System/OpenServerActivity/OperationTimeHepler.cs
@@ -435,17 +435,17 @@
     public void UpdateActLunhuidianInfo(HAA88_tagMCActLunhuidianInfo package)
     {
         OperationBase operationBase = null;
-        operationDict.TryGetValue(OperationType.default47, out operationBase);
+        operationDict.TryGetValue(OperationType.TimeRush, out operationBase);
         if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate))
         {
-            ForceStopOperation(OperationType.default47);
+            ForceStopOperation(OperationType.TimeRush);
         }
         else
         {
             if (operationBase == null)
             {
                 operationBase = new OperationCycleHall();
-                operationDict.Add(OperationType.default47, operationBase);
+                operationDict.Add(OperationType.TimeRush, operationBase);
             }
             OperationCycleHall operation = operationBase as OperationCycleHall;
             operation.Reset();
@@ -456,9 +456,43 @@
             operation.ParseCycleHallInfo(package);
             if (operationTimeUpdateEvent != null)
             {
-                operationTimeUpdateEvent(OperationType.default47);
+                operationTimeUpdateEvent(OperationType.TimeRush);
             }
         }
+    }
+
+    public void UpdateActHeroAppearInfo(HAA21_tagSCActHeroAppearInfo package)
+    {
+        var opreationType = OperationType.HeroDebut;
+        switch (package.ActNum)
+        {
+            case 10:
+                opreationType = OperationType.HeroDebut;
+                break;
+            // case 11:
+            //     opreationType = OperationType.HeroBack;
+            //     break;
+        }
+
+        if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate))
+        {
+            ForceStopOperation(opreationType);
+            return;
+        }
+
+        if (!operationDict.TryGetValue(opreationType, out OperationBase operationBase))
+        {
+            operationBase = new OperationHeroAppearInfo();
+            operationDict.Add(opreationType, operationBase);
+        }
+        OperationHeroAppearInfo operation = operationBase as OperationHeroAppearInfo;
+        operation.Reset();
+        operation.startDate = ParseOperationDate(package.StartDate);
+        operation.endDate = ParseOperationDate(package.EndtDate);
+        operation.ActType = package.ActType;
+        operation.CfgID = package.CfgID;
+
+        operationTimeUpdateEvent?.Invoke(opreationType);
     }
 
     // public void UpdateActYunShiInfo(HAA87_tagMCActYunshiInfo package)
@@ -1048,93 +1082,7 @@
 
 public enum OperationType
 {
-
-
-    MultipleExp,
-    ConsumeRebate,
-    FlashSale,//闄愭椂鐗规儬
-    BossReborn,
-    GiftPackage,
-    FairyCeremony, //浠欑晫鐩涘吀
-    MultipRealmPoint, //N鍊嶄慨琛岀偣
-    FlashRushToBuy, //闄愭椂鎶㈣喘
-    WishingWellInfo, //璁告効姹�
-    AccumulateRecharge,//绱鍏呭�硷紝鍗曟棩
-    LoginReward,//鐧诲綍濂栧姳
-    FestivalRedpack,//鑺傛棩绾㈠寘
-    NewYearFairyCeremony, //鏄ヨ妭浠欑晫鐩涘吀
-    SpringFestival,//鏄ヨ妭宸$ぜ
-    OpenServiceAchievement,//涓冩棩宸$ぜ
-    LuckyTreasure,//骞歌繍閴村疂
-    MultiRecharge, //浠欑帀鍏呭�艰繑鍒� 锛堥鍏呭弻鍊嶏級
-    CZBMGift,   // 鎴愰暱蹇呬拱绀煎寘
-    DaysAccumulateRecharge, //绱鍏呭�硷紝澶氭棩
-    CollectWords,   //鏀堕泦鏂囧瓧
-    HolidayLogin,   //鑺傛棩鐧诲綍
-    HolidayWish,   //鑺傛棩绁濈鐏
-    HolidayMultiRecharge,//鑺傛棩绁濈鐨勫鏃ョ疮璁″厖鍊� 鍖呭惈浠绘剰鍏呭�肩晫闈㈠拰澶氭棩绱厖鐣岄潰
-    HolidayTravel,      //鑺傛棩娓稿巻
-    HolidayAccumulateRecharge, //鑺傛棩-鍗曟棩鐨勭疮绉厖鍊�
-    HolidayCollectWords, //鑺傛棩-闆嗗瓧
-    HolidayGiftPackage, //鑺傛棩绁濈-闄愭椂绀煎寘
-    HolidayFlashRushToBuy, //鑺傛棩-闄愭椂鎶㈣喘
-    HolidayFlashSale, //鑺傛棩绁濈-闄愭椂鐗规儬
-    HolidayConsumeRebate, //鑺傛棩绁濈-娑堣垂杩斿埄
-
-    //鍚庣画IL寮�鍙戞坊鍔犻璁�
-    default1,   // 杩炵画澶氭棩绱厖
-    default2,
-    default3,   // 鑺傛棩-鍨冨溇鍒嗙被
-    default4,   // 鑺傛棩-缈荤墝
-    default5,
-    default6,
-    default7,   // 绮惧僵娲诲姩-璺ㄦ湇鍏呭��
-    default8,   // 鍚堟湇-绂忓埄锛堝鏃ョ疮鍏�1妗o級
-    default9,   // 鍚堟湇-杞洏
-    default10,  // 鍚堟湇-闆嗗瓧鐙傛
-    default11,  // 鍚堟湇-鍧愰獞鐩涘
-    default12,  // 鍚堟湇-瓒呭�奸檺璐�
-    default13,  // 鍚堟湇-闄愭椂绀煎寘
-    default14,
-    default15,
-    default16,
-    default17,
-    default18,  // 骞歌繍浜戣喘
-    default19,
-    default20,  //鑺傛棩鎸囧畾绱鍏呭�奸搴︼紝鍜岃妭鏃ヤ换鎰忓厖鍊肩嫭绔嬩袱涓晫闈�
-    default21,
-    default22,  //澶╁笣绀煎寘
-    default23,
-    default24,
-    default25,  //涔�1閫�5
-    default26,
-    default27,  //鏃ユ湡鍨嬫椿鍔�- boss鍘嗙粌娲诲姩
-    default28,  //绮惧僵娲诲姩-鍗曠瑪鍏呭��
-    default29,  //鏃ユ湡鍨嬫椿鍔�- 鐧诲綍锛屽彲琛ョ
-    default30,  //鏃ユ湡鍨嬫椿鍔�- 浠诲姟
-    default31,  //鏃ユ湡鍨嬫椿鍔�- 绀煎寘锛屽彲绱璐拱娆℃暟棰嗗彇
-    default32,  //绂忕紭- 闀夸箙绱厖锛堝嚑涓湀鎴栨洿闀匡級 鐙珛鐣岄潰
-    default33,  //鏃ユ湡鍨嬫椿鍔�- boss 鍘嗙粌娲诲姩(璺ㄦ湇) 蹇呴』鍜屾椿鍔╠efault27涓�璧蜂娇鐢�
-    default34,  //鏃ユ湡鍨嬫椿鍔�- 浠欑洘鍏呭�间簰鍔╋紝鐗规畩锛氬厑璁稿涓椿鍔ㄥ悓鏃跺紑鍚�
-    default35,  //鑷�夌ぜ鍖�
-    default36,  //鏃ユ湡鍨嬫椿鍔�- 绉樺瀵诲疂锛堢被浠欏專锛� 涓绘椿鍔�
-    default37,  //鏃ユ湡鍨嬫椿鍔�- 绉樺瀵诲疂锛堢被浠欏專锛� 璺ㄦ湇
-    default38,  //鏃ユ湡鍨嬫椿鍔�- 鑷�夌ぜ鍖� + 鍟嗗簵
-    default39,  //鏃ユ湡鍨嬫椿鍔�- 楠戝疇鍩瑰吇鏈湇
-    default40,  //鏃ユ湡鍨嬫椿鍔�- 楠戝疇鍩瑰吇璺ㄦ湇
-    default41,  //鏃ユ湡鍨嬫椿鍔�- 鍙ゅ疂鍏绘垚鏈湇
-    default42,  //鏃ユ湡鍨嬫椿鍔�- 鍙ゅ疂鍏绘垚璺ㄦ湇
-    default43,  ////鏃ユ湡鍨嬫椿鍔�- 浠诲姟鐜�
-    default44,  //鏃ユ湡鍨嬫椿鍔� - 浠欑紭鐧婚檰,鍙ˉ绛�
-    default45,  //鏃ユ湡鍨嬫椿鍔� - 浠欑紭浠诲姟
-    default46,  //鏃ユ湡鍨嬫椿鍔� - 浠欑紭绀煎寘
-    default47,  //鏃ユ湡鍨嬫椿鍔� - 杞洖娈�
-    default48,  //鏃ユ湡鍨嬫椿鍔� - 杩愬娍瀵诲疂
-    default49,  //鏃ユ湡鍨嬫椿鍔� - 杩愬娍浠诲姟
-    default50,  //鏃ユ湡鍨嬫椿鍔� - 杩愬娍绀煎寘
-    default51,  //鏃ユ湡鍨嬫椿鍔� - 浠欏尃澶т細鐐煎櫒
-    default52,  //鏃ユ湡鍨嬫椿鍔� - 浠欏尃澶т細绀煎寘
-    default53,  //鏃ユ湡鍨嬫椿鍔� - 浠欑洘鏀诲煄鎴� 璺ㄦ湇
-    default54,  //鏃ユ湡鍨嬫椿鍔� - 浠欑洘鏀诲煄鎴樹粰鐩熷崗鍔╁拰绀煎寘
+    TimeRush = 1,  //鏃ユ湡鍨嬫椿鍔� - 杞洖娈�
+    HeroDebut = 2,  //鏃ユ湡鍨嬫椿鍔� - 姝﹀皢鐧诲満
     max,
 }
\ No newline at end of file
diff --git a/Main/System/OtherPlayerDetail/BuffInfoCell.cs b/Main/System/OtherPlayerDetail/BuffInfoCell.cs
new file mode 100644
index 0000000..f070d4a
--- /dev/null
+++ b/Main/System/OtherPlayerDetail/BuffInfoCell.cs
@@ -0,0 +1,33 @@
+using UnityEngine;
+
+public class BuffInfoCell : CellView
+{
+    [SerializeField] TextEx buffNameText;
+    [SerializeField] TextEx roundText;
+    [SerializeField] ImageEx buffImage;
+    [SerializeField] TextEx buffCountText;
+    [SerializeField] RichText descText;
+    public void Display(int index, BattleClickBuffData data)
+    {
+        if (data.datas?.Count <= index) return;
+
+        var info = data.datas[index];
+        var config = SkillConfig.Get((int)info.SkillID);
+        if (config == null) return;
+
+        buffImage.SetOrgSprite(config.BuffIconName, "BuffIcon");
+        buffCountText.text = info.Layer == 0 ? "" : info.Layer.ToString();
+
+        buffNameText.text = UIHelper.AppendColor(config.IsDebuff() ? TextColType.Red : TextColType.LightGreen, config.SkillName);
+        descText.text = config.Description;
+        roundText.text = info.LastTime <= 0 ? "" : Language.Get("BuffInfo01", info.LastTime);
+
+        //Debug.Log($"鎶�鑳絀D {info.SkillID} 鎶�鑳藉悕绉� {config.SkillName} 鎶�鑳芥弿杩� {config.Description}");
+    }
+
+    public float GetTextHeight(string content)
+    {
+        descText.text = content;
+        return string.IsNullOrEmpty(content) ? 0 : descText.preferredHeight + 80;
+    }
+}
\ No newline at end of file
diff --git a/Main/System/OtherPlayerDetail/BuffInfoCell.cs.meta b/Main/System/OtherPlayerDetail/BuffInfoCell.cs.meta
new file mode 100644
index 0000000..e54d8a6
--- /dev/null
+++ b/Main/System/OtherPlayerDetail/BuffInfoCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c9e2789d8b3a4e047b0cfbfbc2d0c06d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OtherPlayerDetail/BuffInfoWin.cs b/Main/System/OtherPlayerDetail/BuffInfoWin.cs
new file mode 100644
index 0000000..20134d7
--- /dev/null
+++ b/Main/System/OtherPlayerDetail/BuffInfoWin.cs
@@ -0,0 +1,83 @@
+using System;
+using UnityEngine;
+
+public class BuffInfoWin : UIBase
+{
+    [SerializeField] BuffInfoCell buffInfoCell;
+    [SerializeField] ImageEx teamImage;
+    [SerializeField] ImageEx heroImage;
+    [SerializeField] TextEx heroNameText;
+    [SerializeField] ScrollerController buffScroller;
+    ViewBuffManager manager => ViewBuffManager.Instance;
+    BattleClickBuffData data;
+    protected override void OnPreOpen()
+    {
+        buffScroller.OnRefreshCell += OnRefreshCell;
+        buffScroller.OnGetDynamicSize += OnGetWorldChatDynamicSize;
+
+        data = manager.currentBuffData;
+
+        var heroConfig = HeroConfig.Get(data.heroID);
+        if (heroConfig == null) return;
+
+        var heroSkinConfig = HeroSkinConfig.Get(data.skinID);
+        if (heroSkinConfig == null) return;
+
+        teamImage.SetSprite(data.isMySide ? "OtherHeroDetailBGBlue" : "OtherHeroDetailBGRed");
+         var sprite = UILoader.LoadSprite("HeroHead", HeroSkinConfig.Get(data.skinID).SquareIcon);
+        if (sprite == null)
+        {
+            // 鍐呯綉鏈厤缃椂
+            heroImage.SetSprite("herohead_default");
+        }
+        else
+        {
+            heroImage.overrideSprite = sprite;
+        }
+        heroNameText.text = heroConfig.Name;
+
+        CreateScroller();
+    }
+
+    protected override void OnPreClose()
+    {
+        buffScroller.OnRefreshCell -= OnRefreshCell;
+        buffScroller.OnGetDynamicSize -= OnGetWorldChatDynamicSize;
+    }
+
+    public bool TryGetSkillConfig(int index, out SkillConfig config)
+    {
+        config = null;
+        if (data.datas?.Count <= index)
+            return false;
+        config = SkillConfig.Get((int)data.datas[index].SkillID);
+        return config != null;
+    }
+
+    private bool OnGetWorldChatDynamicSize(ScrollerDataType type, int index, out float height)
+    {
+        height = 0;
+        if (!TryGetSkillConfig(index, out SkillConfig config))
+            return false;
+        height = buffInfoCell.GetTextHeight(config.Description);
+        return true;
+    }
+
+    private void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell.GetComponent<BuffInfoCell>();
+        _cell?.Display(cell.index, data);
+    }
+
+    private void CreateScroller()
+    {
+        buffScroller.Refresh();
+        for (int i = 0; i < data.datas.Count; i++)
+        {
+            buffScroller.AddCell(ScrollerDataType.Header, i);
+        }
+        buffScroller.Restart();
+    }
+
+
+}
\ No newline at end of file
diff --git a/Main/System/OtherPlayerDetail/BuffInfoWin.cs.meta b/Main/System/OtherPlayerDetail/BuffInfoWin.cs.meta
new file mode 100644
index 0000000..e0e8264
--- /dev/null
+++ b/Main/System/OtherPlayerDetail/BuffInfoWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a35bb00628d0ac543b6f512d9d81f1e9
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/OtherPlayerDetail/OtherPlayerDetailWin.cs b/Main/System/OtherPlayerDetail/OtherPlayerDetailWin.cs
index 1317fb3..b0e94fa 100644
--- a/Main/System/OtherPlayerDetail/OtherPlayerDetailWin.cs
+++ b/Main/System/OtherPlayerDetail/OtherPlayerDetailWin.cs
@@ -159,7 +159,7 @@
         txtServerName.text = Language.Get("PlayerProfile11", ServerListCenter.Instance.GetServerName(viewPlayerData.ServerID));
         txtLV.text = viewPlayerData.LV.ToString();
         avatarCell.InitUI(AvatarHelper.GetAvatarModel(viewPlayerData.PlayerID, viewPlayerData.Face, viewPlayerData.FacePic));
-        officialTitle.InitUI(viewPlayerData.RealmLV, viewPlayerData.TitleID);
+        officialTitle.InitUI(viewPlayerData.RealmLV, viewPlayerData.TitleID, 0.65f);
         DisplayHorseModel(viewPlayerData);
 
     }
diff --git a/Main/System/PhantasmPavilion/AvatarCell.cs b/Main/System/PhantasmPavilion/AvatarCell.cs
index b30e46a..4906278 100644
--- a/Main/System/PhantasmPavilion/AvatarCell.cs
+++ b/Main/System/PhantasmPavilion/AvatarCell.cs
@@ -244,7 +244,7 @@
 
         int resourceType = manager.GetResourceType(PhantasmPavilionType.FacePic, facePicID);
         string resourceValue = manager.GetResourceValue(PhantasmPavilionType.FacePic, facePicID);
-        manager.Show(facePicImage, facePicSpine, facePicUIFrame, resourceType, resourceValue);
+        manager.Show(PhantasmPavilionType.FacePic, facePicImage, facePicSpine, facePicUIFrame, resourceType, resourceValue);
 
         faceBGImage.SetNativeSize();
         faceImage.SetNativeSize();
diff --git a/Main/System/PhantasmPavilion/IPhantasmPavilionTabHandler.cs b/Main/System/PhantasmPavilion/IPhantasmPavilionTabHandler.cs
index 777dab0..8110b2d 100644
--- a/Main/System/PhantasmPavilion/IPhantasmPavilionTabHandler.cs
+++ b/Main/System/PhantasmPavilion/IPhantasmPavilionTabHandler.cs
@@ -17,4 +17,5 @@
     int[] GetInitAttrValueList(int id);
     int[] GetAttrPerStarAddList(int id);
     string GetGetWayString(int id);
+    int GetSortIndex(int id);
 }
\ No newline at end of file
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionChatBoxHandler.cs b/Main/System/PhantasmPavilion/PhantasmPavilionChatBoxHandler.cs
index 0902368..1949c04 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionChatBoxHandler.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionChatBoxHandler.cs
@@ -63,5 +63,8 @@
     {
         return ChatBubbleBoxConfig.Get(id).GetWayString;
     }
-
+    public int GetSortIndex(int id)
+    {
+        return ChatBubbleBoxConfig.Get(id).SortIndex;
+    }
 }
\ No newline at end of file
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionChatBoxItem.cs b/Main/System/PhantasmPavilion/PhantasmPavilionChatBoxItem.cs
index 8d4a361..8dfb9f5 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionChatBoxItem.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionChatBoxItem.cs
@@ -39,7 +39,7 @@
 
         int resourceType = manager.GetResourceType(type, id);
         string resourceValue = manager.GetResourceValue(type, id);
-        manager.Show(imgFace, spine, uiFrame, resourceType, resourceValue);
+        manager.Show(PhantasmPavilionType.ChatBox, imgFace, spine, uiFrame, resourceType, resourceValue);
         if (resourceType == 1)
         {
             imgFace.SetNativeSize();
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionFaceHandler.cs b/Main/System/PhantasmPavilion/PhantasmPavilionFaceHandler.cs
index 1860f26..fe0f136 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionFaceHandler.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionFaceHandler.cs
@@ -8,7 +8,20 @@
     }
     public List<int> GetKeyList()
     {
-        return PlayerFaceConfig.GetKeys();
+        List<int> allKeys = PlayerFaceConfig.GetKeys();
+        List<int> validKeys = new List<int>();
+
+        for (int i = 0; i < allKeys.Count; i++)
+        {
+            int id = allKeys[i];
+            var faceCfg = PlayerFaceConfig.Get(id);
+            // 杩囨护鏈揪鍒板紑鏈嶅ぉ鏁扮殑姝﹀皢鍜岀毊鑲ゅご鍍�
+            if (PhantasmPavilionManager.Instance.IsFaceOrModelVisible(faceCfg.UnlockWay, faceCfg.UnlockValue))
+            {
+                validKeys.Add(id);
+            }
+        }
+        return validKeys;
     }
     public int GetResourceType(int id)
     {
@@ -63,5 +76,8 @@
     {
         return PlayerFaceConfig.Get(id).GetWayString;
     }
-
+    public int GetSortIndex(int id)
+    {
+        return PlayerFaceConfig.Get(id).SortIndex;
+    }
 }
\ No newline at end of file
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionFacePicHandler.cs b/Main/System/PhantasmPavilion/PhantasmPavilionFacePicHandler.cs
index ce96f65..34aeffe 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionFacePicHandler.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionFacePicHandler.cs
@@ -64,4 +64,8 @@
     {
         return PlayerFacePicConfig.Get(id).GetWayString;
     }
+    public int GetSortIndex(int id)
+    {
+        return PlayerFacePicConfig.Get(id).SortIndex;
+    }
 }
\ No newline at end of file
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionFacePicItem.cs b/Main/System/PhantasmPavilion/PhantasmPavilionFacePicItem.cs
index 35d8119..827dde1 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionFacePicItem.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionFacePicItem.cs
@@ -37,7 +37,7 @@
 
         int resourceType = manager.GetResourceType(type, id);
         string resourceValue = manager.GetResourceValue(type, id);
-        manager.Show(imgFace, spine, uiFrame, resourceType, resourceValue);
+        manager.Show(PhantasmPavilionType.FacePic, imgFace, spine, uiFrame, resourceType, resourceValue);
 
         manager.UpdateItemRedPoint(imgRed, type, id);
     }
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionFaceWin.cs b/Main/System/PhantasmPavilion/PhantasmPavilionFaceWin.cs
index 79c7ae0..6759c26 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionFaceWin.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionFaceWin.cs
@@ -88,6 +88,7 @@
         manager.OnUpdateFaceInfoEvent += OnUpdateFaceInfoEvent;
         manager.OnUpdateFacePicInfo += OnUpdateFacePicInfo;
         manager.OnTimeOut += OnTimeOut;
+        TimeMgr.Instance.OnDayEvent += OnDayEvent;
         InitRedPoint();
         SelectTiltleBtn();
     }
@@ -107,9 +108,15 @@
         manager.OnUpdateFaceInfoEvent -= OnUpdateFaceInfoEvent;
         manager.OnUpdateFacePicInfo -= OnUpdateFacePicInfo;
         manager.OnTimeOut -= OnTimeOut;
+        TimeMgr.Instance.OnDayEvent -= OnDayEvent;
 
         manager.RemoveAllNewHeroByTabType(PhantasmPavilionType.Face, functionOrder + 1);
         manager.UpdateRedPoint();
+    }
+
+    private void OnDayEvent()
+    {
+        SelectTiltleBtn();
     }
 
     private void OnTimeOut()
@@ -159,14 +166,16 @@
 
     void SelectTeamFunc(PhantasmPavilionType type, bool isRemove = false)
     {
+        var lastType = manager.nowType;
+        manager.nowType = type;
+
         manager.SetSelectItemId(type);
         if (isRemove)
         {
-            manager.RemoveAllNewHeroByTabType(manager.nowType);
+            manager.RemoveAllNewHeroByTabType(lastType);
             manager.UpdateRedPoint();
-            RefreshAll(manager.nowType, false);
+            RefreshAll(lastType, false);
         }
-        manager.nowType = type;
         CreateAll(type);
     }
 
@@ -304,7 +313,7 @@
                 manager.ShowFace(imgNowFacePicFace, UIEffectPlayerNowFacePicFace, uiFrameNowFacePicFace, maskNowFacePicFace, faceID).Forget();
                 str = AvatarHelper.GetAvatarBgColorStr(faceID);
                 imgNowFacePicFaceBg.SetSprite(str);
-                manager.Show(imgNowFacePic, UIEffectPlayerNowFacePic, uiFrameNowFacePic, resourceType, resourceValue);
+                manager.Show(PhantasmPavilionType.FacePic, imgNowFacePic, UIEffectPlayerNowFacePic, uiFrameNowFacePic, resourceType, resourceValue);
                 if (resourceType == 1)
                 {
                     imgNowFacePicFace.SetNativeSize();
@@ -313,7 +322,7 @@
 
                 break;
             case PhantasmPavilionType.ChatBox:
-                manager.Show(imgNowChatBox, UIEffectPlayerNowChatBox, uiFrameNowChatBox, resourceType, resourceValue);
+                manager.Show(PhantasmPavilionType.ChatBox,imgNowChatBox, UIEffectPlayerNowChatBox, uiFrameNowChatBox, resourceType, resourceValue);
                 if (resourceType == 1)
                 {
                     imgNowChatBox.SetNativeSize();
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionInfoCell.cs b/Main/System/PhantasmPavilion/PhantasmPavilionInfoCell.cs
index 8836015..1e26584 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionInfoCell.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionInfoCell.cs
@@ -10,6 +10,17 @@
     {
         int id = cellView.info.Value.infoInt1;
         PhantasmPavilionType type = manager.nowType;
+        //澶╄祴
+        if (index == 10000)
+        {
+            txtUnLockInfo.SetActive(true);
+            txtAddInfo.SetActive(false);
+            var effectInfo = PhantasmPavilionManager.Instance.GetTalentString(type, id);
+            txtUnLockInfo.text = effectInfo;
+            return;
+        }
+
+        //灞炴��
         int[] attrIDList = manager.GetAttrIDList(type, id);
         int[] initAttrValueList = manager.GetInitAttrValueList(type, id);
         if (attrIDList.IsNullOrEmpty() || initAttrValueList.IsNullOrEmpty()
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionManager.Attr.cs b/Main/System/PhantasmPavilion/PhantasmPavilionManager.Attr.cs
index 00ecd7e..8b13ece 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionManager.Attr.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionManager.Attr.cs
@@ -108,4 +108,78 @@
         int attrPerStarAdd = attrPerStarAddList[AttrIndex];
         return initAttrValue + info.Star * attrPerStarAdd;
     }
+
+
+    /// <summary>
+    /// 鑾峰緱鍗曞璞$殑澶╄祴鏁堟灉
+    /// </summary>
+    /// <param name="id">ID</param>
+    /// <param name="defaultAttr">鑷冲皯杩斿洖榛樿鐨� 濡傛湭婵�娲荤殑鏃跺��</param>
+    /// <returns>杩斿洖澶╄祴ID - 鏁堟灉鍊硷紝0浠h〃娌℃湁澶╄祴</returns>
+    public Int2 GetTalentEffect(PhantasmPavilionType type, int id)
+    {
+        if (PhantasmPavilionType.Title != type)
+        {
+            return new Int2(0, 0);
+        }
+        var config = TitleConfig.Get(id);
+        if (TryGetInfo(PhantasmPavilionType.Title, id, out PhantasmPavilionData info))
+        {
+            if (info.State)
+            {
+                return new Int2(config.EffType, config.EffValue + info.Star * config.EffPerStarAdd);
+            }
+        }
+
+        //鏈縺娲昏繑鍥為粯璁�
+        return new Int2(config.EffType, config.EffValue);
+    }
+
+    public string GetTalentString(PhantasmPavilionType type, int id)
+    {
+        if (PhantasmPavilionType.Title != type)
+        {
+            return "";
+        }
+        var config = TitleConfig.Get(id);
+        var values = GetTalentEffect(type, id);
+
+        switch (config.EffType)
+        {
+            case 1:
+                return Language.Get("HJGTalent1", ItemConfig.Get(config.EffTypeValue).ItemName, values.y);
+            default:
+                return Language.Get($"HJGTalent{config.EffType}", values.y);
+        }
+    }
+
+    /// <summary>
+    /// 鑾峰緱鎵�鏈夊璞$殑澶╄祴鎬诲��
+    /// </summary>
+    public int GetTotalTalentValue(PhantasmPavilionType type, int effctType)
+    {
+        if (PhantasmPavilionType.Title != type)
+        {
+            return 0;
+        }
+        var effectValue = 0;
+        dataDict.TryGetValue(type, out var dict);
+        if (dict == null)
+        {
+            return 0;
+        }
+        foreach (var info in dict.Values)
+        {
+            if (!info.State)
+            {
+                continue;
+            }
+            var config = TitleConfig.Get((int)info.ID);
+            if (config.EffType != effctType)
+                continue;
+            effectValue += GetTalentEffect(type, (int)info.ID).y;
+        }
+        return effectValue;
+
+    }
 }
\ No newline at end of file
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionManager.LoadConfig.cs b/Main/System/PhantasmPavilion/PhantasmPavilionManager.LoadConfig.cs
index 2a2d361..e41cd26 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionManager.LoadConfig.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionManager.LoadConfig.cs
@@ -128,4 +128,12 @@
             return string.Empty;
         return handler.GetGetWayString(id);
     }
+    public int GetSortIndex(PhantasmPavilionType type, int id)
+    {
+        if (!TryGetHandlerValue(type, out var handler))
+            return 0;
+        if (!Has(type, id))
+            return 0;
+        return handler.GetSortIndex(id);
+    }
 }
\ No newline at end of file
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionManager.Redpoint.cs b/Main/System/PhantasmPavilion/PhantasmPavilionManager.Redpoint.cs
index 923a788..e1cd0d9 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionManager.Redpoint.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionManager.Redpoint.cs
@@ -73,13 +73,22 @@
                 continue;
             int unlockWay = GetUnlockWay(type, id);
             int unlockValue = GetUnlockValue(type, id);
-            if (unlockWay != 3)
+            if (unlockWay != 3 && unlockWay != 4)
                 continue;
-            bool hasNewHero = HasNewHero(type, unlockValue);
-            if (hasNewHero)
+            if (unlockWay == 3)
             {
-                tabRedPointDict[redType].state = RedPointState.Simple;
+                bool hasNewHero = HasNewHero(type, unlockValue);
+                if (hasNewHero)
+                {
+                    tabRedPointDict[redType].state = RedPointState.Simple;
+                }
             }
+            else if (unlockWay == 4)
+            {
+                if (HasNewSkin(type, unlockValue))
+                    tabRedPointDict[redType].state = RedPointState.Simple;
+            }
+
         }
     }
 
@@ -102,15 +111,21 @@
         }
 
         int unlockWay = GetUnlockWay(type, id);
-        if (unlockWay != 3)
+        if (unlockWay != 3 && unlockWay != 4)
             return;
 
         int unlockValue = GetUnlockValue(type, id);
-        bool hasNewHero = HasNewHero(type, unlockValue);
-        if (hasNewHero)
+        if (unlockWay == 3)
         {
-            imgRed.SetActive(true);
+            if (HasNewHero(type, unlockValue))
+                imgRed.SetActive(true);
         }
+        else if (unlockWay == 4)
+        {
+            if (HasNewSkin(type, unlockValue))
+                imgRed.SetActive(true);
+        }
+
     }
     readonly int funcId = 3;//鍐呮斂
     //鍐呮斂娌″紑涓嶅埛绾㈢偣
@@ -165,21 +180,68 @@
         }
     }
 
-    public List<int> newHeroIDModelList = new List<int>();
-    public List<int> newHeroIDFaceList = new List<int>();
-    public void AddNewHero(int heroID)
+    private HashSet<int> UpdateRedPointItemSet = new HashSet<int>();
+    public HashSet<int> GetUpdateRedPointItemSet()
     {
-        AddNewHero(newHeroIDModelList, heroID);
-        AddNewHero(newHeroIDFaceList, heroID);
+        if (UpdateRedPointItemSet.Count > 0)
+            return UpdateRedPointItemSet;
+
+        var types = (PhantasmPavilionType[])System.Enum.GetValues(typeof(PhantasmPavilionType));
+        foreach (var type in types)
+        {
+            List<int> keys = GetTableKeys(type);
+            if (keys == null)
+                continue;
+
+            foreach (var id in keys)
+            {
+                if (GetUnlockWay(type, id) != 2)
+                    continue;
+
+                int itemId = GetUnlockValue(type, id);
+                UpdateRedPointItemSet.Add(itemId);
+            }
+        }
+
+        return UpdateRedPointItemSet;
     }
 
-    void AddNewHero(List<int> list, int heroID)
+    public List<int> newSkinIDModelList = new List<int>();
+    public List<int> newSkinIDFaceList = new List<int>();
+    string modelSkinKey { get { return StringUtility.Concat("PhantasmPavilion_Redponit_ModelSkin_", PlayerDatas.Instance.PlayerId.ToString()); } }
+    string faceSkinKey { get { return StringUtility.Concat("PhantasmPavilion_Redponit_FaceSkin_", PlayerDatas.Instance.PlayerId.ToString()); } }
+    public void AddNewSkin(int skinID)
     {
-        if (list.Contains(heroID))
+        AddNew(newSkinIDModelList, skinID);
+        AddNew(newSkinIDFaceList, skinID);
+    }
+    // 鎶借薄娣诲姞閫昏緫
+    void AddNew(List<int> list, int id)
+    {
+        if (list.Contains(id))
             return;
-        list.Add(heroID);
+        list.Add(id);
         SaveLocal();
         UpdateRedPoint();
+    }
+
+    public bool HasNewSkin(PhantasmPavilionType type, int skinID)
+    {
+        switch (type)
+        {
+            case PhantasmPavilionType.Model: return newSkinIDModelList.Contains(skinID);
+            case PhantasmPavilionType.Face: return newSkinIDFaceList.Contains(skinID);
+            default: return false;
+        }
+    }
+
+    public List<int> newHeroIDModelList = new List<int>();
+    public List<int> newHeroIDFaceList = new List<int>();
+
+    public void AddNewHero(int heroID)
+    {
+        AddNew(newHeroIDModelList, heroID);
+        AddNew(newHeroIDFaceList, heroID);
     }
 
     public void RemoveAllNewHeroByTabType(PhantasmPavilionType type, int tabType = 0)
@@ -212,31 +274,29 @@
             return;
         int unlockWay = GetUnlockWay(type, id);
         int unlockValue = GetUnlockValue(type, id);
-        if (unlockWay != 3)
-            return;
+        if (unlockWay != 3 && unlockWay != 4) return;
 
         switch (type)
         {
             case PhantasmPavilionType.Model:
-                RemoveNewHero(newHeroIDModelList, unlockValue, isSave);
+                if (unlockWay == 3) RemoveNew(newHeroIDModelList, unlockValue, isSave);
+                else if (unlockWay == 4) RemoveNew(newSkinIDModelList, unlockValue, isSave); // 鐨偆
                 break;
             case PhantasmPavilionType.Face:
-                RemoveNewHero(newHeroIDFaceList, unlockValue, isSave);
+                if (unlockWay == 3) RemoveNew(newHeroIDFaceList, unlockValue, isSave);
+                else if (unlockWay == 4) RemoveNew(newSkinIDFaceList, unlockValue, isSave); // 鐨偆
                 break;
         }
     }
 
-    void RemoveNewHero(List<int> list, int heroID, bool isSave = true)
+    void RemoveNew(List<int> list, int id, bool isSave = true)
     {
-        if (!list.Contains(heroID))
-            return;
-        list.Remove(heroID);
-        if (isSave)
-        {
-            SaveLocal();
-        }
+        if (!list.Contains(id)) return;
+        list.Remove(id);
+        if (isSave) SaveLocal();
         UpdateRedPoint();
     }
+
 
     public bool HasNewHero(PhantasmPavilionType type, int heroID)
     {
@@ -258,11 +318,37 @@
     {
         LocalSave.SetIntArray(modelkey, newHeroIDModelList.ToArray());
         LocalSave.SetIntArray(facekey, newHeroIDFaceList.ToArray());
+        LocalSave.SetIntArray(modelSkinKey, newSkinIDModelList.ToArray());
+        LocalSave.SetIntArray(faceSkinKey, newSkinIDFaceList.ToArray());
     }
     public void LoadLocal()
     {
         LoadLocalModel();
         LoadLocalFace();
+        LoadLocalSkin();
+    }
+
+    void LoadLocalSkin()
+    {
+        if (LocalSave.HasKey(modelSkinKey))
+        {
+            int[] arr = LocalSave.GetIntArray(modelSkinKey);
+            newSkinIDModelList = arr.IsNullOrEmpty() ? new List<int>() : arr.ToList();
+        }
+        else
+        {
+            newSkinIDModelList = new List<int>();
+        }
+
+        if (LocalSave.HasKey(faceSkinKey))
+        {
+            int[] arr = LocalSave.GetIntArray(faceSkinKey);
+            newSkinIDFaceList = arr.IsNullOrEmpty() ? new List<int>() : arr.ToList();
+        }
+        else
+        {
+            newSkinIDFaceList = new List<int>();
+        }
     }
 
     void LoadLocalModel()
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionManager.cs b/Main/System/PhantasmPavilion/PhantasmPavilionManager.cs
index 38c4134..24c28f5 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionManager.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionManager.cs
@@ -54,6 +54,8 @@
         PackManager.Instance.RefreshItemEvent += OnRefreshItemEvent;
         GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
         FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent;
+        HeroUIManager.Instance.OnNewSkinAcquired += OnNewSkinAcquired;
+        TimeMgr.Instance.OnDayEvent += OnDayEvent;
         InitTable();
         InitTabRedPoint();
     }
@@ -66,6 +68,19 @@
         PackManager.Instance.RefreshItemEvent -= OnRefreshItemEvent;
         GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
         FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent;
+        HeroUIManager.Instance.OnNewSkinAcquired -= OnNewSkinAcquired;
+        TimeMgr.Instance.OnDayEvent -= OnDayEvent;
+    }
+
+    private void OnDayEvent()
+    {
+        UpdateRedPoint();
+    }
+
+    private void OnNewSkinAcquired(int arg1, int arg2)
+    {
+        AddNewSkin(arg2);
+        UpdateRedPoint();
     }
 
     private void OnFuncStateChangeEvent(int obj)
@@ -85,9 +100,8 @@
     {
         if (type != PackType.Item)
             return;
-        if (itemID <= 0)
-            return;
-        if (ItemConfig.Get(itemID).Type != 146)
+        var map = GetUpdateRedPointItemSet();
+        if (!map.Contains(itemID))
             return;
         UpdateRedPoint();
     }
@@ -201,15 +215,21 @@
         int unlockValue = GetUnlockValue(type, id);
         int resourceType = GetResourceType(type, id);
         string resourceValue = GetResourceValue(type, id);
-        if (UnlockWay == 3 && resourceValue == "")
+        if ((UnlockWay == 3 || UnlockWay == 4) && resourceValue == "")
         {
-            int heroID = unlockValue;
-            if (!HeroConfig.HasKey(heroID))
-                return;
-            HeroConfig heroConfig = HeroConfig.Get(heroID);
-            int skinID = heroConfig.SkinIDList[0];
-            if (!HeroSkinConfig.HasKey(skinID))
-                return;
+            int skinID = 0;
+            if (UnlockWay == 3)
+            {
+                int heroID = unlockValue;
+                if (!HeroConfig.HasKey(heroID)) return;
+                skinID = HeroConfig.Get(heroID).SkinIDList[0];
+            }
+            else if (UnlockWay == 4)
+            {
+                skinID = unlockValue; // UnlockValue 鐩存帴灏辨槸 skinID
+            }
+
+            if (!HeroSkinConfig.HasKey(skinID)) return;
             HeroSkinConfig skinConfig = HeroSkinConfig.Get(skinID);
             var sprite = await UILoader.LoadSpriteAsync("HeroHead", skinConfig.SquareIcon);
             if (sprite == null)
@@ -249,22 +269,22 @@
             var sprite = await UILoader.LoadSpriteAsync("HeroHead", skinConfig.SquareIcon);
             if (sprite == null)
             {
-                Show(imgFace, spine, uiFrame, resourceType, "herohead_default", null, ellipseMask);
+                Show(type, imgFace, spine, uiFrame, resourceType, "herohead_default", null, ellipseMask);
             }
             else
             {
-                Show(imgFace, spine, uiFrame, resourceType, string.Empty, sprite, ellipseMask);
+                Show(type, imgFace, spine, uiFrame, resourceType, string.Empty, sprite, ellipseMask);
             }
         }
         else
         {
             resourceValue = GetResourceValue(type, id);
-            Show(imgFace, spine, uiFrame, resourceType, resourceValue, null, ellipseMask);
+            Show(type, imgFace, spine, uiFrame, resourceType, resourceValue, null, ellipseMask);
         }
 
     }
 
-    public void Show(ImageEx imgFace, UIEffectPlayer spine, UIFrame uiFrame, int resourceType, string resourceValue, Sprite sprite = null, EllipseMask ellipseMask = null)
+    public void Show(PhantasmPavilionType type, ImageEx imgFace, UIEffectPlayer spine, UIFrame uiFrame, int resourceType, string resourceValue, Sprite sprite = null, EllipseMask ellipseMask = null)
     {
         spine.Stop();
 
@@ -286,9 +306,15 @@
                 {
                     imgFace.overrideSprite = sprite;
                 }
+
+                if (type == PhantasmPavilionType.Title)
+                {
+                    imgFace.SetNativeSize();
+                }
+
                 break;
             case 2: // spine
-                imgFace.enabled = true;
+                imgFace.enabled = false;
                 uiFrame.enabled = false;
                 spine.enabled = true;
 
@@ -308,13 +334,16 @@
                 imgFace.sprite = null;
                 imgFace.overrideSprite = null;
 
-                if (!UIFrameMgr.Inst.ContainsDynamicImage(resourceValue))
-                    break;
-                //List<UnityEngine.Sprite> spriteList = UIFrameMgr.Inst.GetDynamicImage(resourceValue);
-                // if (!spriteList.IsNullOrEmpty())
-                // {
-                //     imgFace.rectTransform.sizeDelta = new Vector2(spriteList[0].rect.width, spriteList[0].rect.height);
-                // }
+                if (type == PhantasmPavilionType.Title)
+                {
+                    if (!UIFrameMgr.Inst.ContainsDynamicImage(resourceValue))
+                        break;
+                    List<Sprite> spriteList = UIFrameMgr.Inst.GetDynamicImage(resourceValue);
+                    if (!spriteList.IsNullOrEmpty())
+                    {
+                        imgFace.rectTransform.sizeDelta = new Vector2(spriteList[0].rect.width, spriteList[0].rect.height);
+                    }
+                }
 
                 uiFrame.ResetFrame(resourceValue);
                 uiFrame.enabled = true;
@@ -363,6 +392,18 @@
     // 鏈夋病鏈夊睘鎬�
     public bool HasInitAttr(PhantasmPavilionType type, int id)
     {
+        if (type == PhantasmPavilionType.Title)
+        {
+            //绉板彿鏈夌壒娈婂ぉ璧嬫晥鏋�
+            var cfg = TitleConfig.Get(id);
+            if (cfg == null)
+            {
+                Debug.LogError($"TitleConfig.Get(id) is null, id: {id}");
+                return false;
+            }
+            if (cfg.EffType > 0)
+                return true;
+        }
         if (!Has(type, id))
             return false;
         int[] attrIDList = GetAttrIDList(type, id);
@@ -431,7 +472,7 @@
 
     public int Cmp(int a, int b, PhantasmPavilionType type)
     {
-        // 鑾峰彇 a 鍜� b 鐨勮В閿佺姸鎬�
+        // 1. 鑾峰彇 a 鍜� b 鐨勮В閿佺姸鎬�
         int stateA = (int)GetUnLockState(type, a);
         int stateB = (int)GetUnLockState(type, b);
 
@@ -439,11 +480,22 @@
         int priorityA = stateA == 2 ? 0 : (stateA == 1 ? 1 : 2);
         int priorityB = stateB == 2 ? 0 : (stateB == 1 ? 1 : 2);
 
-
+        // 浼樺厛鍒ゆ柇鐘舵��
         if (priorityA != priorityB)
         {
             return priorityA.CompareTo(priorityB);
         }
+
+        // 2. 鐘舵�佺浉鍚岀殑璇濓紝鑾峰彇涓よ�呯殑 SortIndex
+        int sortIndexA = GetSortIndex(type, a);
+        int sortIndexB = GetSortIndex(type, b);
+
+        if (sortIndexA != sortIndexB)
+        {
+            return sortIndexA.CompareTo(sortIndexB);
+        }
+
+        // 3. 鐘舵�佸拰 SortIndex 閮界浉鍚岀殑璇濓紝鎸夊敮涓� ID 鎺掑簭
         return a.CompareTo(b);
     }
 
@@ -532,6 +584,9 @@
                 if (IsExpired(info, unlockWay))
                     return false;
                 return true;
+            case PhantasmPavilionUnlockWay.Skin:
+                bool hasSkin = HeroUIManager.Instance.IsHeroSkinActive(HeroConfig.GetHeroIDBySkinID(unlockValue), unlockValue);
+                return hasSkin;
             default:
                 return false;
         }
@@ -571,6 +626,10 @@
             case PhantasmPavilionUnlockWay.Hero:
                 int heroID = unlockValue;
                 return HeroManager.Instance.HasHero(heroID)
+                    ? PhantasmPavilionState.Activated
+                    : PhantasmPavilionState.Locked;
+            case PhantasmPavilionUnlockWay.Skin:
+                return HeroUIManager.Instance.IsHeroSkinActive(HeroConfig.GetHeroIDBySkinID(unlockValue), unlockValue)
                     ? PhantasmPavilionState.Activated
                     : PhantasmPavilionState.Locked;
             default:
@@ -665,6 +724,41 @@
         RefreshAttr();
         UpdateRedPoint();
         OnTimeOut?.Invoke();
+    }
+
+
+    /// <summary>
+    /// 鍒ゆ柇璇ュ舰璞�/澶村儚鏄惁鍙互鏄剧ず鍦ㄥ够澧冮榿鍒楄〃涓�
+    /// </summary>
+    public bool IsFaceOrModelVisible(int unlockWay, int unlockValue)
+    {
+        if (unlockWay == 3)
+        {
+            int heroId = unlockValue;
+            return IsHeroCollectionOpen(heroId);
+        }
+        else if (unlockWay == 4)
+        {
+            // 鐨偆閫斿緞锛孶nlockValue 鏄� SkinID
+            int skinId = unlockValue;
+            return IsHeroCollectionOpen(HeroConfig.GetHeroIDBySkinID(skinId));
+        }
+
+        // 鍏朵粬鑾峰彇閫斿緞锛堝娲诲姩銆侀粯璁ょ瓑锛夛紝涓嶅仛闄愬埗锛岀洿鎺ユ樉绀�
+        return true;
+    }
+
+    /// <summary>
+    /// 妫�鏌ュ搴旀灏嗘槸鍚﹁揪鍒颁簡寮�鏈嶅ぉ鏁拌姹�
+    /// </summary>
+    public bool IsHeroCollectionOpen(int heroId)
+    {
+        var config = HeroConfig.Get(heroId);
+        if (config == null) return false;
+
+        // 0琛ㄧず涓嶉檺鍒跺紑鏈嶅ぉ鏁�
+        if (config.OpenCollectionDay > 0 && TimeUtility.OpenDay + 1 < config.OpenCollectionDay) return false;
+        return true;
     }
 
     #region 鏀跺皝鍖�
@@ -848,6 +942,7 @@
         GameNetSystem.Instance.SendInfo(pack);
     }
 
+
 }
 
 public class PhantasmPavilionData
@@ -882,6 +977,7 @@
     Activate = 1,               // 榛樿(鍒涜鑹插氨鍙互鐢ㄧ殑)
     Item,                       // 閬撳叿
     Hero,                       // 姝﹀皢
+    Skin,                   // 鐨偆
 }
 
 /// 骞诲闃佺墿鍝佺殑鐘舵��
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionModelHandler.cs b/Main/System/PhantasmPavilion/PhantasmPavilionModelHandler.cs
index 7a7f5a2..26b19cc 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionModelHandler.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionModelHandler.cs
@@ -8,7 +8,21 @@
     }
     public List<int> GetKeyList()
     {
-        return ModelConfig.GetKeys();
+        List<int> allKeys = ModelConfig.GetKeys();
+        List<int> validKeys = new List<int>();
+
+        for (int i = 0; i < allKeys.Count; i++)
+        {
+            int id = allKeys[i];
+            var modelCfg = ModelConfig.Get(id);
+
+            // 杩囨护鏈揪鍒板紑鏈嶅ぉ鏁扮殑姝﹀皢鍜岀毊鑲ゅ舰璞�
+            if (PhantasmPavilionManager.Instance.IsFaceOrModelVisible(modelCfg.UnlockWay, modelCfg.UnlockValue))
+            {
+                validKeys.Add(id);
+            }
+        }
+        return validKeys;
     }
     public int GetResourceType(int id)
     {
@@ -63,5 +77,8 @@
     {
         return ModelConfig.Get(id).GetWayString;
     }
-
+    public int GetSortIndex(int id)
+    {
+        return ModelConfig.Get(id).SortIndex;
+    }
 }
\ No newline at end of file
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionModelWin.cs b/Main/System/PhantasmPavilion/PhantasmPavilionModelWin.cs
index 6cc20c6..86b4cdf 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionModelWin.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionModelWin.cs
@@ -60,6 +60,8 @@
         manager.OnUpdateModelInfoEvent += OnUpdateModelInfoEvent;
         manager.OnTimeOut += OnTimeOut;
         manager.OnUpdateModelStarAdd += OnUpdateModelStarAdd;
+        TimeMgr.Instance.OnDayEvent += OnDayEvent;
+
         InitRedPoint();
         TabSetActive();
         SelectTiltleBtn();
@@ -77,9 +79,15 @@
         manager.OnUpdateModelInfoEvent -= OnUpdateModelInfoEvent;
         manager.OnTimeOut -= OnTimeOut;
         manager.OnUpdateModelStarAdd -= OnUpdateModelStarAdd;
+        TimeMgr.Instance.OnDayEvent -= OnDayEvent;
 
         manager.RemoveAllNewHeroByTabType(PhantasmPavilionType.Model, functionOrder + 1);
         manager.UpdateRedPoint();
+    }
+
+    private void OnDayEvent()
+    {
+        SelectTiltleBtn();
     }
 
     private void OnTimeOut()
@@ -112,15 +120,17 @@
 
     void SelectTeamFunc(PhantasmPavilionType type, int order, bool isRemove = false)
     {
+        var lastType = manager.nowType;
+        var lastOrder = functionOrder;
+        manager.nowType = type;
+        functionOrder = order;
         manager.SetSelectItemId(type, order + 1);
         if (isRemove)
         {
-            manager.RemoveAllNewHeroByTabType(manager.nowType, functionOrder + 1);
+            manager.RemoveAllNewHeroByTabType(lastType, lastOrder + 1);
             manager.UpdateRedPoint();
-            RefreshAll(manager.nowType, functionOrder + 1, false);
+            RefreshAll(lastType, lastOrder + 1, false);
         }
-        manager.nowType = type;
-        functionOrder = order;
         CreateAll();
     }
 
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionTilteWin.cs b/Main/System/PhantasmPavilion/PhantasmPavilionTilteWin.cs
index f976df1..beb5433 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionTilteWin.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionTilteWin.cs
@@ -109,9 +109,9 @@
 
     void SelectTeamFunc(PhantasmPavilionType type, int order)
     {
-        manager.SetSelectItemId(type, order + 1);
         manager.nowType = type;
         functionOrder = order;
+        manager.SetSelectItemId(type, order + 1);
         CreateTitleScroller();
         CreateAll();
     }
@@ -185,11 +185,8 @@
     {
         int resourceType = manager.GetResourceType(type, id);
         string resourceValue = manager.GetResourceValue(type, id);
-        manager.Show(imgNowChatBox, UIEffectPlayerNowChatBox, uiFrameNowChatBox, resourceType, resourceValue);
-        if (resourceType == 1)
-        {
-            imgNowChatBox.SetNativeSize();
-        }
+        manager.Show(PhantasmPavilionType.Title, imgNowChatBox, UIEffectPlayerNowChatBox, uiFrameNowChatBox, resourceType, resourceValue);
+
         txtName.text = manager.GetName(type, id);
         txtGetWayString.text = Language.Get("PhantasmPavilion06", manager.GetGetWayString(type, id));
 
@@ -248,6 +245,14 @@
                 scrInfo.AddCell(ScrollerDataType.Header, i, cellInfo);
             }
         }
+
+        //绉板彿鏈夊ぉ璧�
+        if (TitleConfig.Get(id).EffType > 0)
+        {
+            CellInfo cellInfo = new CellInfo();
+            cellInfo.infoInt1 = id;
+            scrInfo.AddCell(ScrollerDataType.Header, 10000, cellInfo);
+        }
         scrInfo.Restart();
     }
 
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionTitleHandler.cs b/Main/System/PhantasmPavilion/PhantasmPavilionTitleHandler.cs
index 3037f5f..849c3c7 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionTitleHandler.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionTitleHandler.cs
@@ -63,6 +63,9 @@
     {
         return TitleConfig.Get(id).GetWayString;
     }
-
+    public int GetSortIndex(int id)
+    {
+        return TitleConfig.Get(id).SortIndex;
+    }
 
 }
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionTitleItem.cs b/Main/System/PhantasmPavilion/PhantasmPavilionTitleItem.cs
index 828e572..1f338ea 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionTitleItem.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionTitleItem.cs
@@ -30,7 +30,7 @@
         PhantasmPavilionState state = manager.GetUnLockState(type, id);
         bool isLimitedTime = manager.IsLimitTime(type, id);
 
-        bool isUsing = manager.IsUsing(type, id); 
+        bool isUsing = manager.IsUsing(type, id);
         imgChoose.SetActive(manager.selectId == id);
         imgBg.SetSprite(manager.selectId == id ? "ChatBoxSelect" : "ChatBoxUnSelect");
         imgLimit.SetActive(state == PhantasmPavilionState.Activated && isLimitedTime);
@@ -40,12 +40,7 @@
 
         int resourceType = manager.GetResourceType(type, id);
         string resourceValue = manager.GetResourceValue(type, id);
-        manager.Show(imgFace, spine, uiFrame, resourceType, resourceValue);
-        if (resourceType == 1)
-        {
-            imgFace.SetNativeSize();
-        }
-
+        manager.Show(PhantasmPavilionType.Title, imgFace, spine, uiFrame, resourceType, resourceValue);
         manager.UpdateItemRedPoint(imgRed, type, id);
     }
 
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionUnlockButton.cs b/Main/System/PhantasmPavilion/PhantasmPavilionUnlockButton.cs
index 395aceb..78d9b25 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionUnlockButton.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionUnlockButton.cs
@@ -40,6 +40,15 @@
                     return;
                 }
             }
+            else if (unlockWay == 4) // 鏂板锛氬鏋滄槸鐨偆瑙i攣
+            {
+                bool hasSkin = HeroUIManager.Instance.IsHeroSkinActive(HeroConfig.GetHeroIDBySkinID(unlockValue), unlockValue);
+                if (!hasSkin)
+                {
+                    SysNotifyMgr.Instance.ShowTip("UnLockFail1");
+                    return;
+                }
+            }
             manager.SendOPPack(type, PhantasmPavilionOperation.Activate, (uint)id);
             SysNotifyMgr.Instance.ShowTip("UnLockSuccess");
         });
diff --git a/Main/System/PhantasmPavilion/PhantasmPavilionWin.cs b/Main/System/PhantasmPavilion/PhantasmPavilionWin.cs
index 9a98265..82c88f7 100644
--- a/Main/System/PhantasmPavilion/PhantasmPavilionWin.cs
+++ b/Main/System/PhantasmPavilion/PhantasmPavilionWin.cs
@@ -5,6 +5,7 @@
 {
     [SerializeField] RedpointBehaviour[] rpTabArr;
     [SerializeField] ImageEx imgModelBG;
+    [SerializeField] ImageEx imgTitleBG;
     PhantasmPavilionManager manager { get { return PhantasmPavilionManager.Instance; } }
     protected override void OnPreOpen()
     {
@@ -23,6 +24,7 @@
     protected override async void OpenSubUIByTabIndex()
     {
         imgModelBG.SetActive(functionOrder == 0);
+        imgTitleBG.SetActive(functionOrder == 2);
         switch (functionOrder)
         {
             case 0:
diff --git a/Main/System/PlayerProfile/ChangeLanguageWin.cs b/Main/System/PlayerProfile/ChangeLanguageWin.cs
new file mode 100644
index 0000000..8bd5bfe
--- /dev/null
+++ b/Main/System/PlayerProfile/ChangeLanguageWin.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class ChangeLanguageWin : UIBase
+{
+    [SerializeField] Toggle[] languageToggles;
+    [SerializeField] Text[] languageTexts;
+    [SerializeField] Button changeBtn;
+
+    List<string> languageList = new List<string>();
+    protected override void InitComponent()
+    {
+        changeBtn.AddListener(() =>
+        {
+            int index = 0;
+            for (int i = 0; i < languageToggles.Length; i++)
+            {
+                if (languageToggles[i].isOn)
+                {
+                    index = i;
+                    break;
+                }
+            }
+
+            var lgId = languageList[index];
+            ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"), Language.Get("language_tip_info"),
+                Language.Get("language_tip_btn2"), Language.Get("language_tip_btn1"), (yes) =>
+            {
+                if (yes)
+                {
+                    Language.Id = lgId;
+#if UNITY_EDITOR
+                    UnityEditor.EditorApplication.isPlaying = false;
+#else
+                    Application.Quit();
+#endif
+                }
+            });
+        });
+    }
+
+    protected override void OnPreOpen()
+    {
+        languageList = new List<string>();
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        base.OnPreClose();
+    }
+
+    void Display()
+    {
+        var languages = Language.GetLanguages();
+        for (int i = 0; i < languageToggles.Length; i++)
+        {
+            if (i < languages.Length)
+            {
+                languageToggles[i].SetActive(true);
+                languageTexts[i].text = Language.languageShowDict[languages[i]];
+                if (Language.Id == languages[i])
+                {
+                    languageToggles[i].isOn = true;
+                }
+                languageList.Add(languages[i]);
+            }
+            else
+            {
+                languageToggles[i].SetActive(false);
+            }
+        }
+    }
+    
+}
\ No newline at end of file
diff --git a/Main/System/PlayerProfile/ChangeLanguageWin.cs.meta b/Main/System/PlayerProfile/ChangeLanguageWin.cs.meta
new file mode 100644
index 0000000..0684b8b
--- /dev/null
+++ b/Main/System/PlayerProfile/ChangeLanguageWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2e64ebc16632a5d4895be9d2e57e2650
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/PlayerProfile/PlayerProfileWin.cs b/Main/System/PlayerProfile/PlayerProfileWin.cs
index 0cad221..ea778a8 100644
--- a/Main/System/PlayerProfile/PlayerProfileWin.cs
+++ b/Main/System/PlayerProfile/PlayerProfileWin.cs
@@ -22,7 +22,8 @@
     [SerializeField] ButtonEx btnSyncPlatformAvatar;
     [SerializeField] ButtonEx btnCopy;
     [SerializeField] ButtonEx btnChangeName;
-    [SerializeField] ButtonEx btnText1;
+    [SerializeField] ButtonEx btnLanguage;
+    [SerializeField] ButtonEx btnText1; // 闅愮鍗忚
     [SerializeField] ButtonEx btnText2;
     protected override void InitComponent()
     {
@@ -62,6 +63,10 @@
                 UIManager.Instance.OpenWindowAsync<PhantasmPavilionWin>().Forget();
             });
         });
+        btnLanguage.AddListener(()=>
+        {
+            UIManager.Instance.OpenWindow<ChangeLanguageWin>();
+        });
     }
 
     protected override void OnPreOpen()
@@ -85,7 +90,7 @@
     {
         if (type == PlayerDataType.ExAttr3)
         {
-            officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
+            officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID, 1f);
         }
     }
 
@@ -109,6 +114,8 @@
         avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)PlayerDatas.Instance.baseData.PlayerID,
                                                     PlayerDatas.Instance.baseData.face,
                                                     PlayerDatas.Instance.baseData.facePic));
-        officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
+        officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID, 1f);
+        var languages = Language.GetLanguages();
+        btnLanguage.SetActive(!languages.IsNullOrEmpty());
     }
 }
\ No newline at end of file
diff --git a/Main/System/PlayerProfile/RenameManager.cs b/Main/System/PlayerProfile/RenameManager.cs
index 5237e52..7b3b052 100644
--- a/Main/System/PlayerProfile/RenameManager.cs
+++ b/Main/System/PlayerProfile/RenameManager.cs
@@ -5,6 +5,7 @@
 {
     public int moneyType;
     public int moneyNeed;
+    public int costItemID;
     public override void Init()
     {
         DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin;
@@ -13,6 +14,7 @@
         int[] arr = ConfigParse.GetMultipleStr<int>(config.Numerical3);
         moneyType = arr[0];
         moneyNeed = arr[1];
+        costItemID = int.Parse(config.Numerical4);
     }
 
     public override void Release()
diff --git a/Main/System/PlayerProfile/RenameWin.cs b/Main/System/PlayerProfile/RenameWin.cs
index 13aff3b..9d206a9 100644
--- a/Main/System/PlayerProfile/RenameWin.cs
+++ b/Main/System/PlayerProfile/RenameWin.cs
@@ -1,7 +1,6 @@
 using System;
 using UnityEngine;
 using UnityEngine.UI;
-using Cysharp.Threading.Tasks;
 
 public class RenameWin : UIBase
 {
@@ -9,8 +8,8 @@
     [SerializeField] Button btnOk;
     [SerializeField] Button btnRandom;
     [SerializeField] TextEx txtFirst;
-    [SerializeField] TextEx txtMoney;
-    [SerializeField] ImageEx imgMoney;
+    [SerializeField] TextEx txtNeedCount;
+    [SerializeField] ImageEx imgIcon;
 
     RenameManager manager { get { return RenameManager.Instance; } }
     protected override void InitComponent()
@@ -20,32 +19,12 @@
         {
             input.text = manager.GetSafeRandomName();
         });
+
         btnOk.SetListener(() =>
         {
             bool isFirstRename = manager.IsFirstRename();
-            if (!isFirstRename && !UIHelper.CheckMoneyCount(manager.moneyType, manager.moneyNeed))
-            {
-                string title = Language.Get("Mail101");
-                string info = Language.Get("PlayerProfile22", RichTextMsgReplaceConfig.GetRichReplace("MONEY", manager.moneyType));
-                ConfirmCancel.ShowPopConfirm(title, info, (bool isOk) =>
-                {
-                    if (isOk)
-                    {
-                        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Recharge, true))
-                            return;
-                        RechargeManager.Instance.selectTabIndex = 1;
-                        if (UIManager.Instance.IsOpened<StoreBaseWin>())
-                        {
-                            UIManager.Instance.GetUI<StoreBaseWin>().ClickFuncBtn(1);
-                        }
-                        else
-                        {
-                            UIManager.Instance.OpenWindowAsync<StoreBaseWin>(1).Forget();
-                        }
-                    }
-                });
+            if (!isFirstRename && !UIHelper.CheckItemCount(manager.costItemID, 1, 2))
                 return;
-            }
 
             if (!manager.CheckNameLimit(input.text, out var errorCode))
             {
@@ -63,7 +42,7 @@
         base.OnPreOpen();
         manager.OnUpdatePlayerNameCountEvent += OnUpdatePlayerNameCount;
         manager.OnUpdateRenameResultEvent += OnUpdateRenameResultEvent;
-        PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefresh;
+        PackManager.Instance.RefreshItemEvent += OnRefreshItemEvent;
         Display();
     }
 
@@ -72,11 +51,15 @@
         base.OnPreClose();
         manager.OnUpdatePlayerNameCountEvent -= OnUpdatePlayerNameCount;
         manager.OnUpdateRenameResultEvent -= OnUpdateRenameResultEvent;
-        PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefresh;
+        PackManager.Instance.RefreshItemEvent -= OnRefreshItemEvent;
     }
 
-    private void PlayerDataRefresh(PlayerDataType type)
+    private void OnRefreshItemEvent(PackType type, int index, int itemID)
     {
+        if (type != PackType.Item)
+            return;
+        if (itemID != manager.costItemID)
+            return;
         Display();
     }
 
@@ -94,8 +77,12 @@
     {
         bool isFirstRename = manager.IsFirstRename();
         txtFirst.SetActive(isFirstRename);
-        txtMoney.SetActive(!isFirstRename);
-        imgMoney.SetIconWithMoneyType(manager.moneyType);
-        txtMoney.text = UIHelper.ShowUseMoney(manager.moneyType, manager.moneyNeed);
+        txtNeedCount.SetActive(!isFirstRename);
+
+        if (!isFirstRename)
+        {
+            imgIcon.SetItemSprite(manager.costItemID);
+            txtNeedCount.text = UIHelper.ShowUseItem(PackType.Item, manager.costItemID, 1);
+        }
     }
-}
+}
\ No newline at end of file
diff --git a/Main/System/Qunying.meta b/Main/System/Qunying.meta
new file mode 100644
index 0000000..ffe550c
--- /dev/null
+++ b/Main/System/Qunying.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 238d6b6ac93c28c4a9701aed893a04c1
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Qunying/QYAchievementCell.cs b/Main/System/Qunying/QYAchievementCell.cs
new file mode 100644
index 0000000..140084e
--- /dev/null
+++ b/Main/System/Qunying/QYAchievementCell.cs
@@ -0,0 +1,76 @@
+锘縰sing System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class QYAchievementCell : CellView
+{
+    [SerializeField] Text rankText;
+    [SerializeField] Image rankImg;
+    [SerializeField] ItemCell[] itemCells;
+    [SerializeField] Transform notActiveText;
+    [SerializeField] Button getBtn;
+    [SerializeField] Transform finishImg;
+
+    public void Display(int rank)
+    {
+        var rankAwards = QunyingManager.Instance.achievementAwards[rank];
+        
+        if (rank <= 3)
+        {
+            rankImg.SetActive(true);
+            rankText.SetActive(false);
+            rankImg.SetSprite($"Rank{rank}");
+        }
+        else
+        {
+            rankImg.SetActive(false);
+            rankText.SetActive(true);
+            rankText.text = rank.ToString();
+        }
+
+        for (int i = 0; i < itemCells.Length; i++)
+        {
+            var itemCell = itemCells[i];
+            if (i < rankAwards.Length)
+            {
+                itemCell.SetActive(true);
+                int itemID = rankAwards[i][0];
+                itemCell.Init(new ItemCellModel(itemID, true, rankAwards[i][1]));
+                itemCell.button.SetListener(() => ItemTipUtility.Show(itemID));
+            }
+            else
+            {
+                itemCell.SetActive(false);
+            }
+        }
+
+        var state = QunyingManager.Instance.GetAchievementState(rank);
+        if (state == 1)
+        {
+            notActiveText.SetActive(false);
+            getBtn.SetActive(true);
+            finishImg.SetActive(false);
+        }
+        else if (state == 2)
+        {
+            notActiveText.SetActive(false);
+            getBtn.SetActive(false);
+            finishImg.SetActive(true);
+        }
+        else
+        {
+            notActiveText.SetActive(true);
+            getBtn.SetActive(false);
+            finishImg.SetActive(false);
+        }
+
+        getBtn.AddListener(() =>
+        {
+            var pack = new CA504_tagCMPlayerGetReward();
+            pack.RewardType = 7;
+            GameNetSystem.Instance.SendInfo(pack);
+        });
+    }
+
+}
diff --git a/Main/System/Qunying/QYAchievementCell.cs.meta b/Main/System/Qunying/QYAchievementCell.cs.meta
new file mode 100644
index 0000000..b37a8d3
--- /dev/null
+++ b/Main/System/Qunying/QYAchievementCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 367255ddd03841c48b32d105723c0c29
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Qunying/QYAchievementWin.cs b/Main/System/Qunying/QYAchievementWin.cs
new file mode 100644
index 0000000..5ac9a66
--- /dev/null
+++ b/Main/System/Qunying/QYAchievementWin.cs
@@ -0,0 +1,62 @@
+using System.Collections.Generic;
+using System.Linq;
+using Cysharp.Threading.Tasks;
+using LitJson;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class QYAchievementWin : UIBase
+{
+    [SerializeField] ScrollerController scroller;
+    [SerializeField] Button closeBtn;
+
+    protected override void InitComponent()
+    {
+
+        closeBtn.AddListener(() =>
+        {
+            CloseWindow();
+        });
+        
+       
+    }
+
+    protected override void OnPreOpen()
+    {
+        scroller.OnRefreshCell += OnRefreshCell;
+        QunyingManager.Instance.OnUpdateQunyingInfoEvent += OnUpdateQunyingInfo;
+
+        scroller.Refresh();
+        var keys = QunyingManager.Instance.achievementAwards.Keys.ToList();
+        keys.Sort();
+        int jumpIndex = 0;
+        for (int i = 0; i < keys.Count; i++)
+        {
+            scroller.AddCell(ScrollerDataType.Header, keys[i]);
+            if (QunyingManager.Instance.GetAchievementState(keys[i]) == 1)
+            {
+                jumpIndex = i;
+            }
+        }
+        scroller.Restart();
+        scroller.JumpIndex(jumpIndex - 5);
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        QunyingManager.Instance.OnUpdateQunyingInfoEvent -= OnUpdateQunyingInfo;
+    }
+
+
+    private void OnRefreshCell(ScrollerDataType type, CellView cellView)
+    {
+        var cell = cellView as QYAchievementCell;
+        cell.Display(cell.index);
+    }
+
+    void OnUpdateQunyingInfo()
+    {
+        scroller.m_Scorller.RefreshActiveCellViews();
+    }
+}
\ No newline at end of file
diff --git a/Main/System/Qunying/QYAchievementWin.cs.meta b/Main/System/Qunying/QYAchievementWin.cs.meta
new file mode 100644
index 0000000..7cc7848
--- /dev/null
+++ b/Main/System/Qunying/QYAchievementWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5a46d946f42d0ae40929cfb07cc095a4
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Qunying/QYBattleFailWin.cs b/Main/System/Qunying/QYBattleFailWin.cs
new file mode 100644
index 0000000..befbd8e
--- /dev/null
+++ b/Main/System/Qunying/QYBattleFailWin.cs
@@ -0,0 +1,99 @@
+using System.Collections.Generic;
+using Cysharp.Threading.Tasks;
+using LitJson;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class QYBattleFailWin : UIBase
+{
+    [SerializeField] AvatarCell myAvatarCell;
+    [SerializeField] AvatarCell enemyAvatarCell;
+    [SerializeField] TextEx txtMyName;
+    [SerializeField] TextEx txtEnemyName;
+    [SerializeField] TextEx txtFuncName;
+    
+    [SerializeField] Button tipHeroCultivateBtn;
+    [SerializeField] Button tipEquipBtn;
+    [SerializeField] Button tipHeroPosBtn;
+    [SerializeField] ButtonEx detailBtn;
+    JsonData jsonData;
+    string battleName = BattleConst.QYBattleField;
+    protected override void InitComponent()
+    {
+        detailBtn.SetListener(() =>
+        {
+            BattleSettlementManager.Instance.OpenBattleDetailWin(battleName);
+        });
+        tipHeroCultivateBtn.AddListener(() =>
+        {
+            CloseWindow();
+        });
+        
+        tipEquipBtn.AddListener(() =>
+        {
+            CloseWindow();
+        });
+
+        tipHeroPosBtn.AddListener(() =>
+        {
+            CloseWindow();
+            UIManager.Instance.OpenWindow<HeroPosWin>();
+        });
+    }
+
+    protected override void OnPreOpen()
+    {
+        jsonData = BattleSettlementManager.Instance.GetBattleSettlement(battleName);
+        if (jsonData == null)
+        {
+            DelayCloseWindow().Forget();
+            return;
+        }
+        Display();
+        if (!FirstChargeManager.Instance.GetLocalFail())
+        {
+            FirstChargeManager.Instance.SetLocalFail();
+        }
+        FirstChargeManager.Instance.TryPopWin();
+    }
+
+    protected override void OnPreClose()
+    {
+        BattleSettlementManager.Instance.WinShowOver(battleName);
+    }
+
+    // B4 20 鍥炲悎鍒舵垬鏂楃姸鎬� #tagMCTurnFightState  閫氱敤鐨勭粨绠楃姸鎬� State 4-缁撶畻濂栧姳
+    // Msg 涓澶栦俊鎭�
+    // "tagPlayerID":瀵规垬鐨勭洰鏍嘔D,
+    // "atkAddScore":鍙戣捣鏂瑰鍔犵殑绉垎锛屽彲鑳戒负0,
+    // "defDecScore":琚嚮鏂瑰噺灏戠殑绉垎锛屽彲鑳戒负0,
+    // itemInfo:濂栧姳鐗╁搧鍒楄〃锛屽彲鑳戒负绌�
+    void Display()
+    {
+        if (!jsonData.ContainsKey("tagPlayerID"))
+            return;
+        uint tagPlayerID = (uint)jsonData["tagPlayerID"];
+
+        if (!QunyingManager.Instance.TryGetPlayerInfo(tagPlayerID, out QunyingMatchInfo info))
+            return;
+        uint enemyFace = info.Face;
+        uint enemyFacePic = info.FacePic;
+
+        myAvatarCell.InitUI(AvatarHelper.GetAvatarModel((int)PlayerDatas.Instance.baseData.PlayerID,
+                                                PlayerDatas.Instance.baseData.face,
+                                                PlayerDatas.Instance.baseData.facePic));
+        enemyAvatarCell.InitUI(AvatarHelper.GetAvatarModel((int)tagPlayerID, (int)enemyFace, (int)enemyFacePic));
+        enemyAvatarCell.SetListener(() =>
+        {
+            AvatarHelper.TryViewOtherPlayerInfo((int)tagPlayerID, viewPlayerLineupType: (int)BattlePreSetType.Qunying);
+        });
+
+        txtMyName.text = PlayerDatas.Instance.baseData.PlayerName;
+        txtEnemyName.text = UIHelper.ServerStringTrim(info.PlayerName);
+
+        int funcId = (int)FuncOpenEnum.Qunying;
+        txtFuncName.text = FuncOpenLVConfig.HasKey(funcId) ? FuncOpenLVConfig.Get(funcId).Name : string.Empty;
+    }
+    
+
+}
\ No newline at end of file
diff --git a/Main/System/Qunying/QYBattleFailWin.cs.meta b/Main/System/Qunying/QYBattleFailWin.cs.meta
new file mode 100644
index 0000000..4726ead
--- /dev/null
+++ b/Main/System/Qunying/QYBattleFailWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 123ef991d6043894482acaa49a2b7776
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Qunying/QYBattleVictoryWin.cs b/Main/System/Qunying/QYBattleVictoryWin.cs
new file mode 100644
index 0000000..bb0650e
--- /dev/null
+++ b/Main/System/Qunying/QYBattleVictoryWin.cs
@@ -0,0 +1,141 @@
+using System.Collections.Generic;
+using Cysharp.Threading.Tasks;
+using LitJson;
+using UnityEngine;
+
+public class QYBattleVictoryWin : UIBase
+{
+    [SerializeField] AvatarCell myAvatarCell;
+    [SerializeField] AvatarCell enemyAvatarCell;
+    [SerializeField] TextEx txtMyName;
+    [SerializeField] TextEx txtEnemyName;
+    [SerializeField] TextEx winInfo;
+    [SerializeField] TextEx quickWinInfo;
+    [SerializeField] TextEx txtFuncName;
+    [SerializeField] ScrollerController scroller;
+    [SerializeField] ButtonEx detailBtn;
+    JsonData jsonData;
+    string battleName = BattleConst.QYBattleField;
+
+    protected override void InitComponent()
+    {
+        detailBtn.SetListener(() =>
+        {
+            BattleSettlementManager.Instance.OpenBattleDetailWin(battleName);
+        });
+    }
+
+    protected override void OnPreOpen()
+    {
+        scroller.OnRefreshCell += OnRefreshCell;
+        jsonData = BattleSettlementManager.Instance.GetBattleSettlement(battleName);
+        if (jsonData == null && QunyingManager.Instance.quickCnt == 0)
+        {
+            DelayCloseWindow().Forget();
+            return;
+        }
+        Display();
+        CreateScroller();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        BattleSettlementManager.Instance.WinShowOver(battleName);
+        QunyingManager.Instance.quickCnt = 0;
+        QunyingManager.Instance.itemInfos.Clear();
+    }
+    // B4 20 鍥炲悎鍒舵垬鏂楃姸鎬� #tagMCTurnFightState  閫氱敤鐨勭粨绠楃姸鎬� State 4-缁撶畻濂栧姳
+    // Msg 涓澶栦俊鎭�
+    // "tagPlayerID":瀵规垬鐨勭洰鏍嘔D,
+    // "atkAddScore":鍙戣捣鏂瑰鍔犵殑绉垎锛屽彲鑳戒负0,
+    // "defDecScore":琚嚮鏂瑰噺灏戠殑绉垎锛屽彲鑳戒负0,
+    // itemInfo:濂栧姳鐗╁搧鍒楄〃锛屽彲鑳戒负绌�
+    void Display()
+    {
+
+        int quickCnt = QunyingManager.Instance.quickCnt;
+        uint tagPlayerID = quickCnt == 0 ? (uint)jsonData["tagPlayerID"] : (uint)QunyingManager.Instance.tagPlayerID;
+        if (!QunyingManager.Instance.TryGetPlayerInfo(tagPlayerID, out QunyingMatchInfo info))
+            return;
+        uint enemyFace = info.Face;
+        uint enemyFacePic = info.FacePic;
+
+        myAvatarCell.InitUI(AvatarHelper.GetAvatarModel((int)PlayerDatas.Instance.baseData.PlayerID,
+                                                PlayerDatas.Instance.baseData.face,
+                                                PlayerDatas.Instance.baseData.facePic));
+        enemyAvatarCell.InitUI(AvatarHelper.GetAvatarModel((int)tagPlayerID, (int)enemyFace, (int)enemyFacePic));
+        enemyAvatarCell.SetListener(() =>
+        {
+            AvatarHelper.TryViewOtherPlayerInfo((int)tagPlayerID, viewPlayerLineupType: (int)BattlePreSetType.Qunying);
+        });
+
+        txtMyName.text = PlayerDatas.Instance.baseData.PlayerName;
+        txtEnemyName.text = UIHelper.ServerStringTrim(info.PlayerName);
+        if (quickCnt == 0)
+        {
+            winInfo.SetActive(true);
+            quickWinInfo.SetActive(false);
+            winInfo.text = QunyingManager.Instance.tagRank.ToString();
+        }
+        else
+        {
+            winInfo.SetActive(false);
+            quickWinInfo.SetActive(true);
+            quickWinInfo.text = Language.Get("Qunying16", quickCnt);
+        }
+
+        int funcId = (int)FuncOpenEnum.Qunying;
+        txtFuncName.text = FuncOpenLVConfig.HasKey(funcId) ? FuncOpenLVConfig.Get(funcId).Name : string.Empty;
+    }
+
+    List<Item> showItems = new List<Item>();
+    void CreateScroller()
+    {
+
+        showItems.Clear();
+        scroller.Refresh();
+
+        if (QunyingManager.Instance.quickCnt == 0)
+        {
+            if (!jsonData.ContainsKey("itemInfo"))
+            {
+                return;
+            }
+
+            var resultStr = jsonData["itemInfo"];
+            for (int i = 0; i < resultStr.Count; i++)
+            {
+                showItems.Add(new Item((int)resultStr[i]["ItemID"], (long)resultStr[i]["Count"]));
+            }
+        }
+        else
+        {
+            for (int i = 0; i < QunyingManager.Instance.itemInfos.Count; i++)
+            {
+                showItems.Add(QunyingManager.Instance.itemInfos[i]);
+            }
+        }
+
+        showItems.Sort(SortItem);
+        for (int i = 0; i < showItems.Count; i++)
+        {
+            scroller.AddCell(ScrollerDataType.Header, i);
+        }
+        scroller.Restart();
+    }
+
+    int SortItem(Item itemA, Item itemB)
+    {
+        var itemConfigA = ItemConfig.Get(itemA.id);
+        var itemConfigB = ItemConfig.Get(itemB.id);
+        return itemConfigB.ItemColor - itemConfigA.ItemColor;
+    }
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as SettlementAwardCell;
+        var item = showItems[cell.index];
+        _cell?.Display(item.id, item.countEx);
+    }
+}
\ No newline at end of file
diff --git a/Main/System/Qunying/QYBattleVictoryWin.cs.meta b/Main/System/Qunying/QYBattleVictoryWin.cs.meta
new file mode 100644
index 0000000..b64bbb3
--- /dev/null
+++ b/Main/System/Qunying/QYBattleVictoryWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: cf3dc1591a467cf4a90a3fe1b5a42cc4
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Qunying/QYBattleWin.cs b/Main/System/Qunying/QYBattleWin.cs
new file mode 100644
index 0000000..5c2edec
--- /dev/null
+++ b/Main/System/Qunying/QYBattleWin.cs
@@ -0,0 +1,306 @@
+锘縰sing System.Collections.Generic;
+using LitJson;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class QYBattleWin : BaseBattleWin
+{
+    [SerializeField] Transform transButtons;
+    [SerializeField] HeroCountryComponent myCountry;
+    [SerializeField] TextEx txtMyLV;
+    [SerializeField] TextEx txtMyName;
+    [SerializeField] TextEx txtMyHp;
+    [SerializeField] ImageEx imgMyHp;
+    [SerializeField] TextEx txtMyFightPonit;
+    [SerializeField] AvatarCell myAvatarCell;
+    [SerializeField] List<ArenaHeroHead> myHeroHeads;
+
+    [SerializeField] HeroCountryComponent enemyCountry;
+    [SerializeField] TextEx txtEnemyLV;
+    [SerializeField] TextEx txtEnemyName;
+    [SerializeField] TextEx txtEnemyHp;
+    [SerializeField] ImageEx imgEnemyHp;
+    [SerializeField] TextEx txtEnemyFightPonit;
+    [SerializeField] AvatarCell enemyAvatarCell;
+    [SerializeField] List<ArenaHeroHead> enemyHeroHeads;
+
+    [SerializeField] Text funcName;
+
+    protected override void RegisterBattleEvents()
+    {
+        base.RegisterBattleEvents();
+        EventBroadcast.Instance.AddListener<string, JsonData>(EventName.BATTLE_END, OnBattleEnd);
+    }
+
+    protected override void UnregisterBattleEvents()
+    {
+        base.UnregisterBattleEvents();
+        EventBroadcast.Instance.RemoveListener<string, JsonData>(EventName.BATTLE_END, OnBattleEnd);
+    }
+
+    protected virtual void OnBattleEnd(string guid, JsonData endData)
+    {
+        if (battleField != null && guid == battleField.guid)
+        {
+            DisplayHpInfo();
+        }
+    }
+
+    protected override void OnPreOpen()
+    {
+        base.OnPreOpen();
+        MainWin.TabChangeEvent += OnTabChangeEvent;
+        UIManager.Instance.OnOpenWindow += OnOpenWindow;
+        bool isOpenBattleChangeTab = IsOpenBattleChangeTab();
+        transButtons.localPosition = new Vector3(0, isOpenBattleChangeTab ? 130 : 0, 0);
+        if (isOpenBattleChangeTab)
+        {
+            UIManager.Instance.GetUI<MainWin>()?.CloseSubUI();
+        }
+        else
+        {
+            UIManager.Instance.CloseWindow<MainWin>();
+        }
+        isClickSkip = false;
+
+        int funcId = (int)FuncOpenEnum.Qunying;
+        funcName.text = FuncOpenLVConfig.HasKey(funcId) ? FuncOpenLVConfig.Get(funcId).Name : string.Empty;
+    }
+
+    protected override void OnPreClose()
+    {
+        base.OnPreClose();
+        MainWin.TabChangeEvent -= OnTabChangeEvent;
+        UIManager.Instance.OnOpenWindow -= OnOpenWindow;
+        bool isOpenBattleChangeTab = IsOpenBattleChangeTab();
+        if (isOpenBattleChangeTab)
+        {
+            UIManager.Instance.GetUI<MainWin>()?.RestoreSubUI();
+        }
+        else
+        {
+            UIManager.Instance.OpenWindow<MainWin>();
+        }
+
+        if (isClickSkip)
+        {
+            isClickSkip = false;
+            TryPass();
+        }
+    }
+
+    void OnOpenWindow(UIBase win)
+    {
+        if (win is QYBattleVictoryWin || win is QYBattleFailWin)
+        {
+            isClickSkip = false;
+        }
+    }
+    bool isClickSkip = false;
+    protected override void OnClickPass()
+    {
+        if (!IsPass())
+            return;
+        isClickSkip = true;
+        clickTime = Time.time;  // 璁板綍鐐瑰嚮鏃堕棿
+        battleField.ForceFinish();
+    }
+
+    float stayTime = 2f;
+    float clickTime = 0f;
+    void LateUpdate()
+    {
+        if (isClickSkip && Time.time - clickTime >= stayTime)
+        {
+            isClickSkip = false;
+            TryPass();
+        }
+    }
+
+    private void TryPass()
+    {
+        if (UIManager.Instance.IsOpened<QYBattleVictoryWin>() ||
+            UIManager.Instance.IsOpened<QYBattleFailWin>())
+            return;
+        CloseWindow();
+        Debug.LogError($"OnBattleEnd 寮傚父鍏抽棴");
+        BattleSettlementManager.Instance.WinShowOver(BattleConst.QYBattleField);
+    }
+    private void OnTabChangeEvent()
+    {
+        CloseWindow();
+    }
+
+    protected override void OnDamageTaken(BattleDmgInfo damageInfo)
+    {
+        base.OnDamageTaken(damageInfo);
+        if (battleField == null)
+            return;
+        if (damageInfo.battleFieldGuid == battleField.guid)
+        {
+            DisplayHpInfo();
+        }
+    }
+
+    protected override void OnCreateBattleField(string guid, BattleField field)
+    {
+        if (field is QYBattleField)
+        {
+            SetBattleField(field);
+        }
+    }
+
+    protected override void RefreshSpecific()
+    {
+        DisplayHpInfo();
+        DisplayPlayerInfo();
+    }
+
+    private void DisplayHpInfo()
+    {
+        if (battleField == null)
+            return;
+
+        // 鑾峰彇鎴戞柟锛堢孩鏂癸級闃熶紞鏁版嵁
+        List<BattleObject> myTeam = battleField.battleObjMgr.GetBattleObjList(BattleCamp.Red);
+        // 鑾峰彇鏁屾柟锛堣摑鏂癸級闃熶紞鏁版嵁
+        List<BattleObject> enemyTeam = battleField.battleObjMgr.GetBattleObjList(BattleCamp.Blue);
+
+        ulong myMaxHp = GetMaxHP(myTeam);
+        ulong enemyMaxHp = GetMaxHP(enemyTeam);
+
+        ulong myNowHp = GetNowHP(myTeam);
+        ulong enemyNowHp = GetNowHP(enemyTeam);
+        txtMyHp.text = Language.Get("BoneField09", UIHelper.ReplaceLargeNum(myNowHp), UIHelper.ReplaceLargeNum(myMaxHp));
+        txtEnemyHp.text = Language.Get("BoneField09", UIHelper.ReplaceLargeNum(enemyNowHp), UIHelper.ReplaceLargeNum(enemyMaxHp));
+        imgMyHp.fillAmount = Mathf.Clamp01((myMaxHp > 0) ? (float)myNowHp / myMaxHp : 0f);
+        imgEnemyHp.fillAmount = Mathf.Clamp01((enemyMaxHp > 0) ? (float)enemyNowHp / enemyMaxHp : 0f);
+
+    }
+
+    private long GetFightPonit(List<BattleObject> Team)
+    {
+        if (Team.IsNullOrEmpty())
+        {
+            return 0;
+        }
+        long res = 0;
+        foreach (var obj in Team)
+        {
+            if (obj is not HeroBattleObject)
+                continue;
+            res += obj.GetFightPower();
+        }
+        return res;
+    }
+
+    private void DisplayPlayerInfo()
+    {
+        if (battleField == null)
+            return;
+        if (!QunyingManager.Instance.TryGetPlayerInfo(QunyingManager.Instance.atkPlayerId, out QunyingMatchInfo info))
+            return;
+        // 鑾峰彇鎴戞柟锛堢孩鏂癸級闃熶紞鏁版嵁
+        List<BattleObject> myTeam = battleField.battleObjMgr.GetBattleObjList(BattleCamp.Red);
+        // 鑾峰彇鏁屾柟锛堣摑鏂癸級闃熶紞鏁版嵁
+        List<BattleObject> enemyTeam = battleField.battleObjMgr.GetBattleObjList(BattleCamp.Blue);
+
+
+        txtEnemyLV.text = Language.Get("Arena22", info.LV);
+        txtEnemyName.text = UIHelper.ServerStringTrim(info.PlayerName);
+        txtEnemyFightPonit.text = UIHelper.ReplaceLargeArtNum(GetFightPonit(enemyTeam));
+        enemyAvatarCell.InitUI(AvatarHelper.GetAvatarModel((int)info.PlayerID, (int)info.Face, (int)info.FacePic));
+        enemyAvatarCell.SetListener(() =>
+        {
+            AvatarHelper.TryViewOtherPlayerInfo((int)info.PlayerID, viewPlayerLineupType: (int)BattlePreSetType.Qunying);
+        });
+        var team = GetTeamHeroList(enemyTeam);
+        enemyCountry.RefreshOnTeamCountry(team, true);
+
+        txtMyLV.text = Language.Get("Arena22", PlayerDatas.Instance.baseData.LV);
+        txtMyName.text = PlayerDatas.Instance.baseData.PlayerName;
+        long myFightPower = GetFightPonit(myTeam);
+        txtMyFightPonit.text = UIHelper.ReplaceLargeArtNum(myFightPower);
+        myAvatarCell.InitUI(AvatarHelper.GetAvatarModel((int)PlayerDatas.Instance.baseData.PlayerID, PlayerDatas.Instance.baseData.face, PlayerDatas.Instance.baseData.facePic));
+        team = GetTeamHeroList(myTeam);
+        myCountry.RefreshOnTeamCountry(team, true);
+
+        for (int i = 0; i < myHeroHeads.Count; i++)
+        {
+            if (i < myTeam.Count && myTeam[i] is HeroBattleObject heroBattleObject)
+            {
+                myHeroHeads[i].SetActive(true);
+                var teamHero = heroBattleObject.teamHero;
+                myHeroHeads[i].Display(teamHero.heroId, teamHero.SkinID, teamHero.level);
+            }
+            else
+            {
+                myHeroHeads[i].SetActive(false);
+            }
+        }
+
+        // 鏁屾柟鑻遍泟鏄剧ず锛堜粠鍙冲埌宸︼級
+        for (int i = enemyHeroHeads.Count - 1; i >= 0; i--)
+        {
+            int teamIndex = enemyHeroHeads.Count - 1 - i;  // 寤虹珛鍙嶅悜鏄犲皠
+
+            if (teamIndex < enemyTeam.Count && enemyTeam[teamIndex] is HeroBattleObject heroBattleObject)
+            {
+                enemyHeroHeads[i].SetActive(true);
+                var teamHero = heroBattleObject.teamHero;  // 浣跨敤鏄犲皠鍚庣殑绱㈠紩
+                enemyHeroHeads[i].Display(teamHero.heroId, teamHero.SkinID, teamHero.level);
+            }
+            else
+            {
+                enemyHeroHeads[i].SetActive(false);
+            }
+        }
+
+    }
+    ulong GetMaxHP(List<BattleObject> battleObjects)
+    {
+        ulong sun = 0;
+        if (!battleObjects.IsNullOrEmpty())
+        {
+            for (int i = 0; i < battleObjects.Count; i++)
+            {
+                sun += (ulong)battleObjects[i].GetMaxHp();
+            }
+        }
+        return sun;
+    }
+
+    ulong GetNowHP(List<BattleObject> battleObjects)
+    {
+        ulong sun = 0;
+        if (!battleObjects.IsNullOrEmpty())
+        {
+            for (int i = 0; i < battleObjects.Count; i++)
+            {
+                sun += (ulong)battleObjects[i].GetCurHp();
+            }
+        }
+        return sun;
+    }
+
+    List<TeamHero> GetTeamHeroList(List<BattleObject> teams)
+    {
+        List<TeamHero> teamHeroes = new List<TeamHero>();
+        if (teams.IsNullOrEmpty())
+            return teamHeroes;
+        foreach (var item in teams)
+        {
+            if (item is HeroBattleObject heroBattleObject)
+            {
+                teamHeroes.Add(heroBattleObject.teamHero);
+            }
+        }
+        return teamHeroes;
+
+    }
+
+    bool IsOpenBattleChangeTab()
+    {
+        return FuncOpen.Instance.IsFuncOpen(ArenaManager.Instance.BattleChangeTabFuncId);
+    }
+}
\ No newline at end of file
diff --git a/Main/System/Qunying/QYBattleWin.cs.meta b/Main/System/Qunying/QYBattleWin.cs.meta
new file mode 100644
index 0000000..4e2aba1
--- /dev/null
+++ b/Main/System/Qunying/QYBattleWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2fea3a4b19e88144eb09b61bf7bc4e78
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Qunying/QYFighterCell.cs b/Main/System/Qunying/QYFighterCell.cs
new file mode 100644
index 0000000..026bec5
--- /dev/null
+++ b/Main/System/Qunying/QYFighterCell.cs
@@ -0,0 +1,194 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+
+// 缇よ嫳鎸戞垬
+public class QYFighterCell : MonoBehaviour
+{
+    [SerializeField] HorseController model;
+    [SerializeField] OfficialTitleCell officialTitleCell;
+    [SerializeField] Text fightPowerText;
+    [SerializeField] Text nameText;
+    [SerializeField] Text serverText;
+    [SerializeField] Button queryPlayerBtn; //鍚庣画娣诲姞鐐瑰嚮鏌ョ湅鐜╁璇︽儏
+    [SerializeField] Text rankText;
+    [SerializeField] Transform myMark;
+    [SerializeField] Button challengeBtn;
+    [SerializeField] Transform quickObj;
+    [SerializeField] Button quickChallengeBtn;
+    [SerializeField] Button quickChallengeMoreBtn;
+    [SerializeField] Text quickChallengeMoreText;
+
+
+
+    QunyingMatchInfo matchInfo;
+    void Start()
+    {
+        challengeBtn.SetListener(() =>
+        {
+            if (matchInfo == null)
+                return;
+            if (!UIHelper.CheckMoneyCount(QunyingManager.challengeMoneyType, 1, 1))
+            {
+                StoreModel.Instance.ShowBuyItem(QunyingManager.challengeShopID, -1);
+                return;
+            }
+            QunyingManager.Instance.atkPlayerId = matchInfo.PlayerID;
+            QunyingManager.Instance.tagRank = matchInfo.Rank;
+            BattleManager.Instance.SendTurnFight(QunyingManager.DataMapID, 0, 1, matchInfo.PlayerID, new uint[] { matchInfo.Rank, 0 });
+        });
+
+        queryPlayerBtn.AddListener(() =>
+        {
+            if (GeneralDefine.IsRobot((int)matchInfo.PlayerID)) return;
+            AvatarHelper.TryViewOtherPlayerInfo((int)matchInfo.PlayerID, viewPlayerLineupType: (int)BattlePreSetType.Qunying);
+        });
+
+        quickChallengeBtn.AddListener(() =>
+        {
+            if (matchInfo == null)
+                return;
+            if (!UIHelper.CheckMoneyCount(QunyingManager.challengeMoneyType, 1, 1))
+            {
+                StoreModel.Instance.ShowBuyItem(QunyingManager.challengeShopID, -1);
+                return;
+            }
+            QunyingManager.Instance.atkPlayerId = matchInfo.PlayerID;
+            BattleManager.Instance.SendTurnFight(QunyingManager.DataMapID, 0, 1, matchInfo.PlayerID, new uint[] { matchInfo.Rank, 1 }, false);
+        });
+
+        quickChallengeMoreBtn.AddListener(() =>
+        {
+            if (matchInfo == null)
+                return;
+
+            //鏈�浣庢樉绀轰袱娆★紝浣嗗彲浠ユ渶浣庢寫鎴�1娆�
+            var cnt = Math.Max(1, Math.Min(5, UIHelper.GetMoneyCnt(QunyingManager.challengeMoneyType)));
+            if (!UIHelper.CheckMoneyCount(QunyingManager.challengeMoneyType, cnt, 1))
+            {
+                StoreModel.Instance.ShowBuyItem(QunyingManager.challengeShopID, -1);
+                return;
+            }
+            QunyingManager.Instance.atkPlayerId = matchInfo.PlayerID;
+            BattleManager.Instance.SendTurnFight(QunyingManager.DataMapID, 0, 1, matchInfo.PlayerID, new uint[] { matchInfo.Rank, (uint)cnt }, false);
+        });
+    }
+
+    public void Display(int index)
+    {
+        var myMatch = QunyingManager.Instance.GetMyMatchInfo(out int myIndex);
+        var list = QunyingManager.Instance.matchInfoList;
+        if (list.IsNullOrEmpty() || index < 0 || index >= list.Count)
+        {
+            if (myMatch != null)
+            {
+                this.SetActive(false);
+                return;
+            }
+            if (myMatch == null && index != 4)
+            {
+                this.SetActive(false);
+                return;
+            }
+            //鑷繁鏈笂鐗堢殑 鍦ㄧ5浣嶈ˉ
+
+        }
+
+        this.SetActive(true);
+
+        if (myMatch == null && index == 4)
+        {
+            //濉厖鑷繁鐨�
+            matchInfo = new QunyingMatchInfo
+            {
+                Rank = 0,
+                PlayerID = PlayerDatas.Instance.baseData.PlayerID,
+                PlayerName = PlayerDatas.Instance.baseData.PlayerName,
+                LV = PlayerDatas.Instance.baseData.LV,
+                RealmLV = PlayerDatas.Instance.baseData.realmLevel,
+                FightPower = (ulong)PlayerDatas.Instance.baseData.FightPower,
+                TitleID = (uint)PlayerDatas.Instance.baseData.TitleID,
+                ModelMark = (uint)PlayerDatas.Instance.baseData.modelMark,
+                EquipShowSwitch = PlayerDatas.Instance.baseData.equipShowSwitch,
+                ServerID = (uint)ServerListCenter.Instance.currentServer.region_flag,
+            };
+        }
+        else
+        {
+            matchInfo = list[index];
+        }
+
+        
+
+        if (GeneralDefine.IsRobot((int)matchInfo.PlayerID))
+        {
+            serverText.text = Language.Get("Qunying15");
+        }
+        else
+        {
+            serverText.text = ServerListCenter.Instance.GetServerName((int)matchInfo.ServerID);
+        }
+
+
+        
+        int heroSkinID = 0;
+        if (matchInfo.ModelMark == 0)
+        {
+            heroSkinID = QunyingManager.Instance.robotModelIDs[matchInfo.PlayerID % QunyingManager.Instance.robotModelIDs.Length];
+        }
+        else
+        {
+            heroSkinID = PhantasmPavilionManager.Instance.GetModelSkinID((int)matchInfo.ModelMark);
+        }
+
+        if (matchInfo.PlayerID == PlayerDatas.Instance.baseData.PlayerID)
+        {
+            fightPowerText.text = UIHelper.ReplaceLargeArtNum(PlayerDatas.Instance.baseData.FightPower);
+            nameText.text = UIHelper.ServerStringTrim(PlayerDatas.Instance.baseData.PlayerName);
+
+            var skinConfig = HorseSkinConfig.Get(HorseManager.Instance.GetUsingHorseSkinID());
+            model.Create(skinConfig.SkinID, PhantasmPavilionManager.Instance.GetMyModelSkinID(), 0.9f);
+            officialTitleCell.InitUI(PlayerDatas.Instance.baseData.realmLevel, PlayerDatas.Instance.baseData.TitleID);
+        }
+        else
+        {
+            fightPowerText.text = UIHelper.ReplaceLargeArtNum(matchInfo.FightPower);
+            nameText.text = UIHelper.ServerStringTrim(matchInfo.PlayerName);
+            model.Create((int)matchInfo.EquipShowSwitch % 1000, heroSkinID, 0.9f);
+            officialTitleCell.InitUI(matchInfo.RealmLV, (int)matchInfo.TitleID);
+        }
+
+        
+        rankText.text = matchInfo.Rank > 0 ? $"{matchInfo.Rank}" : Language.Get("L1125");
+        myMark.SetActive(matchInfo.PlayerID == PlayerDatas.Instance.baseData.PlayerID);
+
+        var ticketCnt = Math.Max(2, Math.Min(5, UIHelper.GetMoneyCnt(QunyingManager.challengeMoneyType)));
+        if (myMatch != null && myMatch.Rank < matchInfo.Rank)
+        {
+            //浣庝簬鑷繁鐨�
+            quickObj.SetActive(true);
+            challengeBtn.SetActive(false);
+            quickChallengeMoreText.text = Language.Get("Qunying9", ticketCnt);
+        }
+        else if ((myMatch == null && index == 4) || (myMatch != null && myMatch.Rank == matchInfo.Rank))
+        {
+            //鏄嚜宸憋紝鍒嗘槸鍚︿笂姒滄儏鍐�
+            quickObj.SetActive(false);
+            challengeBtn.SetActive(false);
+        }
+        else
+        {
+            quickObj.SetActive(false);
+            challengeBtn.SetActive(true);
+        }
+    }
+
+
+
+}
+
+
+
+
diff --git a/Main/System/Qunying/QYFighterCell.cs.meta b/Main/System/Qunying/QYFighterCell.cs.meta
new file mode 100644
index 0000000..45946ea
--- /dev/null
+++ b/Main/System/Qunying/QYFighterCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8a72c6bf947ee7e4eab339e27e21d7c7
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Qunying/QYNoteCell.cs b/Main/System/Qunying/QYNoteCell.cs
new file mode 100644
index 0000000..3e547b3
--- /dev/null
+++ b/Main/System/Qunying/QYNoteCell.cs
@@ -0,0 +1,74 @@
+using System.Collections.Generic;
+using UnityEngine;
+using System;
+using UnityEngine.UI;
+
+public class QYNoteCell : CellView
+{
+    [SerializeField] ImageEx atkTypeImg;
+    [SerializeField] Text atkTypeTxt;
+    [SerializeField] AvatarCell avatarCell;
+    [SerializeField] TextEx lvTxt;
+    [SerializeField] TextEx nameTxt;
+    [SerializeField] TextEx rankTxt;
+    [SerializeField] TextEx serverTxt;
+    [SerializeField] Image stateImg;    //鑳滆礋
+
+    [SerializeField] AvatarCell tagAvatarCell;
+    [SerializeField] TextEx tagLVTxt;
+    [SerializeField] TextEx tagNameTxt;
+    [SerializeField] TextEx tagRankTxt;
+    [SerializeField] TextEx tagServerTxt;
+    [SerializeField] Image tagStateImg;
+
+    // [SerializeField] ButtonEx replayBtn; //闇�瑕丟UID
+    QunyingGameRec arenaGameRec;
+
+
+    public void Display(int index)
+    {
+        uint playerID = PlayerDatas.Instance.baseData.PlayerID;
+        QunyingManager.Instance.TryGetSortedGameRecList(playerID, out List<QunyingGameRec> sortedList);
+        if (sortedList.IsNullOrEmpty() || index < 0 || index >= sortedList.Count)
+            return;
+        arenaGameRec = sortedList[index];
+
+        atkTypeImg.SetSprite("QYAtkType" + arenaGameRec.Value2);
+        atkTypeTxt.text = arenaGameRec.Value2 == 1 ? Language.Get("mainui2") : Language.Get("herocard28");
+
+        //鍙栫帺瀹惰嚜宸辩殑鏁版嵁
+        avatarCell.InitUI(AvatarHelper.GetAvatarModel((int)PlayerDatas.Instance.baseData.PlayerID,
+                                        PlayerDatas.Instance.baseData.face,
+                                        PlayerDatas.Instance.baseData.facePic));
+        lvTxt.text = PlayerDatas.Instance.baseData.LV.ToString();
+        nameTxt.text = PlayerDatas.Instance.baseData.PlayerName;
+        serverTxt.text = ServerListCenter.Instance.GetServerName(UIHelper.GetServerIDByAccount(PlayerDatas.Instance.baseData.AccID));
+        stateImg.SetSprite("QYResult" + (arenaGameRec.Value4 == 1 ? 1 : 2));
+        rankTxt.text = arenaGameRec.CurRank == 0 ? Language.Get("L1045") : Language.Get("Qunying20") + arenaGameRec.CurRank;
+
+        tagAvatarCell.InitUI(AvatarHelper.GetAvatarModel((int)arenaGameRec.Value3, (int)arenaGameRec.Value5, (int)arenaGameRec.Value6));
+
+        tagAvatarCell.SetListener(() =>
+        {
+            if (GeneralDefine.IsRobot((int)arenaGameRec.Value3)) return;
+            AvatarHelper.TryViewOtherPlayerInfo((int)arenaGameRec.Value3, viewPlayerLineupType: (int)BattlePreSetType.Arena);
+        });
+        tagLVTxt.text = arenaGameRec.Value8.ToString();
+        tagNameTxt.text = arenaGameRec.Name;
+
+        if (GeneralDefine.IsRobot((int)arenaGameRec.Value3))
+        {
+            tagServerTxt.text = Language.Get("Qunying15");
+        }
+        else
+        {
+            tagServerTxt.text = ServerListCenter.Instance.GetServerName((int)arenaGameRec.Value1);
+        }
+        tagRankTxt.text = Language.Get("Qunying20") + arenaGameRec.TagRank;
+        tagStateImg.SetSprite("QYResult" + (arenaGameRec.Value4 == 1 ? 2 : 1));
+
+
+    }
+
+
+}
diff --git a/Main/System/Qunying/QYNoteCell.cs.meta b/Main/System/Qunying/QYNoteCell.cs.meta
new file mode 100644
index 0000000..cdcd084
--- /dev/null
+++ b/Main/System/Qunying/QYNoteCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fd46d4292beb1db4589734bcafc14387
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Qunying/QYNoteWin.cs b/Main/System/Qunying/QYNoteWin.cs
new file mode 100644
index 0000000..8f09d09
--- /dev/null
+++ b/Main/System/Qunying/QYNoteWin.cs
@@ -0,0 +1,63 @@
+using System.Collections.Generic;
+using UnityEngine;
+
+public class QYNoteWin : UIBase
+{
+    [SerializeField] ScrollerController scrollerController;
+
+    protected override void OnPreOpen()
+    {
+        SendRec();
+        scrollerController.OnRefreshCell += OnRefreshCell;
+        QunyingManager.Instance.OnUpdateGameRecInfo += OnUpdateGameRecInfo;
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        scrollerController.OnRefreshCell -= OnRefreshCell;
+        QunyingManager.Instance.OnUpdateGameRecInfo -= OnUpdateGameRecInfo;
+    }
+
+
+
+    private void OnUpdateGameRecInfo()
+    {
+        Display();
+    }
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell.GetComponent<QYNoteCell>();
+        _cell?.Display(cell.index);
+    }
+
+    private void CreateScroller()
+    {
+        scrollerController.Refresh();
+        uint playerID = PlayerDatas.Instance.baseData.PlayerID;
+        QunyingManager.Instance.TryGetSortedGameRecList(playerID, out List<QunyingGameRec> sortedList);
+        if (!sortedList.IsNullOrEmpty())
+        {
+            for (int i = 0; i < sortedList.Count; i++)
+            {
+                scrollerController.AddCell(ScrollerDataType.Header, i);
+            }
+        }
+        scrollerController.Restart();
+    }
+
+    void Display()
+    {
+        CreateScroller();
+    }
+
+
+    void SendRec()
+    {
+        CA008_tagCSViewGameRec pack = new CA008_tagCSViewGameRec();
+        pack.RecType = 312;
+        pack.RecID = PlayerDatas.Instance.baseData.PlayerID;
+        GameNetSystem.Instance.SendInfo(pack);
+    }
+}
diff --git a/Main/System/Qunying/QYNoteWin.cs.meta b/Main/System/Qunying/QYNoteWin.cs.meta
new file mode 100644
index 0000000..5582605
--- /dev/null
+++ b/Main/System/Qunying/QYNoteWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b8031772edc07284dac0925efb26aaf7
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Qunying/QYPlayerTop3Cell.cs b/Main/System/Qunying/QYPlayerTop3Cell.cs
new file mode 100644
index 0000000..5705ad1
--- /dev/null
+++ b/Main/System/Qunying/QYPlayerTop3Cell.cs
@@ -0,0 +1,52 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+
+// 缇よ嫳鎺掕姒� 鐜╁鎺掕姒� 鍓嶄笁鍚�
+public class QYPlayerTop3Cell : MonoBehaviour
+{
+    [SerializeField] HorseController model;
+    [SerializeField] OfficialTitleCell officialTitleCell;
+    [SerializeField] Text fightPowerText;
+    [SerializeField] Text nameText;
+    [SerializeField] Text serverText;
+    [SerializeField] Button queryPlayerBtn; //鍚庣画娣诲姞鐐瑰嚮鏌ョ湅鐜╁璇︽儏
+
+    public void Display(int rankType, int rank)
+    {
+        var rankData = RankModel.Instance.GetRankDataByRank(rankType, rank);
+        if (rankData == null)
+        {
+            serverText.text = "";
+            nameText.text = Language.Get("L1124");
+            officialTitleCell.SetActive(false);
+            fightPowerText.text = "";
+            return;
+        }
+        officialTitleCell.SetActive(true);
+        if (GeneralDefine.IsRobot((int)rankData.id))
+        {
+            serverText.text = Language.Get("Qunying15");
+        }
+        else
+        {
+            serverText.text = ServerListCenter.Instance.GetServerName(UIHelper.GetServerIDByAccount(rankData.name2));
+        }
+            
+        nameText.text = rankData.name1;
+        officialTitleCell.InitUI((int)rankData.value1, (int)rankData.value2);
+        model.Create(HorseManager.Instance.GetOtherPlayerHorseSkinID((int)rankData.value6), (int)rankData.value5, 0.9f);
+        queryPlayerBtn.SetListener(() =>
+        {
+            if (GeneralDefine.IsRobot((int)rankData.id)) return;
+            AvatarHelper.TryViewOtherPlayerInfo((int)rankData.id, viewPlayerLineupType: (int)BattlePreSetType.Qunying);
+        });
+        fightPowerText.text = UIHelper.ReplaceLargeArtNum(rankData.fightPower);
+    }
+
+
+}
+
+
+
+
diff --git a/Main/System/Qunying/QYPlayerTop3Cell.cs.meta b/Main/System/Qunying/QYPlayerTop3Cell.cs.meta
new file mode 100644
index 0000000..2cab6b0
--- /dev/null
+++ b/Main/System/Qunying/QYPlayerTop3Cell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: dc373890f5310614f894283a67b58cc2
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Qunying/QYRankAwardCell.cs b/Main/System/Qunying/QYRankAwardCell.cs
new file mode 100644
index 0000000..717f2fe
--- /dev/null
+++ b/Main/System/Qunying/QYRankAwardCell.cs
@@ -0,0 +1,54 @@
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+public class QYRankAwardCell : CellView
+{
+    [SerializeField] ImageEx imgRank;
+    [SerializeField] TextEx txtRank;
+    [SerializeField] ItemCell[] itemCells;
+    public void Display(int index, int order)
+    {
+        Dictionary<int, int[][]> rewardDict = QunyingManager.Instance.GetRankAwardDict(order);
+        if (rewardDict.IsNullOrEmpty())
+            return;
+        var list = rewardDict.Keys.ToList();
+        list.Sort();
+
+
+        int rank = list[index];
+        
+        if (rank <= 3)
+        {
+            imgRank.SetActive(true);
+            txtRank.SetActive(false);
+            imgRank.SetSprite($"Rank{rank}");
+            txtRank.text = rank.ToString();
+        }
+        else
+        {
+            imgRank.SetActive(false);
+            txtRank.SetActive(true);
+            int lastIndex = index - 1;
+            txtRank.text = lastIndex > 0 && lastIndex < list.Count ? Language.Get("Arena15", list[lastIndex] + 1, rank) : string.Empty;
+        }
+
+        int key = list[index];
+        int[][] rewardArr = rewardDict[key];
+        for (int i = 0; i < itemCells.Length; i++)
+        {
+            var itemCell = itemCells[i];
+            if (!rewardArr.IsNullOrEmpty() && i < rewardArr.Length)
+            {
+                int itemCellIndex = i;
+                itemCell.SetActive(true);
+                itemCell.Init(new ItemCellModel(rewardArr[i][0], true, rewardArr[i][1]));
+                itemCell.button.SetListener(() => ItemTipUtility.Show(rewardArr[itemCellIndex][0]));
+            }
+            else
+            {
+                itemCell.SetActive(false);
+            }
+        }
+    }
+}
diff --git a/Main/System/Qunying/QYRankAwardCell.cs.meta b/Main/System/Qunying/QYRankAwardCell.cs.meta
new file mode 100644
index 0000000..1f4a828
--- /dev/null
+++ b/Main/System/Qunying/QYRankAwardCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2b2a9b63aec1f704190eeccbb5a7228b
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Qunying/QYRankAwardWin.cs b/Main/System/Qunying/QYRankAwardWin.cs
new file mode 100644
index 0000000..f6b5787
--- /dev/null
+++ b/Main/System/Qunying/QYRankAwardWin.cs
@@ -0,0 +1,140 @@
+using System.Linq;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class QYRankAwardWin : UIBase
+{
+    [SerializeField] Text titleText;
+    [SerializeField] ScrollerController scroller;
+    [SerializeField] Text myRankText;
+    [SerializeField] ItemCell[] itemCells;
+    [SerializeField] Transform unRankText;
+    [SerializeField] Text noAwardText;
+    [SerializeField] Text timeText;
+    [SerializeField] GroupButtonEx weekBtn;
+    [SerializeField] GroupButtonEx dayBtn;
+
+    protected override void InitComponent()
+    {
+        weekBtn.AddListener(()=>
+        {
+            functionOrder = 0;
+            Display();
+        });
+        dayBtn.AddListener(()=>
+        {
+            functionOrder = 1;
+            Display();
+        });
+    }
+
+    protected override void OnPreOpen()
+    {
+        if (functionOrder == 0)
+        {
+            weekBtn.SelectBtn();
+        }
+        else
+        {
+            dayBtn.SelectBtn();
+        }
+
+        scroller.OnRefreshCell += OnRefreshCell;
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        Display();
+
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+    }
+
+
+    private void OnRefreshCell(ScrollerDataType type, CellView cellView)
+    {
+        var cell = cellView as QYRankAwardCell;
+        cell.Display(cell.index, functionOrder);
+    }
+    private void OnSecondEvent()
+    {
+        if (functionOrder == 0)
+        {
+            timeText.text = Language.Get("Arena14", QunyingManager.Instance.GetEndSecondStr());
+
+        }
+        else
+        {
+            timeText.text = Language.Get("Arena14", TimeUtility.SecondsToDHMS((int)(TimeUtility.GetCommTodayEndTime(0) -
+                            TimeUtility.GetCommServerNow()).TotalSeconds));
+        }
+
+    }
+
+    void Display()
+    {
+        scroller.Refresh();
+        if (functionOrder == 1)
+        {
+            titleText.text = Language.Get("Qunying18");
+        }
+        else
+        {
+            titleText.text = Language.Get("Qunying19");
+        }
+        var keys = QunyingManager.Instance.GetRankAwardDict(functionOrder).Keys.ToList();
+        keys.Sort();
+        for (int i = 0; i < keys.Count; i++)
+        {
+            scroller.AddCell(ScrollerDataType.Header, i);
+        }
+        scroller.Restart();
+
+        OnSecondEvent();
+
+        var myMatch = QunyingManager.Instance.GetMyMatchInfo(out var index);
+        if (myMatch != null)
+        {
+            myRankText.SetActive(true);
+            unRankText.SetActive(false);
+            myRankText.text = myMatch.Rank.ToString();
+            var awards = QunyingManager.Instance.GetMyRankAwards(functionOrder, myMatch.Rank);
+            if (awards.IsNullOrEmpty())
+            {
+                noAwardText.SetActive(true);
+                for (int i = 0; i < itemCells.Length; i++)
+                {
+                    itemCells[i].SetActive(false);
+                }
+            }
+            else
+            {
+                noAwardText.SetActive(false);
+                for (int i = 0; i < itemCells.Length; i++)
+                {
+                    if (i < awards.Length)
+                    {
+                        itemCells[i].SetActive(true);
+                        int itemID = awards[i][0];
+                        itemCells[i].Init(new ItemCellModel(itemID, false, awards[i][1]));
+                        itemCells[i].button.SetListener(() => ItemTipUtility.Show(itemID));
+                    }
+                    else
+                    {
+                        itemCells[i].SetActive(false);
+                    }
+                }
+            }
+
+        }
+        else
+        {
+            myRankText.SetActive(false);
+            unRankText.SetActive(true);
+            noAwardText.SetActive(true);
+        }
+
+
+    }
+}
\ No newline at end of file
diff --git a/Main/System/Qunying/QYRankAwardWin.cs.meta b/Main/System/Qunying/QYRankAwardWin.cs.meta
new file mode 100644
index 0000000..82925a6
--- /dev/null
+++ b/Main/System/Qunying/QYRankAwardWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 40adbfa987c6b18468007c00c7d14d4e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Qunying/QYStoreWin.cs b/Main/System/Qunying/QYStoreWin.cs
new file mode 100644
index 0000000..8556cdc
--- /dev/null
+++ b/Main/System/Qunying/QYStoreWin.cs
@@ -0,0 +1,73 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class QYStoreWin : UIBase
+{
+
+    [SerializeField] ScrollerController scroller;
+
+
+    protected override void OnPreOpen()
+    {
+        StoreModel.Instance.selectStoreFuncType = StoreFunc.Qunying;
+        scroller.OnRefreshCell += OnRefreshCell;
+        StoreModel.Instance.RefreshShopEvent += Display;
+        StoreModel.Instance.RefreshBuyShopLimitEvent += Display;
+        
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        StoreModel.Instance.RefreshShopEvent -= Display;
+        StoreModel.Instance.RefreshBuyShopLimitEvent -= Display;
+    }
+
+    void Display()
+    {
+        CreateScroller();
+    }
+
+
+
+    void CreateScroller()
+    {
+        if (!StoreModel.Instance.storeTypeDict.ContainsKey((int)StoreModel.Instance.selectStoreFuncType))
+        {
+            return;
+        }
+
+        scroller.Refresh();
+        int jumpIndex = -1;
+        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);
+            }
+            if (jumpIndex == -1 && list[i].shopId == StoreModel.Instance.jumpShopID)
+            {
+                jumpIndex = i / 3;
+            }
+        }
+        scroller.Restart();
+        scroller.lockType = EnhanceLockType.KeepVertical;
+        if (StoreModel.Instance.jumpShopID != 0)
+        {
+            scroller.JumpIndex(jumpIndex);
+            StoreModel.Instance.jumpShopID = 0;
+        }
+    }
+
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as StoreLineCell;
+        _cell.Display(cell.index);
+    }
+
+
+}
diff --git a/Main/System/Qunying/QYStoreWin.cs.meta b/Main/System/Qunying/QYStoreWin.cs.meta
new file mode 100644
index 0000000..a01cfe7
--- /dev/null
+++ b/Main/System/Qunying/QYStoreWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 47a5fdf362707eb469b6cab4d016a64b
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Qunying/QYWin.cs b/Main/System/Qunying/QYWin.cs
new file mode 100644
index 0000000..299524d
--- /dev/null
+++ b/Main/System/Qunying/QYWin.cs
@@ -0,0 +1,270 @@
+using System;
+using Cysharp.Threading.Tasks;
+using UnityEngine;
+using UnityEngine.UI;
+
+
+//缇よ嫳涓荤晫闈�
+//QunyingManager.Instance.openQYWinNeedRoll 榛樿寮�鍚殑鏃跺�欐粴鍔ㄥ睍绀�
+public class QYWin : UIBase
+{
+    [SerializeField] QYPlayerTop3Cell[] playerTop3Cells;
+    [SerializeField] QYFighterCell[] FighterCells;
+    [SerializeField] ScrollRect battleScrollRect;
+    [SerializeField] Button closeBtn;
+
+    [SerializeField] Text gameTimeText;
+    [SerializeField] Button buyTicketBtn;
+    [SerializeField] Text ticketCountText;
+    [SerializeField] Text ticketTimeText;
+
+    [SerializeField] Button achievementBtn;
+    [SerializeField] Text achievementTargetText;
+    [SerializeField] Text rankText;
+    [SerializeField] Button defentPosBtn;
+    [SerializeField] Button attackPosBtn;
+    [SerializeField] Button refreshBtn;
+    [SerializeField] Text refreshMoneyText;
+    [SerializeField] Image refreshMoneyImg;
+    [SerializeField] Text refreshCntText;
+
+    [SerializeField] Button storeBtn;
+    [SerializeField] Button rankBtn;
+    [SerializeField] Button awardBtn;
+    [SerializeField] Button noteBtn;
+
+    protected override void InitComponent()
+    {
+        closeBtn.AddListener(CloseWindow);
+        buyTicketBtn.AddListener(() =>
+        {
+            StoreModel.Instance.ShowBuyItem(QunyingManager.challengeShopID);
+        });
+        achievementBtn.AddListener(() =>
+        {
+            UIManager.Instance.OpenWindow<QYAchievementWin>();
+        });
+        defentPosBtn.AddListener(() =>
+        {
+            FuncPresetManager.Instance.ClickBattlePreset((int)BattlePreSetType.Qunying);
+        });
+        attackPosBtn.AddListener(() =>
+        {
+            FuncPresetManager.Instance.ClickBattlePreset((int)BattlePreSetType.Story);
+        });
+        refreshBtn.AddListener(() =>
+        {
+            RefreshFighters();
+        });
+
+        storeBtn.AddListener(() =>
+        {
+            UIManager.Instance.OpenWindow<QYStoreWin>();
+        });
+        rankBtn.AddListener(() =>
+        {
+            UIManager.Instance.OpenWindow<PlayerRankWin>(QunyingManager.rankType);
+        });
+        awardBtn.AddListener(() =>
+        {
+            UIManager.Instance.OpenWindow<QYRankAwardWin>(1);
+        });
+        noteBtn.AddListener(() =>
+        {
+            UIManager.Instance.OpenWindow<QYNoteWin>();
+        });
+    }
+
+    protected override void OnPreOpen()
+    {
+        if (!QunyingManager.Instance.openQYWinNeedRoll)
+        {
+            var myMatch = QunyingManager.Instance.GetMyMatchInfo(out int index);
+            battleScrollRect.verticalNormalizedPosition = (4 - index) * 0.15f + 0f;
+        }
+        else
+        {
+            battleScrollRect.verticalNormalizedPosition = 1f;
+        }
+        RankModel.Instance.ResetQueryParam();
+        RankModel.Instance.QueryRankByPage(QunyingManager.rankType, 0, 3);
+        QunyingManager.Instance.RequestRefreshFighters(0);
+
+        RankModel.Instance.onRankRefresh += OnRankRefresh;
+        QunyingManager.Instance.OnMatchListEvent += OnMatchListEvent;
+        PlayerDatas.Instance.playerDataRefreshEvent += OnPlayerDataRefresh;
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        QunyingManager.Instance.OnUpdateQunyingInfoEvent += OnUpdateQunyingInfoEvent;
+        TimeMgr.Instance.OnDayEvent += OnDayEvent;
+
+        Display();
+    }
+
+
+    async UniTask SmoothScrollToBottom(float targetPos)
+    {
+        //绛夊緟
+        await UniTask.Delay(100);
+        float duration = 0.3f;
+        float elapsed = 0f;
+        float startPos = battleScrollRect.verticalNormalizedPosition;
+
+        while (elapsed < duration)
+        {
+            elapsed += Time.deltaTime;
+            float t = elapsed / duration;
+            battleScrollRect.verticalNormalizedPosition = Mathf.Lerp(startPos, targetPos, t);
+            await UniTask.Yield();
+        }
+
+        battleScrollRect.verticalNormalizedPosition = targetPos;
+    }
+
+
+    protected override void OnPreClose()
+    {
+        RankModel.Instance.onRankRefresh -= OnRankRefresh;
+        QunyingManager.Instance.OnMatchListEvent -= OnMatchListEvent;
+        PlayerDatas.Instance.playerDataRefreshEvent -= OnPlayerDataRefresh;
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+        QunyingManager.Instance.OnUpdateQunyingInfoEvent -= OnUpdateQunyingInfoEvent;
+        TimeMgr.Instance.OnDayEvent -= OnDayEvent;
+        QunyingManager.Instance.openQYWinNeedRoll = true;
+
+    }
+
+    void OnDayEvent()
+    {
+        RankModel.Instance.ResetQueryParam();
+        RankModel.Instance.QueryRankByPage(QunyingManager.rankType, 0, 3);
+        QunyingManager.Instance.RequestRefreshFighters(0);
+
+    }
+
+    void OnSecondEvent()
+    {
+        ShowGameTime();
+    }
+    void Display()
+    {
+        DisplayFighers();
+        DisplayPlayerTop3();
+        ShowGameTime();
+        ShowTicketCnt();
+        OnUpdateQunyingInfoEvent();
+
+
+    }
+
+    //娲诲姩鏃堕棿
+    void ShowGameTime()
+    {
+        gameTimeText.text = QunyingManager.Instance.GetEndSecondStr();
+        if (QunyingManager.Instance.m_LastRecoverTime == 0)
+        {
+            ticketTimeText.text = "";
+        }
+        else
+        {
+            ticketTimeText.text = Language.Get("Qunying6", TimeUtility.SecondsToDHMS(QunyingManager.Instance.restoreTicketMinute * 60 - (TimeUtility.GetCommServerTick() - (int)QunyingManager.Instance.m_LastRecoverTime)));
+        }
+    }
+
+    void ShowTicketCnt()
+    {
+        ticketCountText.text = UIHelper.GetMoneyCnt(QunyingManager.challengeMoneyType) + "/" + QunyingManager.Instance.challengeMaxCnt;
+    }
+
+
+    void DisplayPlayerTop3()
+    {
+        for (int i = 0; i < playerTop3Cells.Length; i++)
+        {
+            playerTop3Cells[i].Display(QunyingManager.rankType, i + 1);
+        }
+    }
+
+    void OnPlayerDataRefresh(PlayerDataType type)
+    {
+        if (type == PlayerDataType.QunyingWDL)
+        {
+            DisplayFighers();
+            ShowTicketCnt();
+        }
+    }
+
+    void OnRankRefresh(int type)
+    {
+        if (type != QunyingManager.rankType)
+            return;
+        DisplayPlayerTop3();
+    }
+
+    void OnUpdateQunyingInfoEvent()
+    {
+        var nextRank = QunyingManager.Instance.GetNextAchievementRank();
+        if (nextRank == 0)
+        {
+            achievementTargetText.text = Language.Get("Qunying17");
+        }
+        else
+        {
+            achievementTargetText.text = Language.Get("Qunying4", nextRank);
+        }
+
+        refreshMoneyText.text = UIHelper.ShowUseMoney(QunyingManager.Instance.refreshMoneyType, QunyingManager.Instance.refreshMoneyValue);
+        refreshMoneyImg.SetIconWithMoneyType(QunyingManager.Instance.refreshMoneyType);
+        refreshCntText.text = QunyingManager.Instance.m_RefreshCnt + "/" + QunyingManager.Instance.refreshMaxCnt;
+    }
+
+    void DisplayFighers()
+    {
+        for (int i = 0; i < FighterCells.Length; i++)
+        {
+            FighterCells[i].Display(i);
+        }
+    }
+
+    void OnMatchListEvent()
+    {
+        //婊氬姩鍒拌嚜宸辩殑浣嶇疆
+        var myMatch = QunyingManager.Instance.GetMyMatchInfo(out int index);
+        if (QunyingManager.Instance.openQYWinNeedRoll)
+        {
+            SmoothScrollToBottom(myMatch == null ? 0.1f : (4 - index) * 0.15f + 0f).Forget();
+        }
+        if (myMatch != null)
+        {
+            rankText.text = Language.Get("Qunying5", myMatch.Rank);
+        }
+        else
+        {
+            rankText.text = Language.Get("L1045");
+        }
+        DisplayFighers();
+    }
+
+
+    void RefreshFighters()
+    {
+        //楠岃瘉閽卞拰娆℃暟
+        if (!UIHelper.CheckMoneyCount(QunyingManager.Instance.refreshMoneyType, QunyingManager.Instance.refreshMoneyValue, 1))
+        {
+            return;
+        }
+
+        if (QunyingManager.Instance.m_RefreshCnt >= QunyingManager.Instance.refreshMaxCnt)
+        {
+            SysNotifyMgr.Instance.ShowTip("Qunying1");
+            return;
+        }
+
+        QunyingManager.Instance.RequestRefreshFighters(1);
+    }
+
+}
+
+
+
+
+
diff --git a/Main/System/Qunying/QYWin.cs.meta b/Main/System/Qunying/QYWin.cs.meta
new file mode 100644
index 0000000..02e9105
--- /dev/null
+++ b/Main/System/Qunying/QYWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 252aa1b571920694dba4932aaa4210be
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Qunying/QunyingManager.cs b/Main/System/Qunying/QunyingManager.cs
new file mode 100644
index 0000000..503ec64
--- /dev/null
+++ b/Main/System/Qunying/QunyingManager.cs
@@ -0,0 +1,448 @@
+using System.Collections.Generic;
+using UnityEngine;
+using LitJson;
+using System;
+using System.Linq;
+
+public class QunyingManager : GameSystemManager<QunyingManager>
+{
+    public const int challengeMoneyType = 56;   //鎸戞垬 闂紟浠�
+    public const int challengeShopID = 16;
+    public const int rankType = 10;
+    public const int recType = 312;  // 鎸戞垬璁板綍绫诲瀷 
+    public const int DataMapID = 32000;
+
+    public event Action OnMatchListEvent;
+    public List<QunyingMatchInfo> matchInfoList = new List<QunyingMatchInfo>();
+    //鐢ㄤ簬鐢ㄦ潵鎷挎垬鏂楄儨鍒╁け璐ョ殑澶村儚淇℃伅
+    public Dictionary<uint, QunyingMatchInfo> allFaceInfoDict = new Dictionary<uint, QunyingMatchInfo>();
+    public Dictionary<uint, List<QunyingGameRec>> gameRecDict = new Dictionary<uint, List<QunyingGameRec>>(); // <鐜╁ID,QunyingGameRec>
+    public uint atkPlayerId;
+    public int tagRank; //鎸戞垬鐩爣鐨勬帓鍚� 缁撴灉鏄剧ず鐢�
+    public event Action OnUpdateGameRecInfo;
+
+    public bool openQYWinNeedRoll = true; //鎵撳紑缇よ嫳鐣岄潰闇�瑕佹粴鍔ㄧ殑鎯呭喌
+
+    public uint m_RefreshCnt;    // 鏈懆宸插埛鏂板尮閰嶆鏁�
+    public uint m_LastRecoverTime;    // 涓婃鍏嶈垂鎭㈠鎸戞垬浠ゆ椂闂存埑锛屼负0鏃跺彲涓嶇敤鍊掕鏃�
+    public ushort m_RankHighest;    // 鍘嗗彶鏈�楂樺悕娆★紝绗�1鍚嶄负鏈�楂�
+    public uint m_RankSuccAward;    // 鍘嗗彶鏈�楂樺悕娆℃垚灏遍濂栬褰曪紝鎸夊鍔辫褰曠储寮曚綅杩愮畻璁板綍鏄惁宸查鍙�
+
+    public event Action OnUpdateQunyingInfoEvent;
+
+
+    public override void Init()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += BeforePlayerDataInitializeEventOnRelogin;
+        PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefresh;
+        InitTable();
+    }
+
+    public override void Release()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= BeforePlayerDataInitializeEventOnRelogin;
+        PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefresh;
+    }
+
+    public int resetOpenDay; //閲嶇疆澶�8锛屽绗竴鍛ㄥ鏋滄槸鍛�5寮�鏈嶇殑涓嶄細閲嶇疆
+    public int[] robotModelIDs;
+    public int challengeMaxCnt;
+    public int restoreTicketMinute;
+    public int refreshMoneyType;
+    public int refreshMoneyValue;
+    public int refreshMaxCnt;
+    public Dictionary<int, int[][]> dayRankAwards = new Dictionary<int, int[][]>();
+    public Dictionary<int, int[][]> weekRankAwards = new Dictionary<int, int[][]>();
+    public Dictionary<int, int[][]> achievementAwards = new Dictionary<int, int[][]>();
+    public Dictionary<int, int> achievementIndexs = new Dictionary<int, int>();
+
+    void InitTable()
+    {
+        var config = FuncConfigConfig.Get("QunyingSet");
+        resetOpenDay = int.Parse(config.Numerical1);
+        robotModelIDs = JsonMapper.ToObject<int[]>(config.Numerical2);
+
+        config = FuncConfigConfig.Get("QunyingChallenge");
+        challengeMaxCnt = int.Parse(config.Numerical1);
+        restoreTicketMinute = int.Parse(config.Numerical2);
+
+        config = FuncConfigConfig.Get("QunyingMatch");
+        var moneyInfo = ConfigParse.GetMultipleStr<int>(config.Numerical2);
+        refreshMoneyType = moneyInfo[0];
+        refreshMoneyValue = moneyInfo[1];
+        refreshMaxCnt = int.Parse(config.Numerical3);
+
+        config = FuncConfigConfig.Get("QunyingAward");
+        dayRankAwards = ConfigParse.ParseIntArray2Dict(config.Numerical1);
+        weekRankAwards = ConfigParse.ParseIntArray2Dict(config.Numerical2);
+        achievementAwards = ConfigParse.ParseIntArray2Dict(config.Numerical3);
+        achievementIndexs = ConfigParse.ParseIntDict(config.Numerical4);
+    }
+
+    public void BeforePlayerDataInitializeEventOnRelogin()
+    {
+        matchInfoList.Clear();
+    }
+
+    private void PlayerDataRefresh(PlayerDataType type)
+    {
+        if (type == PlayerDataType.QunyingWDL)
+        {
+            UpdateRedPonit();
+        }
+    }
+
+
+
+    public void UpdateQunyingMatchInfo(HA924_tagSCQunyingMatchList vNetData)
+    {
+        if (vNetData == null || vNetData.MatchList.IsNullOrEmpty())
+            return;
+
+        matchInfoList.Clear();
+
+        foreach (var item in vNetData.MatchList)
+        {
+            var matchInfo = new QunyingMatchInfo
+            {
+                Rank = item.Rank,
+                PlayerID = item.PlayerID,
+                PlayerName = item.PlayerName,
+                LV = item.LV,
+                RealmLV = item.RealmLV,
+                FightPower = (ulong)item.FightPowerEx * 100000000 + (ulong)item.FightPower,
+                Face = item.Face,
+                FacePic = item.FacePic,
+                TitleID = item.TitleID,
+                ModelMark = item.ModelMark,
+                EquipShowSwitch = item.EquipShowSwitch,
+                ServerID = item.ServerID,
+            };
+            matchInfoList.Add(matchInfo);
+            allFaceInfoDict[item.PlayerID] = matchInfo;
+        }
+        matchInfoList.Sort((a, b) => a.Rank.CompareTo(b.Rank));
+
+        UpdateRedPonit();
+        OnMatchListEvent?.Invoke();
+    }
+
+    public void UpdateQunyingInfo(HA925_tagSCQunyingPlayerInfo vNetData)
+    {
+        m_RefreshCnt = vNetData.RefreshCnt;
+        m_LastRecoverTime = vNetData.LastRecoverTime;
+        m_RankHighest = vNetData.RankHighest;
+        m_RankSuccAward = vNetData.RankSuccAward;
+
+        UpdateRedPonit();
+        OnUpdateQunyingInfoEvent?.Invoke();
+    }
+
+    public void UpdateGameRecInfo(HA009_tagSCGameRecInfo vNetData)
+    {
+        if (vNetData == null || vNetData.RecType != recType)
+            return;
+        gameRecDict.Clear();
+        uint recID = vNetData.RecID;
+        if (!gameRecDict.ContainsKey(recID))
+            gameRecDict[recID] = new List<QunyingGameRec>();
+        foreach (var rec in vNetData.RecList)
+        {
+            try
+            {
+                var userData = JsonMapper.ToObject(rec.UserData);
+                string name = userData["Name"].ToString();
+                int curRank = int.Parse(userData["CurRank"].ToString());
+                int tagRank = int.Parse(userData["TagRank"].ToString());
+
+                var gameRec = new QunyingGameRec
+                {
+                    Time = rec.Time,
+                    Value1 = rec.Value1,
+                    Value2 = rec.Value2,
+                    Value3 = rec.Value3,
+                    Value4 = rec.Value4,
+                    Value5 = rec.Value5,
+                    Value6 = rec.Value6,
+                    Value7 = rec.Value7,
+                    Value8 = rec.Value8,
+                    Name = name,
+                    CurRank = curRank,
+                    TagRank = tagRank
+                };
+
+                gameRecDict[recID].Add(gameRec);
+
+                if (recID == PlayerDatas.Instance.baseData.PlayerID)
+                {
+                    allFaceInfoDict[rec.Value3] = new QunyingMatchInfo
+                    {
+                        Rank = (ushort)tagRank,
+                        PlayerID = rec.Value3,
+                        PlayerName = name,
+                        LV = (ushort)rec.Value8,
+                        RealmLV = (ushort)rec.Value7,
+                        Face = rec.Value5,
+                        FacePic = rec.Value6,
+                        ServerID = rec.Value1,
+
+                    };
+                }
+
+            }
+            catch (Exception ex)
+            {
+                Debug.LogError($"JSON瑙f瀽閿欒: {ex.Message}, UserData: {rec.UserData}");
+                continue;
+            }
+        }
+        OnUpdateGameRecInfo?.Invoke();
+    }
+
+
+    public bool TryGetPlayerInfo(uint playerID, out QunyingMatchInfo info)
+    {
+        return allFaceInfoDict.TryGetValue(playerID, out info);
+    }
+
+    // 鑾峰彇鍖归厤淇℃伅涓垜鐨勯儴鍒�
+    public QunyingMatchInfo GetMyMatchInfo(out int index)
+    {
+        index = 0;
+        for (int i = 0; i < matchInfoList.Count; i++)
+        {
+            if (matchInfoList[i].PlayerID == PlayerDatas.Instance.baseData.PlayerID)
+            {
+                index = i;
+                return matchInfoList[i];
+            }
+        }
+        return null;
+    }
+
+    //鍚戞湇鍔″櫒璇锋眰鍒锋柊鎸戞垬瀵硅薄
+    // 0-鎵撳紑鐣岄潰鏃舵煡璇紝1-寮哄埗鍒锋柊鍖归厤鍒楄〃
+    public void RequestRefreshFighters(int refreshType)
+    {
+        var pack = new CB210_tagCSQunyingMatch();
+        pack.IsRefresh = (byte)refreshType;
+        GameNetSystem.Instance.SendInfo(pack);
+
+    }
+    public List<Item> itemInfos = new List<Item>();
+    public int quickCnt;
+    public int tagPlayerID;
+    public void UpdateFBEnd(H0320_tagFBEnd vNetData)
+    {
+        if (vNetData.Msg == null)
+            return;
+        JsonData jsonData = JsonMapper.ToObject(vNetData.Msg);
+        int dataMapID = int.Parse(jsonData["dataMapID"].ToString());
+        if (dataMapID != DataMapID)
+            return;
+        quickCnt = int.Parse(jsonData["quickCnt"].ToString());
+        tagPlayerID = int.Parse(jsonData["tagID"].ToString());
+
+        itemInfos.Clear();
+        if (jsonData["itemInfo"] != null && jsonData["itemInfo"].IsArray)
+        {
+            for (int i = 0; i < jsonData["itemInfo"].Count; i++)
+            {
+                JsonData itemData = jsonData["itemInfo"][i];
+                Item itemInfo = new Item((int)itemData["ItemID"], (long)itemData["Count"]);
+                itemInfos.Add(itemInfo);
+            }
+        }
+        UIManager.Instance.OpenWindow<QYBattleVictoryWin>();
+    }
+
+    //鏄惁鏈懆寮�鍚紝鍛ㄥ嚑寮�鍚�
+    public bool TryGetOpenWeek(out bool isThisWeek, out int weekDay)
+    {
+        weekDay = 0;
+        var openServerDay = TimeUtility.OpenDay + 1;    //浠婂ぉ鏄鍑犱釜寮�鏈嶅ぉ
+        var openFuncDay = FuncOpenLVConfig.Get((int)FuncOpenEnum.Qunying).OpenDay;  //鍔熻兘寮�鍚湪绗嚑涓紑鏈嶅ぉ寮�鏀�
+
+        //鍒ゆ柇鍔熻兘鏄惁宸插紑鍚�
+        if (openServerDay < openFuncDay - 1)
+        {
+            isThisWeek = false;
+            return true;
+        }
+
+        //璁$畻鏈懆鑷劧鍛ㄥ紑濮嬫槸寮�鏈嶅ぉ鑼冨洿
+        //浠婂ぉ鍛ㄥ嚑
+        int theWeekDay = (int)TimeUtility.ServerNow.DayOfWeek == 0 ? 7 : (int)TimeUtility.ServerNow.DayOfWeek;
+        int currentWeekStart = openServerDay - theWeekDay + 1;
+        int currentWeekEnd = currentWeekStart + 6;
+
+        //鍒ゆ柇鍔熻兘寮�鍚ぉ鏄惁鍦ㄥ綋鍓嶅懆鍐�
+        isThisWeek = openFuncDay >= currentWeekStart && openFuncDay <= currentWeekEnd;
+
+
+        if (isThisWeek)
+        {
+            weekDay = openFuncDay - currentWeekStart + 1;
+        }
+
+        return true;
+    }
+
+    public string GetEndSecondStr()
+    {
+        TryGetOpenWeek(out bool isThisWeek, out int openWeekDay);
+        if (isThisWeek && resetOpenDay - FuncOpenLVConfig.Get((int)FuncOpenEnum.Qunying).OpenDay - 1 > 7 - openWeekDay)
+        {
+            //鏈懆寮�鍚椂闂翠笉瓒� 鍒欏拰涓嬪懆鐨勫悎骞�
+            return TimeUtility.SecondsToDHMS(TimeUtility.GetCommonWeekEndTime() + 7 * 24 * 60 * 60);
+        }
+        else
+        {
+            return  TimeUtility.SecondsToDHMS(TimeUtility.GetCommonWeekEndTime());
+        }
+    }
+
+
+    //鑾峰彇涓嬩竴涓垚灏辩殑鎺掑悕濂栧姳
+    //0 娌℃湁涓嬩竴涓� 鏈�楂�
+    public int GetNextAchievementRank()
+    {
+        var keys = achievementAwards.Keys.ToList();
+        if (m_RankHighest == 0)
+            return keys[keys.Count - 1];
+        keys.Sort();
+        for (int i = 0; i < keys.Count; i++)
+        {
+            if (m_RankHighest <= keys[i])
+            {
+                if (i == 0)
+                {
+                    return 0;
+                }
+                return keys[i - 1];
+            }
+        }
+        return keys[keys.Count - 1];
+    }
+
+    //0 鏈揪鎴� 1 杈炬垚 2 宸查鍙�
+    public int GetAchievementState(int rank)
+    {
+        if (m_RankHighest == 0)
+            return 0;
+        if (m_RankHighest > rank)
+            return 0;
+
+        var awardIndex = achievementIndexs[rank];
+        bool isGot = (m_RankSuccAward & (1 << awardIndex)) != 0;
+        return isGot ? 2 : 1;
+    }
+
+    public Dictionary<int, int[][]> GetRankAwardDict(int functionOrder)
+    {
+        return functionOrder == 0 ? weekRankAwards : dayRankAwards;
+    }
+
+    public int[][] GetMyRankAwards(int functionOrder, int rank)
+    {
+        if (rank == 0)
+        {
+            return null;
+        }
+        var awardDict = GetRankAwardDict(functionOrder);
+        var keys = awardDict.Keys.ToList();
+        keys.Sort();
+        for (int i = 0; i < keys.Count; i++)
+        {
+            if (rank <= keys[i])
+            {
+                return awardDict[keys[i]];
+            }
+        }
+        return null;
+    }
+
+    /// <summary>
+    /// 鏍规嵁recID鑾峰彇鎸夋椂闂翠粠澶у埌灏忔帓搴忕殑List<QunyingGameRec>
+    /// </summary>
+    /// <param name="recID">璁板綍ID</param>
+    /// <param name="sortedList">杈撳嚭鍙傛暟锛氭寜鏃堕棿浠庡ぇ鍒板皬鎺掑簭鐨凲unyingGameRec鍒楄〃</param>
+    /// <returns>濡傛灉recID瀛樺湪涓旀垚鍔熻幏鍙栧垪琛ㄨ繑鍥瀟rue锛屽惁鍒欒繑鍥瀎alse</returns>
+    public bool TryGetSortedGameRecList(uint recID, out List<QunyingGameRec> sortedList)
+    {
+        sortedList = null;
+        if (!gameRecDict.ContainsKey(recID))
+            return false;
+        sortedList = new List<QunyingGameRec>(gameRecDict[recID]);
+        sortedList.Sort((a, b) => b.Time.CompareTo(a.Time)); // 鎸夋椂闂翠粠澶у埌灏忔帓搴�
+        return true;
+    }
+
+    #region 绾㈢偣
+
+    public Redpoint parentRedpoint = new Redpoint(MainRedDot.Qunying);
+    Redpoint awardRedpoint = new Redpoint(MainRedDot.Qunying, MainRedDot.Qunying * 10 + 1);
+    Redpoint matchRedpoint = new Redpoint(MainRedDot.Qunying, MainRedDot.Qunying * 10 + 2);
+    public void UpdateRedPonit()
+    {
+        awardRedpoint.state = RedPointState.None;
+        matchRedpoint.state = RedPointState.None;
+
+        if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Qunying))
+        {
+            return;
+        }
+
+        var keys = achievementAwards.Keys.ToList();
+        for (int i = 0; i < keys.Count; i++)
+        {
+            if (GetAchievementState(keys[i]) == 1)
+            {
+                awardRedpoint.state = RedPointState.Simple;
+                break;
+            }
+        }
+
+        if (UIHelper.GetMoneyCnt(challengeMoneyType) >= challengeMaxCnt)
+        {
+            matchRedpoint.state = RedPointState.Simple;
+        }
+        
+    }
+    #endregion
+}
+
+public class QunyingMatchInfo
+{
+    public ushort Rank;        //鎺掑悕锛屼粠1寮�濮�
+    public uint PlayerID;        //鐩爣鐜╁ID
+    public string PlayerName;
+    public ushort LV;        // 鐜╁绛夌骇
+    public ushort RealmLV;        //澧冪晫锛屾満鍣ㄤ汉璇诲鐣岃〃鍙栫瓑绾у搴斿鐣�
+    public ulong FightPower;        //鎴樺姏
+    public uint Face;        //鍩烘湰鑴稿瀷
+    public uint FacePic;        //澶村儚妗�
+    public uint TitleID;        //绉板彿
+    public uint ModelMark;        //鍙樺舰妯″瀷mark
+    public uint EquipShowSwitch;        //鍏朵粬澶栬淇℃伅
+    public uint ServerID;
+
+}
+
+
+public class QunyingGameRec
+{
+    public uint Time;        //鎴樻枟鏃堕棿鎴�
+    public uint Value1;        //sid
+    public uint Value2;        //鏀诲嚮绫诲瀷 1-鍙戣捣鏀诲嚮鐨勶紝2-琚敾鍑荤殑
+    public uint Value3;        //鐩稿鏀诲嚮绫诲瀷鐨勭洰鏍囩帺瀹禝D
+    public uint Value4;        //鏄惁鑾疯儨 1-鑾疯儨锛�2-澶辫触
+    public uint Value5;        //鐩爣澶村儚
+    public uint Value6;        //鐩爣澶村儚妗�
+    public uint Value7;        //鐩爣瀹樿亴
+    public uint Value8;        //鐩爣绛夌骇
+    public string Name;         //鐩爣鍚嶇О
+    public int CurRank;
+    public int TagRank;
+
+}
diff --git a/Main/System/Qunying/QunyingManager.cs.meta b/Main/System/Qunying/QunyingManager.cs.meta
new file mode 100644
index 0000000..24652f3
--- /dev/null
+++ b/Main/System/Qunying/QunyingManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 74ba65a50741eb34587acd91742946aa
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Recharge/ExpSecretCollectionWin.cs b/Main/System/Recharge/ExpSecretCollectionWin.cs
index 963dfae..a231036 100644
--- a/Main/System/Recharge/ExpSecretCollectionWin.cs
+++ b/Main/System/Recharge/ExpSecretCollectionWin.cs
@@ -84,7 +84,7 @@
 
         buyBtn.SetActive(ExpSecretCollectionManager.Instance.m_MJLV == 0);
         RechargeManager.Instance.TryGetOrderInfo(ExpSecretCollectionManager.Instance.ctgID, out var orderInfoConfig);
-        buyText.text = Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale);
+        buyText.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfoConfig.PayRMBNumOnSale));
         buyYetRect.SetActive(ExpSecretCollectionManager.Instance.m_MJLV != 0);
 
         scroller.m_Scorller.RefreshActiveCellViews();
diff --git a/Main/System/Recharge/PrivilegeCardCell.cs b/Main/System/Recharge/PrivilegeCardCell.cs
index 3daacc2..5afc1dd 100644
--- a/Main/System/Recharge/PrivilegeCardCell.cs
+++ b/Main/System/Recharge/PrivilegeCardCell.cs
@@ -87,7 +87,7 @@
         if (state == 0)
         {
             var orderInfo = InvestModel.Instance.GetOrderInfo(type);
-            opBtnText.text = Language.Get("PayMoneyNum", orderInfo.PayRMBNumOnSale);
+            opBtnText.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfo.PayRMBNumOnSale));
             opBtn.SetInteractable(true);
             opBtn.AddListener(() =>
             {
@@ -108,7 +108,7 @@
             if (type == 1)
             {            
                 var orderInfo = InvestModel.Instance.GetOrderInfo(type);
-                opBtnText.text = Language.Get("PayMore", orderInfo.PayRMBNumOnSale);
+                opBtnText.text = Language.Get("PayMore", UIHelper.GetMoneyFormat(orderInfo.PayRMBNumOnSale));
                 opBtn.SetInteractable(true);
                 opBtn.AddListener(() =>
                 {
diff --git a/Main/System/Recharge/RechargeDJQCell.cs b/Main/System/Recharge/RechargeDJQCell.cs
index 6fe331f..7719920 100644
--- a/Main/System/Recharge/RechargeDJQCell.cs
+++ b/Main/System/Recharge/RechargeDJQCell.cs
@@ -28,7 +28,7 @@
         }
         normalNums.text = (config.GainGold/100).ToString();
         RechargeManager.Instance.TryGetOrderInfo(ctgID, out var orderInfoConfig);
-        priceText.text = Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale);
+        priceText.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfoConfig.PayRMBNumOnSale));
         icon.SetSprite(config.Icon);
         icon.SetNativeSize();
         buyBtn.AddListener(() =>
diff --git a/Main/System/Recharge/RechargeGoldCell.cs b/Main/System/Recharge/RechargeGoldCell.cs
index f3c3d0c..a1ba1e3 100644
--- a/Main/System/Recharge/RechargeGoldCell.cs
+++ b/Main/System/Recharge/RechargeGoldCell.cs
@@ -32,7 +32,7 @@
             normalNums.text = config.GainGold.ToString();
         }
         RechargeManager.Instance.TryGetOrderInfo(ctgID, out var orderInfoConfig);
-        priceText.text = Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale);
+        priceText.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfoConfig.PayRMBNumOnSale));
         icon.SetSprite(config.Icon);
         icon.SetNativeSize();
         buyBtn.AddListener(() =>
diff --git a/Main/System/Recharge/RechargeManager.cs b/Main/System/Recharge/RechargeManager.cs
index ff8e625..db1309a 100644
--- a/Main/System/Recharge/RechargeManager.cs
+++ b/Main/System/Recharge/RechargeManager.cs
@@ -754,6 +754,32 @@
     {
         return b.Time.CompareTo(a.Time);
     }
+
+    //鎸変笉鍚岄檺璐鍒欒繘琛屽垽鏂�
+    public bool IsSellOut(int ctgID)
+    {
+        var cfg = CTGConfig.Get(ctgID);
+        Instance.TryGetRechargeCount(ctgID, out RechargeCount _rechargeCount);
+        if (cfg.DailyBuyCount != 0)
+        {
+            return _rechargeCount.todayCount >= cfg.DailyBuyCount;
+        }
+        else if (cfg.WeekBuyCount != 0)
+        {
+            return _rechargeCount.weekPayCount >= cfg.WeekBuyCount;
+        }
+
+        else if (cfg.MonthBuyCount != 0)
+        {
+            return _rechargeCount.monthPayCount >= cfg.MonthBuyCount;
+        }
+        else if (cfg.TotalBuyCount != 0)
+        {
+            return _rechargeCount.totalCount >= cfg.TotalBuyCount;
+        }
+
+        return false;
+    }
 }
 
 
diff --git a/Main/System/Recharge/RechargeWin.cs b/Main/System/Recharge/RechargeWin.cs
index 2a2579f..b44625c 100644
--- a/Main/System/Recharge/RechargeWin.cs
+++ b/Main/System/Recharge/RechargeWin.cs
@@ -72,7 +72,7 @@
                 {
                     if (i % 3 == 0)
                     {
-                        djqScroller.AddCell(ScrollerDataType.Header,i);
+                        djqScroller.AddCell(ScrollerDataType.Header, i);
                     }
                 }
                 djqScroller.Restart();
@@ -81,6 +81,7 @@
             {
                 djqScroller.m_Scorller.RefreshActiveCellViews();
             }
+            SDKUtils.Instance.SendTraceEvent(8, "鍏呭��", "鐜勭帀", "0");
         }
         else if (RechargeManager.Instance.selectTabIndex == 1)
         {
@@ -105,6 +106,7 @@
             {
                 goldScroller.m_Scorller.RefreshActiveCellViews();
             }
+            SDKUtils.Instance.SendTraceEvent(8, "鍏呭��", "鍏冨疂", "1");
         }
     }
 
diff --git a/Main/System/Redpoint/MainRedDot.cs b/Main/System/Redpoint/MainRedDot.cs
index d612f4d..645f78e 100644
--- a/Main/System/Redpoint/MainRedDot.cs
+++ b/Main/System/Redpoint/MainRedDot.cs
@@ -83,6 +83,9 @@
     public const int RedPoint_GuaBao = 118;
     //鍛芥牸
     public const int RedPoint_Mingge = 119;
+    //濂借瘎绂忓埄
+    public const int RedPoint_Review = 120;
+
     //姝﹀皢鍗�
     public const int HeroCardRedpoint = 200;
     public Redpoint HeroListRedpoint = new Redpoint(MainHerosRedpoint, HeroCardRedpoint);
@@ -147,6 +150,11 @@
     public const int DailyTehui = 476;//姣忔棩鐗规儬
     public const int WarlordPavilionRepoint = 477;//瀹氬啗闃�
     public const int TimeRushRepoint = 478; //杞洖娈�
+    public const int HeroDebutRepoint = 479; //姝﹀皢鐧诲満
+    public const int Qunying = 480; //缇よ嫳姒�
+    public const int RedPoint_OSHeroTrain = 481;
+    public const int RedPoint_OSBeautyMM = 482;
+    public const int RedPoint_OSMingge = 483;
     public void Register()
     {
 
diff --git a/Main/System/Scroll/ScrollerController.cs b/Main/System/Scroll/ScrollerController.cs
index e08426b..6e3db1d 100644
--- a/Main/System/Scroll/ScrollerController.cs
+++ b/Main/System/Scroll/ScrollerController.cs
@@ -367,11 +367,13 @@
             if (horizontal)
             {
                 
-                rect.sizeDelta = rect.sizeDelta.SetX(Math.Min(jiaMiddleWithMaxSize, (m_CellHeaderPrefab.height + m_Scorller.spacing) * _data.Count - m_Scorller.spacing));
+                rect.sizeDelta = rect.sizeDelta.SetX(Math.Min(jiaMiddleWithMaxSize, (m_CellHeaderPrefab.height + m_Scorller.spacing) * _data.Count - m_Scorller.spacing +
+                m_Scorller.padding.right + m_Scorller.padding.left));
             }
             else if (vertical)
             {
-                rect.sizeDelta = rect.sizeDelta.SetY(Math.Min(jiaMiddleWithMaxSize, (m_CellHeaderPrefab.height + m_Scorller.spacing) * _data.Count - m_Scorller.spacing));
+                rect.sizeDelta = rect.sizeDelta.SetY(Math.Min(jiaMiddleWithMaxSize, (m_CellHeaderPrefab.height + m_Scorller.spacing) * _data.Count - m_Scorller.spacing +
+                m_Scorller.padding.top + m_Scorller.padding.bottom));
             }
             if (rect.sizeDelta.x < jiaMiddleWithMaxSize)
             {
diff --git a/Main/System/Settlement/BattleSettlementManager.cs b/Main/System/Settlement/BattleSettlementManager.cs
index 199809f..4b74d1b 100644
--- a/Main/System/Settlement/BattleSettlementManager.cs
+++ b/Main/System/Settlement/BattleSettlementManager.cs
@@ -55,6 +55,9 @@
                 WarlordPavilionManager.Instance.isAutoNext = isWin;
                 PopupWindowsProcessor.Instance.Add(isWin ? "WarlordPavilionVictoryWin" : "WarlordPavilionFailWin", false, BattleConst.WarlordPavilionBattleField);
                 break;
+            case BattleConst.QYBattleField:
+                PopupWindowsProcessor.Instance.Add(isWin ? "QYBattleVictoryWin" : "QYBattleFailWin", false, BattleConst.QYBattleField);
+                break;
             default:
                 PopupWindowsProcessor.Instance.Add(isWin ? "BattleVictoryWin" : "BattleFailWin", false, BattleConst.StoryBossBattleField);
                 break;
@@ -101,6 +104,19 @@
                     UIManager.Instance.OpenWindowAsync<WarlordPavilionFailWin>().Forget();
                 }
                 break;
+            case BattleConst.PriviewBattleField:
+                UIManager.Instance.CloseWindow<PreviewBattleWin>();
+                break;
+            case BattleConst.QYBattleField:
+                if (isWin)
+                {
+                    UIManager.Instance.OpenWindow<QYBattleVictoryWin>();
+                }
+                else
+                {
+                    UIManager.Instance.OpenWindow<QYBattleFailWin>();
+                }
+                break;
             default:
                 if (isWin)
                 {
diff --git a/Main/System/SmallFunc.meta b/Main/System/SmallFunc.meta
new file mode 100644
index 0000000..448265b
--- /dev/null
+++ b/Main/System/SmallFunc.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: d87e877ec143c7f42b49d2659587f18a
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/SmallFunc/GoodReviewWin.cs b/Main/System/SmallFunc/GoodReviewWin.cs
new file mode 100644
index 0000000..f2b9205
--- /dev/null
+++ b/Main/System/SmallFunc/GoodReviewWin.cs
@@ -0,0 +1,84 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+//濂借瘎
+public class GoodReviewWin : UIBase
+{
+    [SerializeField] ItemCell[] itemCells;
+    [SerializeField] Button goBtn;
+    [SerializeField] Text goBtnText;    //鍓嶅線璇勪环 Review2 / 棰嗗彇濂栧姳 Review4
+
+
+    protected override void InitComponent()
+    {
+        goBtn.AddListener(()=>
+        {
+            if (SmallFuncManager.Instance.IsReviewOpen())
+            {
+                if (SmallFuncManager.Instance.GetReviewState() == 1)
+                {
+                    //棰嗗彇濂栧姳
+                    var pack = new CA504_tagCMPlayerGetReward();
+                    pack.RewardType = 35;
+                    GameNetSystem.Instance.SendInfo(pack);
+                    CloseWindow();
+                    return;
+                }
+
+                if (!string.IsNullOrEmpty(SDKUtils.channelSign))
+                {
+                    var appID = VersionConfig.Get().appId;
+                    if (appID == "sghy")
+                    {
+                        SDKUtils.Instance.GoToReview();
+                    }
+                    else
+                    {
+                        //鍓嶅線璇勪环
+                        Application.OpenURL(GeneralDefine.review_UrlDict[SDKUtils.channelSign]);
+                    }
+                }
+                LocalSave.SetInt("review" + PlayerDatas.Instance.baseData.PlayerID, TimeUtility.AllSeconds);
+            }
+        });
+    }
+
+
+    protected override void OnPreOpen()
+    {
+        GlobalTimeEvent.Instance.secondEvent += OnSecondEvent;
+        for (int i = 0; i < itemCells.Length; i++)
+        {
+            if (i < GeneralDefine.review_Awards.Length)
+            {
+                itemCells[i].SetActive(true);
+                var itemID = GeneralDefine.review_Awards[i][0];
+                itemCells[i].Init(new ItemCellModel(itemID, false, GeneralDefine.review_Awards[i][1]));
+                itemCells[i].button.AddListener(() =>
+                {
+                    ItemTipUtility.Show(itemID);
+                });
+            }
+            else
+            {
+                itemCells[i].SetActive(false);
+            }
+        }
+
+        goBtnText.text = SmallFuncManager.Instance.GetReviewState() == 1 ? Language.Get("Review4") : Language.Get("Review2");
+    }
+
+    protected override void OnPreClose()
+    {
+        GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent;
+    }
+
+    void OnSecondEvent()
+    {
+        goBtnText.text = SmallFuncManager.Instance.GetReviewState() == 1 ? Language.Get("Review4") : Language.Get("Review2");
+    }
+
+
+
+}
diff --git a/Main/System/SmallFunc/GoodReviewWin.cs.meta b/Main/System/SmallFunc/GoodReviewWin.cs.meta
new file mode 100644
index 0000000..ef9bc1f
--- /dev/null
+++ b/Main/System/SmallFunc/GoodReviewWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: decdd0e3914df2f4a8ced80ac3ae6d4f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/SmallFunc/SmallFuncManager.cs b/Main/System/SmallFunc/SmallFuncManager.cs
new file mode 100644
index 0000000..c166d16
--- /dev/null
+++ b/Main/System/SmallFunc/SmallFuncManager.cs
@@ -0,0 +1,129 @@
+锘縰sing System.Collections.Generic;
+using UnityEngine.UI;
+using System.Linq;
+using LitJson;
+using System;
+
+//涓�浜涘皬鍔熻兘灏戦噺浠g爜瀛樻斁
+public class SmallFuncManager : GameSystemManager<SmallFuncManager>
+{
+
+    public Dictionary<int, int> playerRewardDict = new Dictionary<int, int>();  //A3 0C 鐜╁鍚勫鍔辩被鍨嬮鍙栬褰曚俊鎭� #tagMCPlayerRewardGetRecord
+    public event Action OnPlayerRewardEvent;
+
+
+    
+    public override void Init()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitialize;
+        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk;
+        UIManager.Instance.OnCloseWindow += OnCloseWindow;
+    }
+
+    public override void Release()
+    {
+        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitialize;
+        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnPlayerLoginOk;
+        UIManager.Instance.OnCloseWindow -= OnCloseWindow;
+    }
+
+    public void OnBeforePlayerDataInitialize()
+    {
+        playerRewardDict.Clear();
+    }
+
+    void OnPlayerLoginOk()
+    {
+        UpdateReviewRedpoint();
+    }
+
+    void OnCloseWindow(UIBase win)
+    {
+        if (win is StoryBossBattleWin)
+        {
+            //鍒氬ソ杩囧叧鐨勬椂鍊欐帹閫�
+            if (PlayerDatas.Instance.baseData.ExAttr1 == (GeneralDefine.review_MainLevel + 1) * 100 && IsReviewOpen())
+            {
+                PopupWindowsProcessor.Instance.Add("GoodReviewWin");
+                UpdateReviewRedpoint();
+            }
+        }
+    }
+
+
+    public void UpdatePlayerReward(HA30C_tagMCPlayerRewardGetRecord pack)
+    {
+        playerRewardDict[pack.RewardType] = (int)pack.RewardGetRecord;
+        UpdateReviewRedpoint();
+        OnPlayerRewardEvent?.Invoke();
+    }
+
+
+    #region 濂借瘎
+
+    //鏄惁鏄剧ず濂借瘎 1.杈惧埌閫氬叧鏉′欢 2.璇ユ笭閬撴湁濂借瘎鍔熻兘锛�3. 鏈鍙栧鍔憋紙鏈瘎浠凤級
+    public bool IsReviewOpen()
+    {
+        var appID = VersionConfig.Get().appId;
+        if (appID == "sghy")
+        {
+            if (TimeUtility.CreateDays == 1)
+            {
+                //绗簩澶╂墠鍙互璇勮
+                return false;
+            }
+        }
+        else
+        {
+            if (PlayerDatas.Instance.baseData.ExAttr1 / 100 <= GeneralDefine.review_MainLevel)
+            {
+                return false;
+            }
+
+            if (!GeneralDefine.review_UrlDict.ContainsKey(SDKUtils.channelSign) && VersionConfig.Get().versionAuthority == VersionAuthority.Release)
+            {
+                return false;
+            }
+        }
+
+
+        if (GetReviewState() == 2)
+        {
+            return false;
+        }
+
+        // 濂栧姳
+        return true;
+    }
+
+    // 濂借瘎绾㈢偣
+    Redpoint reviewRedpoint = new Redpoint(MainRedDot.RightFuncRedpoint, MainRedDot.RedPoint_Review);
+
+    void UpdateReviewRedpoint()
+    {
+        reviewRedpoint.state = IsReviewOpen() ? RedPointState.Simple : RedPointState.None;
+    }
+    
+    //璇勫垎浠呭彲棰�1娆� 0 鏈瘎鍒� 1 鍙鍙� 2 宸查鍙�
+    public int GetReviewState()
+    {
+        if (!playerRewardDict.ContainsKey(35) || playerRewardDict[35] == 0)
+        {
+            var clickTime = LocalSave.GetInt("review" + PlayerDatas.Instance.baseData.PlayerID);
+            if (clickTime == 0)
+            {
+                return 0;
+            }
+            if (TimeUtility.AllSeconds - clickTime > GeneralDefine.review_CD)
+            {
+                return 1;
+            }
+            return 0;
+        }
+
+        return 2;
+    }
+
+    #endregion
+}
+
diff --git a/Main/System/SmallFunc/SmallFuncManager.cs.meta b/Main/System/SmallFunc/SmallFuncManager.cs.meta
new file mode 100644
index 0000000..c2ab9ba
--- /dev/null
+++ b/Main/System/SmallFunc/SmallFuncManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 63a1f22377829424cab384d0ce8401ea
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Store/BuyItemWin.cs b/Main/System/Store/BuyItemWin.cs
index a1ea81a..eec1011 100644
--- a/Main/System/Store/BuyItemWin.cs
+++ b/Main/System/Store/BuyItemWin.cs
@@ -50,8 +50,15 @@
         maxCnt = shopConfig.LimitCnt - buyCnt;
         if (maxCnt == 0)
         {
-            //娌℃湁闄愯喘,鐢ㄨ揣甯佸彲璐拱鏁伴噺
-            maxCnt = Math.Max(1, (int)(UIHelper.GetMoneyCnt(shopConfig.MoneyType)/shopConfig.MoneyNum));
+            if (shopConfig.MoneyType <= 0)
+            {
+                maxCnt = Math.Max(1, (int)(PackManager.Instance.GetItemCountByID(PackType.Item, shopConfig.CostItemID) / shopConfig.MoneyNum));
+            }
+            else
+            {
+                //娌℃湁闄愯喘,鐢ㄨ揣甯佸彲璐拱鏁伴噺
+                maxCnt = Math.Max(1, (int)(UIHelper.GetMoneyCnt(shopConfig.MoneyType) / shopConfig.MoneyNum));
+            }
         }
 
         OnSliderChange(useCnt);
@@ -97,8 +104,17 @@
         }
         limitText.text = limitStr;
 
-        moneyIcon.SetIconWithMoneyType(shopConfig.MoneyType);
-        moneyText.text = UIHelper.ShowUseMoney(shopConfig.MoneyType, shopConfig.MoneyNum * useCnt, false);
+        if (shopConfig.MoneyType <= 0)
+        {
+            moneyIcon.SetItemSprite(shopConfig.CostItemID);
+            moneyText.text = UIHelper.ShowUseItem(PackType.Item, shopConfig.CostItemID, shopConfig.MoneyNum * useCnt, false);
+        }
+        else
+        {
+            moneyIcon.SetIconWithMoneyType(shopConfig.MoneyType);
+            moneyText.text = UIHelper.ShowUseMoney(shopConfig.MoneyType, shopConfig.MoneyNum * useCnt, false);
+        }
+
 
     }
 
diff --git a/Main/System/Store/HeroSkinGiftWin.cs b/Main/System/Store/HeroSkinGiftWin.cs
new file mode 100644
index 0000000..ff7ab86
--- /dev/null
+++ b/Main/System/Store/HeroSkinGiftWin.cs
@@ -0,0 +1,120 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+//鏃惰绀煎寘
+public class HeroSkinGiftWin : UIBase
+{
+    [SerializeField] GroupButtonEx[] giftBtns;
+
+    [SerializeField] ItemCell[] itemCells;
+    [SerializeField] Text priceText;
+    [SerializeField] Button buyBtn;
+    [SerializeField] Transform saleOutObj;
+    [SerializeField] Image bg1;
+    [SerializeField] Image bg2;
+    [SerializeField] Button closeBtn;
+
+    int index;
+
+    protected override void InitComponent()
+    {
+        buyBtn.AddListener(() =>
+        {
+            RechargeManager.Instance.CTG(GeneralDefine.heroSkinGiftList[index]);
+        });
+        for (int i = 0; i < giftBtns.Length; i++)
+        {
+            int _index = i;
+            giftBtns[i].AddListener(() =>
+            {
+                index = _index;
+                Display();
+            });
+        }
+        closeBtn.AddListener(() =>
+        {
+            CloseWindow();
+        });
+    }
+
+
+    protected override void OnPreOpen()
+    {
+        index = 0;
+        RechargeManager.Instance.rechargeCountEvent += OnRechargeCountEvent;
+
+        for (int i = 0; i < giftBtns.Length; i++)
+        {
+            if (i < GeneralDefine.heroSkinGiftList.Length)
+            {
+                giftBtns[i].SetActive(true);
+                var cfg = CTGConfig.Get(GeneralDefine.heroSkinGiftList[i]);
+                RechargeManager.Instance.TryGetRechargeCount(GeneralDefine.heroSkinGiftList[i], out RechargeCount _rechargeCount);
+                if (_rechargeCount.todayCount < cfg.DailyBuyCount)
+                {
+                    index = i;
+                    break;
+                }
+            }
+            else
+            {
+                giftBtns[i].SetActive(false);
+            }
+        }
+        giftBtns[index].SelectBtn();
+
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        RechargeManager.Instance.rechargeCountEvent -= OnRechargeCountEvent;
+    }
+
+    void Display()
+    {
+        RechargeManager.Instance.TryGetRechargeItem(GeneralDefine.heroSkinGiftList[index], out var itemList);
+        for (int i = 0; i < itemCells.Length; i++)
+        {
+            if (i < itemList.Count)
+            {
+                itemCells[i].SetActive(true);
+                int itemID = itemList[i].id;
+                itemCells[i].Init(new ItemCellModel(itemID, true, itemList[i].countEx));
+                itemCells[i].button.SetListener(() => ItemTipUtility.Show(itemID));
+            }
+            else
+            {
+                itemCells[i].SetActive(false);
+            }
+        }
+        if (!RechargeManager.Instance.IsSellOut(GeneralDefine.heroSkinGiftList[index]))
+        {
+            buyBtn.SetActive(true);
+            saleOutObj.SetActive(false);
+        }
+        else
+        {
+            buyBtn.SetActive(false);
+            saleOutObj.SetActive(true);
+        }
+
+
+        RechargeManager.Instance.TryGetOrderInfo(GeneralDefine.heroSkinGiftList[index], out var orderInfoConfig);
+        priceText.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfoConfig.PayRMBNumOnSale));
+
+        bg1.SetSprite($"HeroSkinGiftBg{index}_1");
+        bg2.SetSprite($"HeroSkinGiftBg{index}_2");
+        bg1.SetNativeSize();
+        bg2.SetNativeSize();
+    }
+    private void OnRechargeCountEvent(int obj)
+    {
+        Display();
+    }
+
+
+
+
+}
diff --git a/Main/System/Store/HeroSkinGiftWin.cs.meta b/Main/System/Store/HeroSkinGiftWin.cs.meta
new file mode 100644
index 0000000..f80c584
--- /dev/null
+++ b/Main/System/Store/HeroSkinGiftWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 99000a2eedd88ac40bbdf6f46e4a2aa0
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Store/SkinStoreBuyTipWin.cs b/Main/System/Store/SkinStoreBuyTipWin.cs
new file mode 100644
index 0000000..78326c2
--- /dev/null
+++ b/Main/System/Store/SkinStoreBuyTipWin.cs
@@ -0,0 +1,85 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+//鏃惰纰庣墖鍟嗗簵璐拱鐣岄潰
+public class SkinStoreBuyTipWin : UIBase
+{
+    [SerializeField] Image skinImage;
+    [SerializeField] Image skinFrame;
+    [SerializeField] Text skinName;
+    [SerializeField] Text heroName;
+    [SerializeField] Text[] onAttrTexts;
+    [SerializeField] Text[] allAttrTexts;
+    [SerializeField] Image moneyIcon;
+    [SerializeField] Text moneyText;
+    [SerializeField] Button buyButton;
+
+
+
+    protected override void InitComponent()
+    {
+        buyButton.AddListener(BuyGoods);
+    }
+
+
+    protected override void OnPreOpen()
+    {
+        
+        var storeConfig = StoreConfig.Get(StoreModel.Instance.buyShopID);
+        HeroSkinAttrConfig.itemIdToSkinIDDict.TryGetValue(storeConfig.ItemID, out var skinID);
+
+        var skinConfig = HeroSkinConfig.Get(skinID);
+        var attrCfg = HeroSkinAttrConfig.Get(skinID);
+        skinImage.SetOrgSprite(skinConfig.CardPic, "HeroSkinCard");
+        skinFrame.SetSprite("HeroSkinFrame" + (attrCfg== null ? 0 : attrCfg.Quality));
+        skinName.text = skinConfig.SkinName == "" ? Language.Get("HeroSkin2") : skinConfig.SkinName;
+
+        var heroID = HeroConfig.GetHeroIDBySkinID(skinID);
+        heroName.text = Language.Get("HeroSkin12", HeroConfig.Get(heroID).Name);
+
+        var shopConfig = StoreConfig.Get(StoreModel.Instance.buyShopID);
+        moneyIcon.SetIconWithMoneyType(shopConfig.MoneyType);
+        moneyText.text = UIHelper.ShowUseMoney(shopConfig.MoneyType, shopConfig.MoneyNum);
+
+        RefreshAttr(skinID);
+    }
+
+
+    void BuyGoods()
+    {
+        CloseWindow();
+        StoreModel.Instance.SendBuyShopItem(StoreConfig.Get(StoreModel.Instance.buyShopID), 1);
+    } 
+
+    void RefreshAttr(int skinID)
+    {
+        var cfg = HeroSkinAttrConfig.Get(skinID);
+
+        string format = "{0}" + UIHelper.AppendColor(TextColType.Green, "+{1}", false);
+        for (int i = 0; i < onAttrTexts.Length; i++)
+        {
+            if (i < cfg.WearAttrIDList.Length)
+            {
+                onAttrTexts[i].text = PlayerPropertyConfig.GetFullDescription(cfg.WearAttrIDList[i], cfg.WearAttrValueList[i], format);
+            }
+            else
+            {
+                onAttrTexts[i].text = "";
+            }
+        }
+
+        for (int i = 0; i < allAttrTexts.Length; i++)
+        {
+            if (i < cfg.RoleAttrIDList.Length)
+            {
+                allAttrTexts[i].text = PlayerPropertyConfig.GetFullDescription(cfg.RoleAttrIDList[i], cfg.RoleAttrValueList[i], format);
+            }
+            else
+            {
+                allAttrTexts[i].text = "";
+            }
+        }
+
+    }
+}
diff --git a/Main/System/Store/SkinStoreBuyTipWin.cs.meta b/Main/System/Store/SkinStoreBuyTipWin.cs.meta
new file mode 100644
index 0000000..af93f01
--- /dev/null
+++ b/Main/System/Store/SkinStoreBuyTipWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: aa1386c1cdea3ae42a9057ac78623aa9
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Store/SkinStoreCell.cs b/Main/System/Store/SkinStoreCell.cs
new file mode 100644
index 0000000..fc34772
--- /dev/null
+++ b/Main/System/Store/SkinStoreCell.cs
@@ -0,0 +1,72 @@
+锘縰sing System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+
+public class SkinStoreCell : MonoBehaviour
+{
+    [SerializeField] Image skinImage;
+    [SerializeField] Button skinBtn; //璺宠浆鐨偆鐣岄潰
+    [SerializeField] Image skinFrame;
+    [SerializeField] Text skinName;
+    [SerializeField] Text heroName;
+    [SerializeField] Image priceIcon;
+    [SerializeField] Text priceText;
+    [SerializeField] Button buyButton;
+    [SerializeField] Transform gotYetObj; 
+
+
+
+    public void Display(int index)
+    {
+        var list = StoreModel.Instance.storeTypeDict[(int)StoreFunc.HeroSkin];
+        var storeData = list[index];
+        int shopID = storeData.shopId;
+        var itemID = storeData.storeConfig.ItemID;
+        HeroSkinAttrConfig.itemIdToSkinIDDict.TryGetValue(itemID, out var skinID);
+        if (skinID == 0)
+        {
+            Debug.LogError("鏃惰鍟嗗簵閰嶇疆閿欒 娌℃湁瀵瑰簲鐨偆 鍟嗗搧锛�" + shopID);
+            return;
+        }
+        var skinConfig = HeroSkinConfig.Get(skinID);
+        var attrCfg = HeroSkinAttrConfig.Get(skinID);
+        skinImage.SetOrgSprite(skinConfig.CardPic, "HeroSkinCard");
+        skinFrame.SetSprite("HeroSkinFrame" + (attrCfg== null ? 0 : attrCfg.Quality));
+        skinName.text = skinConfig.SkinName == "" ? Language.Get("HeroSkin2") : skinConfig.SkinName;
+
+        var heroID = HeroConfig.GetHeroIDBySkinID(skinID);
+        heroName.text = HeroConfig.Get(heroID).Name;
+
+        //0鍙喘涔� 1宸插敭缃� 2鍏嶈垂 3鏈В閿�
+        var state = StoreModel.Instance.GetShopIDState(shopID);
+        if (state == 0)
+        {
+            buyButton.SetActive(true);
+            gotYetObj.SetActive(false);
+
+            buyButton.AddListener(() => { BuyGoods(shopID); });
+        }
+        else
+        {
+            buyButton.SetActive(false);
+            gotYetObj.SetActive(true);
+        }
+        
+        priceIcon.SetIconWithMoneyType(storeData.storeConfig.MoneyType);
+        priceText.text = storeData.storeConfig.MoneyNum.ToString();
+
+        skinBtn.AddListener(()=>
+        {
+            HeroUIManager.Instance.selectForPreviewHeroID = heroID;
+            HeroUIManager.Instance.selectSkinIndex = HeroDebutManager.Instance.GetSkinIndexInHeroConfig(heroID, skinID);
+            UIManager.Instance.OpenWindow<HeroBestBaseWin>(1);
+        });
+    }
+
+    void BuyGoods(int shopID)
+    {
+        StoreModel.Instance.buyShopID = shopID;
+        UIManager.Instance.OpenWindow<SkinStoreBuyTipWin>();
+    }
+}
diff --git a/Main/System/Store/SkinStoreCell.cs.meta b/Main/System/Store/SkinStoreCell.cs.meta
new file mode 100644
index 0000000..bb59451
--- /dev/null
+++ b/Main/System/Store/SkinStoreCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 532a5bd8a17a88840927d2c86a99e6dd
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Store/SkinStoreLineCell.cs b/Main/System/Store/SkinStoreLineCell.cs
new file mode 100644
index 0000000..d637c35
--- /dev/null
+++ b/Main/System/Store/SkinStoreLineCell.cs
@@ -0,0 +1,28 @@
+锘縰sing System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+
+public class SkinStoreLineCell : CellView
+{
+
+    [SerializeField] SkinStoreCell[] storeCells;
+
+    public void Display(int index)
+    {
+        var list = StoreModel.Instance.storeTypeDict[(int)StoreFunc.HeroSkin];
+
+        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/Store/SkinStoreLineCell.cs.meta b/Main/System/Store/SkinStoreLineCell.cs.meta
new file mode 100644
index 0000000..9a026b4
--- /dev/null
+++ b/Main/System/Store/SkinStoreLineCell.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 18ea07617fb14de4194068886378aa5c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Store/SkinStoreWin.cs b/Main/System/Store/SkinStoreWin.cs
new file mode 100644
index 0000000..b9ff542
--- /dev/null
+++ b/Main/System/Store/SkinStoreWin.cs
@@ -0,0 +1,87 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class SkinStoreWin : UIBase
+{
+    [SerializeField] Button giftBtn;
+
+    [SerializeField] ScrollerController scroller;
+
+   
+
+    protected override void InitComponent()
+    {
+        giftBtn.AddListener(() =>
+        {
+            UIManager.Instance.OpenWindow<HeroSkinGiftWin>();
+        });
+
+    }
+
+
+    protected override void OnPreOpen()
+    {
+        scroller.OnRefreshCell += OnRefreshCell;
+        StoreModel.Instance.RefreshShopEvent += Show;
+        StoreModel.Instance.RefreshBuyShopLimitEvent += Show;
+        
+        Display();
+    }
+
+    protected override void OnPreClose()
+    {
+        scroller.OnRefreshCell -= OnRefreshCell;
+        StoreModel.Instance.RefreshShopEvent -= Show;
+        StoreModel.Instance.RefreshBuyShopLimitEvent -= Show;
+    }
+
+    void Display()
+    {
+        CreateScroller();
+    }
+
+    void Show()
+    {
+        scroller.m_Scorller.RefreshActiveCellViews();
+    }
+
+    void CreateScroller()
+    {
+        if (!StoreModel.Instance.storeTypeDict.ContainsKey((int)StoreFunc.HeroSkin))
+        {
+            return;
+        }
+
+        int jumpIndex = -1;
+        scroller.Refresh();
+        var list = StoreModel.Instance.storeTypeDict[(int)StoreFunc.HeroSkin];
+        for (int i = 0; i < list.Count; i++)
+        {
+            if (i % 4 == 0)
+            {
+                scroller.AddCell(ScrollerDataType.Header, i);
+            }
+            if (jumpIndex == -1 && list[i].shopId == StoreModel.Instance.jumpShopID)
+            {
+                jumpIndex = i / 4;
+            }
+        }
+        scroller.Restart();
+        scroller.lockType = EnhanceLockType.KeepVertical;
+        if (StoreModel.Instance.jumpShopID != 0)
+        {
+            scroller.JumpIndex(jumpIndex);
+            StoreModel.Instance.jumpShopID = 0;
+        }
+    }
+
+
+    void OnRefreshCell(ScrollerDataType type, CellView cell)
+    {
+        var _cell = cell as SkinStoreLineCell;
+        _cell.Display(cell.index);
+    }
+
+
+}
diff --git a/Main/System/Store/SkinStoreWin.cs.meta b/Main/System/Store/SkinStoreWin.cs.meta
new file mode 100644
index 0000000..04a3853
--- /dev/null
+++ b/Main/System/Store/SkinStoreWin.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 08c36714c5911864e87b2fa0f2d78eeb
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/Store/StoreBaseWin.cs b/Main/System/Store/StoreBaseWin.cs
index 520359e..13bc603 100644
--- a/Main/System/Store/StoreBaseWin.cs
+++ b/Main/System/Store/StoreBaseWin.cs
@@ -15,6 +15,10 @@
                 currentSubUI = await UIManager.Instance.OpenWindowAsync<StoreWin>();
                 break;
             case 1:
+                //鏃惰
+                currentSubUI = UIManager.Instance.OpenWindow<SkinStoreWin>();
+                break;
+            case 2:
                 // 鍏呭�肩晫闈�
                 currentSubUI = await UIManager.Instance.OpenWindowAsync<RechargeWin>();
                 break;
diff --git a/Main/System/Store/StoreCell.cs b/Main/System/Store/StoreCell.cs
index 851e1e6..3e16457 100644
--- a/Main/System/Store/StoreCell.cs
+++ b/Main/System/Store/StoreCell.cs
@@ -87,7 +87,14 @@
             freeButton.SetActive(false);
             lockTip.text = "";
 
-            priceIcon.SetIconWithMoneyType(storeData.storeConfig.MoneyType);
+            if (storeData.storeConfig.MoneyType <= 0)
+            {
+                priceIcon.SetItemSprite(storeData.storeConfig.CostItemID);
+            }
+            else
+            {
+                priceIcon.SetIconWithMoneyType(storeData.storeConfig.MoneyType);
+            }
             priceText.text = storeData.storeConfig.MoneyNum.ToString();
 
             if (storeData.storeConfig.MoneyOriginal == 0)
diff --git a/Main/System/Store/StoreModel.cs b/Main/System/Store/StoreModel.cs
index 4214b94..32856e4 100644
--- a/Main/System/Store/StoreModel.cs
+++ b/Main/System/Store/StoreModel.cs
@@ -41,6 +41,8 @@
     public Dictionary<int, List<int>> freeShopDict = new Dictionary<int, List<int>>();  //鍏嶈垂鍟嗗搧 鍟嗗簵绫诲瀷锛氬晢鍝佸垪琛�
     public Dictionary<int, int> shopMoneyTypeDict = new Dictionary<int, int>();
 
+
+
     public override void Init()
     {
         FuncOpen.Instance.OnFuncStateChangeEvent += FuncStateChange;
@@ -362,14 +364,28 @@
 
     public void SendBuyShopItem(StoreConfig model, int count)
     {
-        if (UIHelper.CheckMoneyCount(model.MoneyType, model.MoneyNum * count, 2))
+        if (model.MoneyType <= 0)
         {
-            CA310_tagCSBuyItem buyShop = new CA310_tagCSBuyItem();
-            buyShop.ShopID = (ushort)model.ID;
-            buyShop.BuyCount = (uint)count;
-            GameNetSystem.Instance.SendInfo(buyShop);
+            if (UIHelper.CheckItemCount(model.CostItemID, model.MoneyNum * count, 2))
+            {
+                SendBuyItem(model.ID, count);
+            }
         }
+        else
+        {
+            if (UIHelper.CheckMoneyCount(model.MoneyType, model.MoneyNum * count, 2))
+            {
+                SendBuyItem(model.ID, count);
+            }
+        }
+    }
 
+    public void SendBuyItem(int shopID, int count)
+    {
+        CA310_tagCSBuyItem buyShop = new CA310_tagCSBuyItem();
+        buyShop.ShopID = (ushort)shopID;
+        buyShop.BuyCount = (uint)count;
+        GameNetSystem.Instance.SendInfo(buyShop);
     }
 
     //璐у竵璐拱鐨勪簩娆$‘璁ゆ鐨勭‘璁よ褰�
@@ -392,16 +408,21 @@
             return;
         }
 
-        ConfirmCancel.ToggleConfirmCancel(Language.Get("Mail101"), Language.Get("BuyStoreItem", model.MoneyNum, model.MoneyType, model.Name),
-        Language.Get("ConfirmCancel102"), (bool isOk, bool isToggle) =>
-        {
-            if (isOk)
+        ConfirmCancel.ToggleConfirmCancel(
+            Language.Get("Mail101"),
+            model.MoneyType <= 0 ?
+                Language.Get("BuyStoreItem1", model.MoneyNum, ItemConfig.Get(model.CostItemID).ItemName, model.Name) :
+                Language.Get("BuyStoreItem", model.MoneyNum, model.MoneyType, model.Name),
+            Language.Get("ConfirmCancel102"),
+            (isOk, isToggle) =>
             {
-                SendBuyShopItem(model, count);
-                buyItemCheckDict[eventType] = isToggle;
-            }
-            
-        });
+                if (isOk)
+                {
+                    SendBuyShopItem(model, count);
+                    buyItemCheckDict[eventType] = isToggle;
+                }
+
+            });
     }
 
     //鑺变粰鐜夎喘涔扮殑浜屾纭妗�(鏈鐧诲綍)
@@ -562,6 +583,30 @@
         }
         return true;
     }
+
+    // 寮瑰嚭璐拱妗嗭紝涓嶈冻鍒欐彁绀哄凡鍞絼
+    public void ShowBuyItem(int shopID, int tipType = 0)
+    {
+        var cfg = StoreConfig.Get(shopID);
+        if (!TryGetIsSellOut(cfg, out var cnt))
+        {
+            buyShopID = shopID;
+            UIManager.Instance.OpenWindow<BuyItemWin>();
+        }
+        else
+        {
+            if (tipType == 0)
+            {
+                //鍞絼
+                SysNotifyMgr.Instance.ShowTip("StoreTip1");
+            }
+            else if (tipType == 1)
+            {
+                //鐗╁搧涓嶈冻鎻愮ず
+                SysNotifyMgr.Instance.ShowTip("ItemNotEnough", ItemConfig.Get(cfg.ItemID).ItemName);
+            }
+        }
+    }
 }
 
 public enum StoreFunc
@@ -576,6 +621,11 @@
     DailySpecialsFree = 8, //8: 姣忔棩鐗规儬-姣忔棩鐗规儬鍏嶈垂
     DailyGiftFree = 9, //9: 姣忔棩鐗规儬-姣忔棩绀煎寘鍏嶈垂
     WeeklyGiftFree = 10, //10: 姣忔棩鐗规儬-姣忓懆绀煎寘鍏嶈垂
+    HeroSkin = 16, //16: 鏃惰鍟嗗簵
+    OSBeautyMM = 17, //17: 绾㈤鍐叉绀煎寘
+    OSHeroTrain = 18, //18: 姝﹀皢鍐叉绀煎寘
+    OSMingge = 19, //19: 鍛芥牸鍐叉绀煎寘
+    Qunying = 20, //20: 缇よ嫳绉垎鍟嗗簵
 }
 
 
diff --git a/Main/System/SystemSetting/SystemSetting.cs b/Main/System/SystemSetting/SystemSetting.cs
index fdc9e4f..94f1b4a 100644
--- a/Main/System/SystemSetting/SystemSetting.cs
+++ b/Main/System/SystemSetting/SystemSetting.cs
@@ -51,6 +51,7 @@
     public void SetSoundEffect(float value)
     {
         LocalSave.SetFloat(SOUND_EFFECT_KEY, Mathf.Clamp01(value));
+        EventBroadcast.Instance.Broadcast(EventName.SOUND_EFFECT_VOLUME_CHANGE, value);
     }
 
     public float GetSoundEffect()
@@ -73,6 +74,7 @@
     {
         LocalSave.SetBool(MUTE_SOUND_EFFECT_KEY, _mute);
         SoundPlayer.Instance.MuteSoundEffect(_mute);
+        EventBroadcast.Instance.Broadcast(EventName.SOUND_EFFECT_MUTE_CHANGE, _mute);
     }
 
     public bool GetMuteSoundEffect()
diff --git a/Main/System/TianziBillborad/TianziBillboradWin.cs b/Main/System/TianziBillborad/TianziBillboradWin.cs
index b256bed..336cb9a 100644
--- a/Main/System/TianziBillborad/TianziBillboradWin.cs
+++ b/Main/System/TianziBillborad/TianziBillboradWin.cs
@@ -85,6 +85,7 @@
     protected override void OnPreOpen()
     {
         base.OnPreOpen();
+        AdsManager.Instance.LoadAds();
         model.UpdateTianziKYInfoExent += OnUpdateTianziKYInfoExent;
         dungeonModel.UpdateFBInfoListEvent += OnUpdateFBInfoListEvent;
         adsModel.OnAdsInfoListUpdateEvent += OnAdsInfoListUpdateEvent;
diff --git a/Main/System/TimeRush/TimeRushGiftCell.cs b/Main/System/TimeRush/TimeRushGiftCell.cs
index 68e12f2..10944a6 100644
--- a/Main/System/TimeRush/TimeRushGiftCell.cs
+++ b/Main/System/TimeRush/TimeRushGiftCell.cs
@@ -3,6 +3,11 @@
 
 public class TimeRushGiftCell : MonoBehaviour
 {
+    [SerializeField] ImageEx vipImage;
+    [SerializeField] TextEx vipText;
+    [SerializeField] OutlineEx vipTextOutline;
+    [SerializeField] ImageEx rateImage;
+    [SerializeField] TextEx rateText;
     [SerializeField] TextEx titleText;
     [SerializeField] ItemCell[] itemCells;
     [SerializeField] ButtonEx buyButton;
@@ -34,6 +39,8 @@
         buyText.SetActive(true);
         buyText1.SetActive(false);
         moneyIconImage.SetActive(false);
+        rateImage.SetActive(true);
+
 
         if (!RechargeManager.Instance.TryGetOrderInfo(ctgId, out var orderConfig))
             return;
@@ -46,15 +53,44 @@
 
         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);
+        }
+
+        rateText.text = Language.Get("DailySpecials07", config.Percentage);
+
         bool isCanBuy = manager.IsCanBuyCTG(ctgId);
         titleText.text = config.Title;
         buyImage.SetSprite(isCanBuy ? "DailySpecialsBuy1" : "DailySpecialsBuy2");
-        buyText.text = !isCanBuy ? Language.Get("storename11") : Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderConfig.PayRMBNum));
+        buyText.text = !isCanBuy ? Language.Get("storename11") : Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderConfig.PayRMBNumOnSale));
         limitCountText.SetActive(true);
         limitCountText.text = Language.Get("TimeRush07", UIHelper.AppendColor(rechargeCount.totalCount >= config.TotalBuyCount ? TextColType.Red : TextColType.LightGreen, Mathf.Max(0, config.TotalBuyCount - rechargeCount.totalCount).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);
         });
 
@@ -80,6 +116,8 @@
 
     private void DisplayStore(int id)
     {
+        rateImage.SetActive(false);
+        vipImage.SetActive(false);
         if (!StoreConfig.HasKey(id))
             return;
         StoreConfig storeConfig = StoreConfig.Get(id);
diff --git a/Main/System/TimeRush/TimeRushManager.cs b/Main/System/TimeRush/TimeRushManager.cs
index 70eb289..b6ed1e5 100644
--- a/Main/System/TimeRush/TimeRushManager.cs
+++ b/Main/System/TimeRush/TimeRushManager.cs
@@ -6,8 +6,6 @@
 
 public class TimeRushManager : GameSystemManager<TimeRushManager>, IOpenServerActivity
 {
-
-
     public Action PlayAnimationSync;
 
     private bool isPlayAnimation = false;
@@ -28,10 +26,10 @@
         }
     }
 
-    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_Activity2;
+    public const int activityType = (int)OpenServerActivityCenter.ActivityType.AT_DateActivity;
     public const int activityID = (int)NewDayActivityID.TimeRushAct;
     public int actNum = 10;
-    public static OperationType operaType = OperationType.default47;
+    public static OperationType operaType = OperationType.TimeRush;
     public Redpoint redPoint = new Redpoint(MainRedDot.TimeRushRepoint);
 
     public bool IsOpen => OperationTimeHepler.Instance.SatisfyOpenCondition(operaType);
diff --git a/Main/System/TimeRush/TimeRushTaskCell.cs b/Main/System/TimeRush/TimeRushTaskCell.cs
index 18dac4a..b6e57f7 100644
--- a/Main/System/TimeRush/TimeRushTaskCell.cs
+++ b/Main/System/TimeRush/TimeRushTaskCell.cs
@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using DG.Tweening;
 using UnityEngine;
 
 public class TimeRushTaskCell : MonoBehaviour
@@ -10,7 +11,18 @@
     [SerializeField] TextEx sliderText;
     [SerializeField] ItemCell[] itemCells;
     [SerializeField] ImageEx[] grays;
-    [SerializeField] RotationTween[] tweens;
+
+    [SerializeField] RectTransform[] tweenTargets;
+    
+    [SerializeField, Tooltip("鍗曡竟鎽嗗姩鐨勫熀纭�鑰楁椂(绉�)")] 
+    float timeMultiplier = 0.5f;
+    
+    [SerializeField, Tooltip("涓�杞憜鍔ㄧ粨鏉熷悗鐨勫仠椤跨鏁�")] 
+    float pauseDuration = 0.2f; 
+    
+    [SerializeField, Tooltip("宸﹀彸鎽囨憜鐨勬渶澶ф棆杞搴�")] 
+    float shakeAngle = 15f; 
+
     [SerializeField] UIEffectPlayer uiEffectPlayer;
 
     int awardIndex;
@@ -18,76 +30,24 @@
     int tabType;
     TimeRushManager manager { get { return TimeRushManager.Instance; } }
 
-    private void OnEnable()
-    {
-        manager.PlayAnimationSync += OnPlaySyncAnimation;
-        for (int i = 0; i < tweens.Length; i++)
-        {
-            tweens[i].Stop();
-            tweens[i].SetStartState();
-        }
-
-        if (!manager.TryGetOperationInfo(out var act))
-            return;
-        if (!act.TryGetRoundInfoByIndex(roundType, awardIndex, out var awardInfo, out int listIndex) || awardInfo.AwardItemList == null)
-            return;
-        int state = manager.GetAwardState(roundType, awardIndex);
-        for (int i = 0; i < tweens.Length; i++)
-        {
-            if (i < awardInfo.AwardItemList.Length)
-            {
-                if (state == 1)
-                {
-                    tweens[i].Play();
-                }
-            }
-        }
-
-    }
-
-    private void OnDisable()
-    {
-        manager.PlayAnimationSync -= OnPlaySyncAnimation;
-    }
-
-    private void OnPlaySyncAnimation()
-    {
-        if (tabType != 1)
-            return;
-        for (int i = 0; i < tweens.Length; i++)
-        {
-            tweens[i].Stop();
-            tweens[i].SetStartState();
-        }
-        if (!manager.TryGetOperationInfo(out var act))
-            return;
-        if (!act.TryGetRoundInfoByIndex(roundType, awardIndex, out var awardInfo, out int listIndex) || awardInfo.AwardItemList == null)
-            return;
-        int state = manager.GetAwardState(roundType, awardIndex);
-        for (int i = 0; i < tweens.Length; i++)
-        {
-            if (tweens[i].isActiveAndEnabled && state == 1)
-            {
-                tweens[i].Play();
-            }
-        }
-    }
-
     public void Display(int index, CellView cell, List<HAA88_tagMCActLunhuidianInfo.tagMCActLunhuidianAward> taskList)
     {
-
         roundType = cell.info.Value.infoInt1;
         tabType = cell.info.Value.infoInt2;
         if (taskList.IsNullOrEmpty() || index < 0 || index >= taskList.Count)
             return;
+
         var task = taskList[index];
         awardIndex = task.AwardIndex;
+
         if (!manager.TryGetOperationInfo(out var act))
             return;
         if (!act.TryGetRound(roundType, out var round))
             return;
         if (!manager.TryGetPlayerInfo(roundType, out var playerInfo))
             return;
+        RefreshAnimations();
+
         int state = manager.GetAwardState(roundType, awardIndex);
         maskImage.SetActive(state == 2);
         uiEffectPlayer.SetActive(state == 1);
@@ -133,4 +93,67 @@
         });
     }
 
-}
+    private void OnEnable()
+    {
+        manager.PlayAnimationSync += OnPlaySyncAnimation;
+        RefreshAnimations();
+    }
+
+    private void OnDisable()
+    {
+        manager.PlayAnimationSync -= OnPlaySyncAnimation;
+        StopAllTweens();
+    }
+
+    private void OnPlaySyncAnimation()
+    {
+        if (tabType != 1) return;
+        RefreshAnimations();
+    }
+
+    // 缁熶竴澶勭悊鍔ㄧ敾鐨勫埛鏂板拰鍚姩
+    private void RefreshAnimations()
+    {
+        StopAllTweens();
+
+        if (!manager.TryGetOperationInfo(out var act)) return;
+        if (!act.TryGetRoundInfoByIndex(roundType, awardIndex, out var awardInfo, out int listIndex) || awardInfo.AwardItemList == null) return;
+
+        int state = manager.GetAwardState(roundType, awardIndex);
+
+        for (int i = 0; i < tweenTargets.Length; i++)
+        {
+            if (i < awardInfo.AwardItemList.Length && tweenTargets[i].gameObject.activeInHierarchy && state == 1)
+            {
+                PlayShakeAnimation(tweenTargets[i]);
+            }
+        }
+    }
+
+    // 瀹夊叏鍋滄鎵�鏈夊姩鐢诲苟閲嶇疆鐘舵��
+    private void StopAllTweens()
+    {
+        // 褰诲簳娓呯悊 DOTween 鐘舵�佸苟鍥炴
+        for (int i = 0; i < tweenTargets.Length; i++)
+        {
+            if (tweenTargets[i] != null)
+            {
+                tweenTargets[i].DOKill();
+                tweenTargets[i].localEulerAngles = Vector3.zero;
+            }
+        }
+    }
+
+    private void PlayShakeAnimation(RectTransform target)
+    {
+        Sequence shakeSequence = DOTween.Sequence();
+
+        shakeSequence.Append(target.DOLocalRotate(new Vector3(0, 0, -shakeAngle), timeMultiplier * 1).SetEase(Ease.Linear))
+                     .Append(target.DOLocalRotate(new Vector3(0, 0, shakeAngle), timeMultiplier * 2).SetEase(Ease.Linear))
+                     .Append(target.DOLocalRotate(new Vector3(0, 0, -shakeAngle), timeMultiplier * 2).SetEase(Ease.Linear))
+                     .Append(target.DOLocalRotate(Vector3.zero, timeMultiplier * 1).SetEase(Ease.Linear))
+                     .AppendInterval(pauseDuration);  // 娣诲姞鍋滈】
+        shakeSequence.SetLoops(-1);
+        shakeSequence.SetTarget(target);
+    }
+}
\ No newline at end of file
diff --git a/Main/System/TimeRush/TimeRushWin.cs b/Main/System/TimeRush/TimeRushWin.cs
index 5926123..a75d4c2 100644
--- a/Main/System/TimeRush/TimeRushWin.cs
+++ b/Main/System/TimeRush/TimeRushWin.cs
@@ -76,7 +76,7 @@
 
     private void OperationTimeUpdateEvent(OperationType operation)
     {
-        if (operation == OperationType.default47)
+        if (operation == OperationType.TimeRush)
         {
             var list = manager.GetTabIDList();
             if (list.IsNullOrEmpty())
@@ -109,13 +109,13 @@
     {
         var _cell = cell.GetComponent<TimeRushTaskCell>();
         _cell?.Display(cell.index, cell, taskList);
+        manager.PlayAnimationSync?.Invoke();
     }
 
     private void OnRefreshGiftCell(ScrollerDataType type, CellView cell)
     {
         var _cell = cell.GetComponent<TimeRushGiftCell>();
         _cell?.Display(cell.index, giftItems);
-        manager.PlayAnimationSync?.Invoke();
     }
 
     private void OnNowTabIdChangeEvent()
diff --git a/Main/System/TimingGift/TimingGiftCtgIdCell.cs b/Main/System/TimingGift/TimingGiftCtgIdCell.cs
index 6ec54b3..0f3f40f 100644
--- a/Main/System/TimingGift/TimingGiftCtgIdCell.cs
+++ b/Main/System/TimingGift/TimingGiftCtgIdCell.cs
@@ -13,7 +13,7 @@
         int ctgId = ctgIds[index];
         if (!RechargeManager.Instance.TryGetOrderInfo(ctgId, out var orderInfoConfig))
             return;
-        moneyText.text = Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale);
+        moneyText.text = Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfoConfig.PayRMBNumOnSale));
 
         bool isChoose = manager.selectCtgIdIndex == index;
         tabIcon.SetSprite(isChoose ? "TimingGiftTab2_Select" : "TimingGiftTab2_UnSelect");
diff --git a/Main/System/TimingGift/TimingGiftWin.cs b/Main/System/TimingGift/TimingGiftWin.cs
index 8ddc17d..817549a 100644
--- a/Main/System/TimingGift/TimingGiftWin.cs
+++ b/Main/System/TimingGift/TimingGiftWin.cs
@@ -250,7 +250,7 @@
         giftText.SetVerticalGradient(manager.GetColor32(config.TopColor), manager.GetColor32(config.BottomColor));
         giftTextOutline.OutlineColor = manager.GetColor32(config.OutlineColor);
         bool isBuy = manager.IsBuy(manager.selectCtgId);
-        buyText.text = !isBuy ? Language.Get("PayMoneyNum", orderInfoConfig.PayRMBNumOnSale) : Language.Get("L1133");
+        buyText.text = !isBuy ? Language.Get("PayMoneyNum", UIHelper.GetMoneyFormat(orderInfoConfig.PayRMBNumOnSale)) : Language.Get("L1133");
         buyImage.SetSprite(isBuy ? "TimingGiftBuy" : "TimingGiftNoBuy");
         buyImage.raycastTarget = !isBuy;
         RefreshTime();
diff --git a/Main/System/Tip/ConfirmCancel.cs b/Main/System/Tip/ConfirmCancel.cs
index 84a374c..c23713d 100644
--- a/Main/System/Tip/ConfirmCancel.cs
+++ b/Main/System/Tip/ConfirmCancel.cs
@@ -268,7 +268,6 @@
     public static int moneyNeedCount;
 
     public static List<Item> getItems { get; private set; }
-    public static string replaceItemName;
     /// <summary>
     /// 澶氱墿鍝佸睍绀虹‘璁ゆ
     /// </summary>
@@ -281,7 +280,7 @@
     /// <param name="moneyCnt"></param>
     /// <param name="type"></param>
     public static void ShowItemsConfirm(List<Item> items, string tiltle, string info, Action<bool> func,
-        string info2 = "", string btnText = "", int moneyCnt = 0, int type = 0, string itemName = "")
+        string info2 = "", string btnText = "", int moneyCnt = 0, int type = 0)
     {
         getItems = items;
         generalTitle = tiltle;
@@ -291,7 +290,6 @@
         OnPopConfirmClickEvent = func;
         moneyType = type;
         moneyNeedCount = moneyCnt;
-        replaceItemName = itemName;
         if (!UIManager.Instance.IsOpened<ItemsConfirmWin>())
         {
             UIManager.Instance.OpenWindowAsync<ItemsConfirmWin>().Forget();
diff --git a/Main/System/Tip/ItemsConfirmCell.cs b/Main/System/Tip/ItemsConfirmCell.cs
index 9415abc..253f270 100644
--- a/Main/System/Tip/ItemsConfirmCell.cs
+++ b/Main/System/Tip/ItemsConfirmCell.cs
@@ -5,15 +5,21 @@
 {
     [SerializeField] ItemCell itemCell;
     [SerializeField] Text itemName;
+    [SerializeField] Image sourceImg;
 
-    public void Display(int index, string replaceItemName)
+    public void Display(int index)
     {
-        int itemID = ConfirmCancel.getItems[index].id;
-        itemCell.Init(new ItemCellModel(itemID, false, ConfirmCancel.getItems[index].countEx));
+        var item = ConfirmCancel.getItems[index];
+        int itemID = item.id;
+        itemCell.Init(new ItemCellModel(itemID, false, item.countEx));
         itemCell.button.SetListener(() =>
         {
             ItemTipUtility.Show(itemID);
         });
-        itemName.text = string.IsNullOrEmpty(replaceItemName) ? ItemConfig.Get(itemID).ItemName : replaceItemName;
+        itemName.text = string.IsNullOrEmpty(item.dataEx) ? ItemConfig.Get(itemID).ItemName : item.dataEx;
+
+        sourceImg.SetActive(item.useType != 0);
+        sourceImg.SetSprite($"AwardMark{item.useType}");
+        sourceImg.SetNativeSize();
     }
 }
diff --git a/Main/System/Tip/ItemsConfirmWin.cs b/Main/System/Tip/ItemsConfirmWin.cs
index f4b53d0..50df629 100644
--- a/Main/System/Tip/ItemsConfirmWin.cs
+++ b/Main/System/Tip/ItemsConfirmWin.cs
@@ -76,7 +76,7 @@
     void OnRefreshCell(ScrollerDataType type, CellView cell)
     {
         var _cell = cell as ItemsConfirmCell;
-        _cell?.Display(cell.index, ConfirmCancel.replaceItemName);
+        _cell?.Display(cell.index);
     }
 
     void CreateScroller()
diff --git a/Main/System/UIBase/OneLevelWin.cs b/Main/System/UIBase/OneLevelWin.cs
index 72007b9..cc1df7a 100644
--- a/Main/System/UIBase/OneLevelWin.cs
+++ b/Main/System/UIBase/OneLevelWin.cs
@@ -55,6 +55,7 @@
             GameObject go = Instantiate(tabBtn.gameObject, btnParent);
             var data = funcBtnDatas[i];
             tabButtons[i] = go.GetComponent<GroupButtonEx>();
+            tabButtons[i].name = $"funcbtn{i}";
             tabButtons[i].selectIcon.SetSprite(data.iconName);
             tabButtons[i].selectIcon.SetNativeSize();
             tabButtons[i].unSelectIcon.SetSprite(data.unSelectIconName);
diff --git a/Main/System/UIBase/UIBase.cs b/Main/System/UIBase/UIBase.cs
index b4e444f..0444e74 100644
--- a/Main/System/UIBase/UIBase.cs
+++ b/Main/System/UIBase/UIBase.cs
@@ -127,7 +127,8 @@
         }
         catch (Exception e)
         {
-            Debug.LogError($"{uiName}鐣岄潰鐨処nitComponentInternal鎶ラ敊: message: {e.Message} \nStackTrace: {e.StackTrace}");
+            Debug.LogError($"{uiName}鐣岄潰鐨処nitComponentInternal鎶ラ敊: {e.StackTrace}");
+            OperationLogCollect.Instance.BugReportSys(e.ToString(), "10002");
         }
 
         try
@@ -136,7 +137,8 @@
         }
         catch (Exception e)
         {
-            Debug.LogError($"{uiName}鐣岄潰鐨処nitComponent鎶ラ敊: message: {e.Message} \nStackTrace: {e.StackTrace}");
+            Debug.LogError($"{uiName}鐣岄潰鐨処nitComponent鎶ラ敊: {e.StackTrace}");
+            OperationLogCollect.Instance.BugReportSys(e.ToString(), "10002");
         }
 
         // 淇濆瓨鍘熷鍊肩敤浜庡姩鐢�
@@ -144,8 +146,9 @@
         {
             if (Screen.height / Screen.width > 1.8)//瀹藉睆闇�瑕侀�傞厤
             {
-                _rectTransform.offsetMax = new Vector2(0, -SafeHeightUp);   //涓�
-                _rectTransform.offsetMin = new Vector2(0, SafeHeightDown);  //涓�
+                //涓婁笅鍚勯棿闅擲afeWidth
+                _rectTransform.offsetMax = new Vector2(0, -SafeHeightUp);  //涓�
+                _rectTransform.offsetMin = new Vector2(0, SafeHeightDown);   //涓�
             }
             originalPosition = _rectTransform.anchoredPosition;
         }
@@ -175,7 +178,6 @@
         {
             //寤惰繜x甯у悗鍙偣鍑�,闃叉鐐瑰嚮杩囧揩绔嬪嵆鍏抽棴浜�
             await UniTask.Delay(200);
-            if (this == null) return; // destroyed during await
             btnClickEmptyClose.enabled = true;
         }
     }
@@ -204,10 +206,10 @@
         btnClickEmptyClose.enabled = false;
     }
 
+
     protected async void ExecuteNextFrame(Action _action)
     {
         await UniTask.DelayFrame(1);
-        if (this == null) return; // destroyed during await
         _action?.Invoke();
     }
 
@@ -272,10 +274,7 @@
     // 璁剧疆UI灞傜骇
     public void SetSortingOrder(int order)
     {
-        if (canvas == null)
-            canvas = GetComponent<Canvas>();
-        if (canvas != null)
-            canvas.sortingOrder = order;
+        canvas.sortingOrder = order;
     }
 
     protected virtual void OnPreOpen()
@@ -309,7 +308,8 @@
         }
         catch (Exception e)
         {
-            Debug.LogError($"{uiName}鐣岄潰鐨凮nPreOpen鎶ラ敊: message: {e.Message} \nStackTrace: {e.StackTrace}");
+            Debug.LogError($"{uiName}鐣岄潰鐨凮nPreOpen鎶ラ敊: {e.StackTrace}");
+            OperationLogCollect.Instance.BugReportSys(e.ToString(), "10002");
         }
 
         StopCurrentAnimation();
@@ -330,15 +330,11 @@
         }
         catch (Exception e)
         {
-            Debug.LogError($"{uiName}鐣岄潰鐨凮nOpen鎶ラ敊: message: {e.Message} \nStackTrace: {e.StackTrace}");
+            Debug.LogError($"{uiName}鐣岄潰鐨凮nOpen鎶ラ敊: {e.StackTrace}");
+            OperationLogCollect.Instance.BugReportSys(e.ToString(), "10002");
         }
 
-        ApplyClickEmptySpaceClose().Forget();
-
-#if UNITY_WEBGL
-        // WebGL 璇婃柇锛氭娴� Image 缁勪欢鐨� sprite 鏄惁涓� null
-        DiagCheckImageSprites();
-#endif
+        ApplyClickEmptySpaceClose();
 
         ExecuteNextFrame(() =>
         {
@@ -352,7 +348,8 @@
             }
             catch (Exception e)
             {
-                Debug.LogError($"{uiName}鐣岄潰鐨凬extFrameAfterOpen鎶ラ敊: message: {e.Message} \nStackTrace: {e.StackTrace}");
+                Debug.LogError($"{uiName}鐣岄潰鐨凬extFrameAfterOpen鎶ラ敊: {e.StackTrace}");
+                OperationLogCollect.Instance.BugReportSys(e.ToString(), "10002");
             }
         });
     }
@@ -361,75 +358,6 @@
     {
 
     }
-
-#if UNITY_WEBGL
-    /// <summary>
-    /// WebGL 璇婃柇锛氭娴嬫墍鏈� Image 瀛愮粍浠剁殑 sprite 鐘舵�併��
-    /// 鐢ㄤ簬鎺掓煡 WebGL 鏋勫缓涓� Image 璧勬簮涓㈠け鐨勯棶棰樸��
-    /// </summary>
-    private void DiagCheckImageSprites()
-    {
-        var images = GetComponentsInChildren<Image>(true);
-        int nullCount = 0;
-        int totalCount = images.Length;
-        var sb = new System.Text.StringBuilder();
-
-        foreach (var img in images)
-        {
-            if (img.sprite == null && img.overrideSprite == null)
-            {
-                // 璺宠繃 Color-only 鎴� mask 鐢ㄩ�旂殑 Image锛堟棤闇� sprite锛�
-                if (img.type == Image.Type.Simple && img.color.a < 0.01f)
-                    continue;
-
-                nullCount++;
-                string path = GetTransformPath(img.transform);
-                sb.AppendLine($"  [NULL sprite] {path} (type={img.type}, raycast={img.raycastTarget})");
-            }
-        }
-
-        var rawImages = GetComponentsInChildren<RawImage>(true);
-        int rawNullCount = 0;
-        foreach (var ri in rawImages)
-        {
-            if (ri.texture == null)
-            {
-                rawNullCount++;
-                string path = GetTransformPath(ri.transform);
-                sb.AppendLine($"  [NULL texture] RawImage: {path}");
-            }
-        }
-
-        if (nullCount > 0 || rawNullCount > 0)
-        {
-            Debug.LogWarning($"[UIBase][SpriteDiag] {uiName}: {nullCount}/{totalCount} Image sprites NULL, {rawNullCount} RawImage textures NULL\n{sb}");
-        }
-        else
-        {
-            Debug.Log($"[UIBase][SpriteDiag] {uiName}: All {totalCount} Image sprites OK");
-        }
-
-        // 妫�鏌� Canvas 鐘舵��
-        if (canvas != null)
-        {
-            Debug.Log($"[UIBase][SpriteDiag] {uiName} Canvas: renderMode={canvas.renderMode}, worldCamera={(canvas.worldCamera != null ? canvas.worldCamera.name : "NULL")}, sortingOrder={canvas.sortingOrder}");
-        }
-    }
-
-    private string GetTransformPath(Transform t)
-    {
-        string path = t.name;
-        Transform parent = t.parent;
-        int depth = 0;
-        while (parent != null && parent != transform && depth < 10)
-        {
-            path = parent.name + "/" + path;
-            parent = parent.parent;
-            depth++;
-        }
-        return path;
-    }
-#endif
 
     // 鍏抽棴UI - 淇敼鍚庣殑鏂规硶
     public void HandleClose()
@@ -446,7 +374,8 @@
         }
         catch (Exception e)
         {
-            Debug.LogError($"{uiName}鐣岄潰鐨凮nPreClose鎶ラ敊: message: {e.Message} \nStackTrace: {e.StackTrace}");
+            Debug.LogError($"{uiName}鐣岄潰鐨凮nPreClose鎶ラ敊: {e.StackTrace}");
+            OperationLogCollect.Instance.BugReportSys(e.ToString(), "10002");
         }
 
         StopCurrentAnimation();
@@ -467,7 +396,8 @@
         }
         catch (Exception e)
         {
-            Debug.LogError($"{uiName}鐣岄潰鐨凮nClose鎶ラ敊: message: {e.Message} \nStackTrace: {e.StackTrace}");
+            Debug.LogError($"{uiName}鐣岄潰鐨凮nClose鎶ラ敊: {e.StackTrace}");
+            OperationLogCollect.Instance.BugReportSys(e.ToString(), "10002");
         }
 
         if (closeAnimationType == UIAnimationType.None)
@@ -478,7 +408,8 @@
             }
             catch (Exception e)
             {
-                Debug.LogError($"{uiName}鐣岄潰鐨凜ompleteClose鎶ラ敊: message: {e.Message} \nStackTrace: {e.StackTrace}");
+                Debug.LogError($"{uiName}鐣岄潰鐨凜ompleteClose鎶ラ敊: {e.StackTrace}");
+                OperationLogCollect.Instance.BugReportSys(e.ToString(), "10002");
             }
         }
         // 鍚﹀垯鍦ㄥ姩鐢诲畬鎴愬悗绂佺敤娓告垙瀵硅薄锛堝湪PlayCloseAnimation涓鐞嗭級
@@ -499,7 +430,6 @@
     public async UniTask DelayCloseWindow(int delayTime = 30)
     {
         await UniTask.Delay(delayTime);
-        if (this == null) return; // destroyed during await
         CloseWindow();
     }
 
@@ -564,6 +494,11 @@
     public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
     {
         return raycastTarget;
+    }
+
+    public CanvasGroup GetCanvasGroup()
+    {
+        return canvasGroup;
     }
 
     #region 鍔ㄧ敾鏂规硶
@@ -747,7 +682,8 @@
         }
         catch (System.Exception e)
         {
-            Debug.LogError($"鎾斁鎵撳紑鍔ㄧ敾鏃跺嚭閿�: message: {e.Message} \nStackTrace: {e.StackTrace}");
+            Debug.LogError($"鎾斁鎵撳紑鍔ㄧ敾鏃跺嚭閿�: {e.StackTrace}");
+            OperationLogCollect.Instance.BugReportSys(e.ToString(), "10002");
 
             // 鍑洪敊鏃剁‘淇漊I鍙骞跺彲浜や簰
             if (canvasGroup != null)
@@ -870,7 +806,8 @@
                     }
                     catch (Exception e)
                     {
-                        Debug.LogError($"{uiName}鐣岄潰鐨凜ompleteClose鎶ラ敊: message: {e.Message} \nStackTrace: {e.StackTrace}");
+                        Debug.LogError($"{uiName}鐣岄潰鐨凜ompleteClose鎶ラ敊: {e.StackTrace}");
+                        OperationLogCollect.Instance.BugReportSys(e.ToString(), "10002");
                     }
                 }
             });
@@ -879,7 +816,8 @@
         }
         catch (System.Exception e)
         {
-            Debug.LogError($"鎾斁鍏抽棴鍔ㄧ敾鏃跺嚭閿�: message: {e.Message} \nStackTrace: {e.StackTrace}");
+            Debug.LogError($"鎾斁鍏抽棴鍔ㄧ敾鏃跺嚭閿�: {e.StackTrace}");
+            OperationLogCollect.Instance.BugReportSys(e.ToString(), "10002");
             
             // 鍑洪敊鏃剁洿鎺ュ畬鎴愬叧闂�
             isAnimating = false;
diff --git a/Main/System/UIBase/UIJumpManager.cs b/Main/System/UIBase/UIJumpManager.cs
index d5ac708..0098864 100644
--- a/Main/System/UIBase/UIJumpManager.cs
+++ b/Main/System/UIBase/UIJumpManager.cs
@@ -9,8 +9,6 @@
 /// </summary>
 public class UIJumpManager : GameSystemManager<UIJumpManager>
 {
-
-
 	public override void Init()
 	{
 	}
@@ -22,11 +20,20 @@
 		{
 			return false;
 		}
-		if (config.FuncID !=0 && !FuncOpen.Instance.IsFuncOpen(config.FuncID, showTip))
+
+		if (config.FuncID != 0 && !FuncOpen.Instance.IsFuncOpen(config.FuncID, showTip))
 		{
 			return false;
 		}
 
+		if (config.ActiveType != 0 && !OperationTimeHepler.Instance.SatisfyOpenCondition((OperationType)config.ActiveType))
+		{
+			if (showTip)
+			{
+				SysNotifyMgr.Instance.ShowTip("ActivityNoOpen");
+			}
+			return false;
+		}
 		//娲诲姩鍚庣画琛ュ厖
 		return true;
 	}
@@ -41,15 +48,53 @@
 
 		if (config.WinName == "StoreBaseWin")
 		{
-			//鎸囧畾鍟嗗搧
-			StoreModel.Instance.jumpShopID = int.Parse(config.Extra);
-			if (StoreModel.Instance.jumpShopID == 0)
+			if (int.TryParse(config.Extra, out int result))
 			{
-				StoreModel.Instance.selectStoreFuncType = StoreFunc.Normal;
+				//鎸囧畾鍟嗗搧
+				StoreModel.Instance.jumpShopID = result;
+				if (StoreModel.Instance.jumpShopID == 0)
+				{
+					StoreModel.Instance.selectStoreFuncType = StoreFunc.Normal;
+				}
+				else
+				{
+					StoreModel.Instance.selectStoreFuncType = (StoreFunc)StoreConfig.Get(StoreModel.Instance.jumpShopID).ShopType;
+				}
 			}
-			else
+		}
+		else if (config.WinName == "HeroDebutCallWin" ||
+				config.WinName == "HeroDebutSkinWin" ||
+				config.WinName == "HeroDebutCheckInWin" ||
+				config.WinName == "HeroDebutGiftWin" ||
+				config.WinName == "HeroDebutShopWin")
+		{
+			var heroDebutAct = HeroDebutManager.Instance.GetOperationHeroAppearInfo();
+			if (heroDebutAct == null)
 			{
-				StoreModel.Instance.selectStoreFuncType = (StoreFunc)StoreConfig.Get(StoreModel.Instance.jumpShopID).ShopType;
+				SysNotifyMgr.Instance.ShowTip("ActivityNoOpen");
+				return;
+			}
+			var actHeroAppearConfig = ActHeroAppearConfig.Get(heroDebutAct.CfgID);
+			if (actHeroAppearConfig == null)
+			{
+				SysNotifyMgr.Instance.ShowTip("ActivityNoOpen");
+				return;
+			}
+
+			// 鐨偆鍟嗗簵闇�瑕佸垽鏂墿鍝両D
+			if (config.WinName == "HeroDebutSkinWin")
+			{
+				if (!HeroDebutManager.Instance.HasItemInSkinCTGIDList(heroDebutAct.CfgID, int.Parse(config.Extra)))
+				{
+					SysNotifyMgr.Instance.ShowTip("ActivityNoOpen");
+					return;
+				}
+			}
+
+			if (UIManager.Instance.IsOpened(config.WinName))
+			{
+				UIManager.Instance.CloseWindow(config.WinName);
+				UIManager.Instance.OpenWindow(config.WinName);
 			}
 		}
 
diff --git a/Main/System/ViewNPC/ViewBuffManager.cs b/Main/System/ViewNPC/ViewBuffManager.cs
new file mode 100644
index 0000000..ebda488
--- /dev/null
+++ b/Main/System/ViewNPC/ViewBuffManager.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using LitJson;
+
+public class ViewBuffManager : GameSystemManager<ViewBuffManager>
+{
+    public override void Init()
+    {
+        EventBroadcast.Instance.AddListener<BattleClickBuffData>(EventName.BATTLE_CLICK_BUFF, OnBattleClickBuff);
+    }
+
+    public override void Release()
+    {
+        EventBroadcast.Instance.RemoveListener<BattleClickBuffData>(EventName.BATTLE_CLICK_BUFF, OnBattleClickBuff);
+    }
+
+    public BattleClickBuffData currentBuffData;
+    private void OnBattleClickBuff(BattleClickBuffData data)
+    {
+        currentBuffData = data;
+        if (!UIManager.Instance.IsOpened<BuffInfoWin>())
+        {
+            UIManager.Instance.OpenWindow<BuffInfoWin>();
+        }
+    }
+}
+
+public struct BattleClickBuffData
+{
+    public bool isMySide;
+    public int heroID;
+    public int skinID;
+    public List<HB428_tagSCBuffRefresh> datas;
+}
\ No newline at end of file
diff --git a/Main/System/ViewNPC/ViewBuffManager.cs.meta b/Main/System/ViewNPC/ViewBuffManager.cs.meta
new file mode 100644
index 0000000..63853ad
--- /dev/null
+++ b/Main/System/ViewNPC/ViewBuffManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 544777c3539c4e3499b725ddc666a1ee
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Main/System/ViewNPC/ViewNPCManager.cs b/Main/System/ViewNPC/ViewNPCManager.cs
index f5a08d8..b04d735 100644
--- a/Main/System/ViewNPC/ViewNPCManager.cs
+++ b/Main/System/ViewNPC/ViewNPCManager.cs
@@ -68,7 +68,11 @@
             {
                 case BattleConst.ArenaBattleField:
                     int playerId = (int)ArenaManager.Instance.atkPlayerId;
-                    OtherPlayerDetailManager.Instance.ViewPlayerDetail(playerId, 0, (int)ViewPlayerType.viewArenaBattleEnemyHero, (int)BattlePreSetType.Arena);
+                    OtherPlayerDetailManager.Instance.ViewPlayerDetail(playerId, 0, (int)ViewPlayerType.viewPVPBattleEnemyHero, (int)BattlePreSetType.Arena);
+                    break;
+                case BattleConst.QYBattleField:
+                    playerId = (int)QunyingManager.Instance.atkPlayerId;
+                    OtherPlayerDetailManager.Instance.ViewPlayerDetail(playerId, 0, (int)ViewPlayerType.viewPVPBattleEnemyHero, (int)BattlePreSetType.Qunying);
                     break;
             }
             return;
@@ -90,13 +94,13 @@
     {
         switch (viewPlayerType)
         {
-            case (int)ViewPlayerType.viewArenaBattleEnemyHero:
-                ViewArenaBattleEnemyHero(playerID);
+            case (int)ViewPlayerType.viewPVPBattleEnemyHero:
+                ViewPVPBattleEnemyHero(playerID);
                 break;
         }
     }
 
-    private void ViewArenaBattleEnemyHero(int playerID)
+    private void ViewPVPBattleEnemyHero(int playerID)
     {
         int presetID = otherPlayerManager.GetFuncPresetID(playerID, OtherPlayerDetailManager.Instance.viewPreSetType, (int)FuncPresetType.Global);
         var heroList = otherPlayerManager.GetHeroDataSortList(playerID, presetID);
diff --git a/Main/Utility/DeviceUtility.cs b/Main/Utility/DeviceUtility.cs
index b44fb1f..86ad894 100644
--- a/Main/Utility/DeviceUtility.cs
+++ b/Main/Utility/DeviceUtility.cs
@@ -147,7 +147,7 @@
             switch (Application.platform)
             {
                 case RuntimePlatform.Android:
-                    _memory = 0; //TODO YL collect device memory //ynmbxxjUtil.Instance.Device.totalMemory;
+                    _memory = 0; 
                     break;
                 case RuntimePlatform.IPhonePlayer:
                     _memory = IsLowMemory() ? 1 : 2 * 1024;
diff --git a/Main/Utility/EnumHelper.cs b/Main/Utility/EnumHelper.cs
index 259009d..af301c5 100644
--- a/Main/Utility/EnumHelper.cs
+++ b/Main/Utility/EnumHelper.cs
@@ -713,6 +713,9 @@
     ChallengeVoucher = 286,//鎸戞垬鍑瘉
     DailySpecials = 287, //鐗规儬鍗扮欢
     OSGalaScore = 288, //寮�鏈嶅簡鍏哥Н鍒�
+    QunyingWDL = 289, //缇よ嫳闂紟浠�
+    QYScore = 290, //缇よ嫳绉垎
+    heroSkin = 291, // 鐢ㄤ簬鐨偆鍟嗗簵璐拱
 };
 
 
@@ -850,6 +853,11 @@
     FuncPreset = 56, //娴佹淳棰勮
     TimingGift = 57, //鏃舵満绀煎寘
     TimeRush = 58, //闄愭椂鍐插埡
+    OSHeroTrain = 59, //寮�鏈嶆灏嗗煿鍏绘娲诲姩
+    OSBeautyMM = 60, //寮�鏈嶇孩棰滄娲诲姩
+    OSMingge = 61, //寮�鏈嶅懡鏍煎煿鍏绘娲诲姩
+    Qunying = 62, //缇よ嫳姒�
+    HeroDebut = 63,//姝﹀皢鐧诲満
 }
 
 
@@ -1803,29 +1811,8 @@
 //OpenServerActivityCenter.ActivityType.AT_Activity2鐨勬椿鍔�  鍘嗗彶鍘熷洜涓嶈鐢�100
 public enum NewDayActivityID
 {
-    BossTrial = 200,    //boss鍑瘉
-    LoginAct = 201, //鐧诲綍娲诲姩
-    MissionAct = 202,   //浠诲姟娲诲姩
-    RechargeGiftAct = 203,  //鍏呭�肩ぜ鍖咃紙鍏呭�兼鏁板鍔憋級
-    CrossBossTrial = 204,   //璺ㄦ湇boss鍑瘉 蹇呴』鍜孊ossTrial 涓�璧�
-    FamilyRechargeConnAct = 205, //浠欑洘鍗忓姪
-    CustomizedGiftWin = 206, //鑷�夌ぜ鍖�
-    SecretPlaceXB = 207, //绉樺瀵诲疂
-    SecretPlaceXBCross = 208, //绉樺瀵诲疂 璺ㄦ湇
-    RechargeGiftAct31 = 209,  //鑷�夊厖鍊� + 鍟嗗簵绀煎寘
-    PetHorseAct = 210,  //瀹犵墿鍧愰獞娲诲姩
-    PetHorseActCross = 211,  //瀹犵墿鍧愰獞娲诲姩 璺ㄦ湇
-    TreasurePavilionAct = 212,  //鍙ゅ疂娲诲姩
-    TreasurePavilionActCross = 213,  //鍙ゅ疂娲诲姩 璺ㄦ湇
-    FairyAffinityLoginAct = 214,  //浠欑紭鐧婚檰娲诲姩
-    FairyAffinityMissionAct = 215,  //浠欑紭浠诲姟娲诲姩
-    FairyAffinityRechargeGiftAct = 216,  //浠欑紭绀煎寘娲诲姩
-    TimeRushAct = 217,  //杞洖娈挎椿鍔�
-    YunShiXBAct = 218,  //杩愬娍瀵诲疂娲诲姩
-    YunShiMissionAct = 219,  //杩愬娍浠诲姟娲诲姩
-    YunShiRechargeGiftAct = 220,  //杩愬娍绀煎寘娲诲姩
-    LianQiActCross = 221,    //浠欏尃澶т細娲诲姩 璺ㄦ湇
-    LianQiRechargeGiftActCross = 222, //浠欏尃澶т細绀煎寘娲诲姩 璺ㄦ湇
+    TimeRushAct = 200,  //杞洖娈�(姝﹀皢鍐插埡)
+    HeroDebutAct = 201,  //鑻遍泟鐧诲満娲诲姩
 }
 
 //浠欑帀璐拱鐨勪簩娆$‘璁ゆ绫诲瀷
@@ -1844,5 +1831,5 @@
 {
     viewPlayerData = 0,  //鏌ョ湅鐜╁鍩烘湰淇℃伅锛屽叕鐢ㄦ墦寮�鐣岄潰
     viewGuildLeader = 1,  //鏌ョ湅鐜╁鐨勫叕浼氭棌闀夸俊鎭�
-    viewArenaBattleEnemyHero = 2,  //鏌ョ湅绔炴妧鍦烘垬鏂楁晫鏂硅嫳闆勪俊鎭�
+    viewPVPBattleEnemyHero = 2,  //鏌ョ湅绔炴妧鍦烘垬鏂楁晫鏂硅嫳闆勪俊鎭�
 }
diff --git a/Main/Utility/OperationLogCollect.cs b/Main/Utility/OperationLogCollect.cs
index d260794..0b105ab 100644
--- a/Main/Utility/OperationLogCollect.cs
+++ b/Main/Utility/OperationLogCollect.cs
@@ -3,197 +3,82 @@
 using UnityEngine;
 using System;
 using LitJson;
-using Cysharp.Threading.Tasks;
 
 
 public class OperationLogCollect : Singleton<OperationLogCollect>
-
 {
-//     const string url = "http://xssgcenter.secondworld.net.cn:11000/event_receiver?";
 
-//     public void RecordLauchEvent(int _step)
-//     {
-//         return;
-// #if !UNITY_EDITOR
-//         if (config.versionAuthority == VersionAuthority.Release)
-//         {
-//             var tables = new Dictionary<string, string>();
-//             tables["OperatorID"] = config.appId;
-//             tables["RegionName"] = "data";
-//             tables["EventID"] = 9001.ToString();
-//             tables["ProductID"] = config.gameId;
-//             tables["Device"] = SystemInfo.deviceName;
-//             tables["DeviceFlag"] = ynmbxxjUtil.Instance.Device.uniqueID;
-//             tables["IP"] = DeviceUtility.GetIp();
-//             tables["DeviceFlag"] = DeviceUtility.GetDeviceUniquenessIdentify();
-//             tables["Flag"] = "1001";
-//             tables["Time"] = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
-//             tables["Step"] = _step.ToString();
-
-//             HttpRequest.Instance.RequestHttpGet(StringUtility.Concat(url, HttpRequest.HashtablaToString(tables)), HttpRequest.defaultHttpContentType);
-//         }
-// #endif
-//     }
-
-//     public void RecordEvent(int _step, uint coin = 0)
-//     {
-//         return;
-// #if !UNITY_EDITOR
-//         if (config.versionAuthority == VersionAuthority.Release)
-//         {
-//             var tables = new Dictionary<string, string>();
-//             tables["OperatorID"] = config.appId;
-//             tables["RegionName"] = "data";
-//             tables["AccountID"] = ynmbxxjUtil.Instance.FreePlatformInfo == null ? "" : ynmbxxjUtil.Instance.FreePlatformInfo.account;
-//             tables["EventID"] = 9001.ToString();
-//             tables["ProductID"] = config.gameId;
-//             tables["Device"] = SystemInfo.deviceName;
-//             tables["IP"] = DeviceUtility.GetIp();
-//             tables["DeviceFlag"] = ynmbxxjUtil.Instance.Device.uniqueID;
-//             tables["Flag"] = config.clientPackageFlag;
-//             tables["Time"] = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
-//             tables["Step"] = _step.ToString();
-
-//             if (coin != 0)
-//             {
-//                 tables["Level"] = coin.ToString();
-//             }
-
-//             string _content = StringUtility.Concat(url, HttpRequest.HashtablaToString(tables));
-//             HttpRequest.Instance.RequestHttpGet(_content, HttpRequest.defaultHttpContentType);
-//         }
-// #endif
-//     }
-
-//     bool recordedDeviceDetail = false;
-//     public void RecordDeviceDetails()
-//     {
-//         return;
-// #if !UNITY_EDITOR
-//         if (config.versionAuthority != VersionAuthority.Release)
-//         {
-//             return;
-//         }
-
-//         if (!recordedDeviceDetail)
-//         {
-//             var tables = new Dictionary<string, string>();
-//             tables["OperatorID"] = config.appId;
-//             tables["RegionName"] = StringUtility.Concat("s" + ServerListCenter.Instance.currentServer.region_flag);
-//             tables["EventID"] = 1102.ToString();
-//             tables["ProductID"] = config.gameId;
-//             tables["Time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
-//             tables["IP"] = DeviceUtility.GetIp();
-//             tables["AccountID"] = ModelCenter.Instance.GetModel<LoginModel>().sdkLoginResult.account;
-//             tables["SessionID"] = "";
-
-//             var device = new Dictionary<string, string>();
-//             device["IMEI"] = DeviceUtility.GetDeviceUniquenessIdentify();
-//             device["DeviceFlag"] = ynmbxxjUtil.Instance.Device.uniqueID;
-// #if UNITY_ANDROID
-//             device["IMEI2"] = ynmbxxjUtil.Instance.Device.uniqueID;
-// #endif
-//             device["Brand"] = DeviceUtility.GetDeviceName();
-//             device["MI5"] = DeviceUtility.GetDeviceModel();
-//             tables["Device"] = JsonMapper.ToJson(device);
-
-//             var runtime = new Dictionary<string, string>();
-//             runtime["os_version"] = DeviceUtility.GetDeviceOSLevel();
-//             tables["Runtime"] = JsonMapper.ToJson(runtime);
-//             tables["Version"] = StringUtility.Concat(config.version, "_", config.buildIndex);
-
-//             HttpRequest.Instance.RequestHttpGet(StringUtility.Concat(url, HttpRequest.HashtablaToString(tables)), HttpRequest.defaultHttpContentType);
-//         }
-
-//         recordedDeviceDetail = true;
-// #endif
-//     }
-
-
-    const string bugReportUrl = "http://gamecenter.secondworld.net.cn:11000/center/eventreport.php?";
+    const string bugReportUrl = "http://xssgcenter.secondworld.net.cn:11000/center/eventreport.php?";
 
     public void BugReport(string _title, string _content)
     {
+        var tables = new Dictionary<string, string>();
+        tables["OperatorID"] = VersionConfig.Get().appId;
+        tables["RegionName"] = "data";
+        tables["RegionID"] = ServerListCenter.Instance.currentServer.region_flag.ToString();
+        tables["EventID"] = 9002.ToString();
+        tables["ProductID"] = VersionConfig.Get().gameId;
+        tables["Time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+        tables["IP"] = DeviceUtility.GetIp();
+        tables["AccountID"] = LoginManager.Instance.sdkLoginResult.account;
+        tables["Level"] = PlayerDatas.Instance.baseData.LV.ToString();
+        tables["RoleID"] = PlayerDatas.Instance.baseData.PlayerName;
+        tables["VIPLevel"] = PlayerDatas.Instance.baseData.VIPLv.ToString();
+        tables["DeviceFlag"] = SDKUtils.Instance.Device.uniqueID;
 
-        var config = VersionConfig.config;
-        DeviceUtility.GetIp().ContinueWith(ip =>
-        {
-            var gameId = config.gameId;
+        var contentPrefix = StringUtility.Concat("IMEI:", DeviceUtility.GetDeviceUniquenessIdentify(), ";");
+        contentPrefix = StringUtility.Concat(contentPrefix, "Version:", StringUtility.Concat(VersionConfig.Get().version, "_", 
+            VersionConfig.Get().buildIndex.ToString(), "-", LoginManager.Instance.hotVersion), Language.Id, ";");
+        contentPrefix = StringUtility.Concat(contentPrefix, "Brand:", DeviceUtility.GetDeviceName(), ";");
+        contentPrefix = StringUtility.Concat(contentPrefix, "MI5:", DeviceUtility.GetDeviceModel(), ";");
+        contentPrefix = StringUtility.Concat(contentPrefix, "os_version:", DeviceUtility.GetDeviceOSLevel(), ";");
 
-            var tables = new Dictionary<string, string>();
-            tables["OperatorID"] = config.appId;
-            tables["RegionName"] = "data";
-            tables["RegionID"] = ServerListCenter.Instance.currentServer.region_flag.ToString();
-            tables["EventID"] = 9002.ToString();
-            tables["ProductID"] = config.gameId;
-            tables["Time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
-            tables["IP"] = ip;
-            tables["AccountID"] = LoginManager.Instance.sdkLoginResult.account;
-            tables["Level"] = PlayerDatas.Instance.baseData.LV.ToString();
-            tables["RoleID"] = PlayerDatas.Instance.baseData.PlayerName;
-            tables["VIPLevel"] = PlayerDatas.Instance.baseData.VIPLv.ToString();
-            tables["DeviceFlag"] = SDKUtils.Instance.Device.uniqueID;
+        tables["Title"] = _title;
+        tables["Content"] = _content;
+        tables["ClientInfo"] = contentPrefix;
 
-            var contentPrefix = StringUtility.Concat("IMEI:", DeviceUtility.GetDeviceUniquenessIdentify(), ";");
-            contentPrefix = StringUtility.Concat(contentPrefix, "Version:", StringUtility.Concat(config.version, "_", 
-                config.buildIndex.ToString(), "-", LoginManager.Instance.hotVersion), Language.Id, ";");
-            contentPrefix = StringUtility.Concat(contentPrefix, "Brand:", DeviceUtility.GetDeviceName(), ";");
-            contentPrefix = StringUtility.Concat(contentPrefix, "MI5:", DeviceUtility.GetDeviceModel(), ";");
-            contentPrefix = StringUtility.Concat(contentPrefix, "os_version:", DeviceUtility.GetDeviceOSLevel(), ";");
-
-            tables["Title"] = _title;
-            tables["Content"] = _content;
-            tables["ClientInfo"] = contentPrefix;
-
-            HttpRequest.Instance.RequestHttpGet(StringUtility.Concat(bugReportUrl, HttpRequest.HashtablaToString(tables)), HttpRequest.defaultHttpContentType);
-
-        }).Forget();
-
+        HttpRequest.Instance.RequestHttpGet(StringUtility.Concat(bugReportUrl, HttpRequest.HashtablaToString(tables)), HttpRequest.defaultHttpContentType);
 
     }
 
-    public void BugReportSys( string _content)
+    //10000 鎴樺満鎶ラ敊, 10001 灏佸寘閿欒, 10002 鐣岄潰鎿嶄綔
+    public void BugReportSys(string _content, string sid = "10000")
     {
 #if !UNITY_EDITOR
         try
         {
-            DeviceUtility.GetIp().ContinueWith(ip =>
+            var tables = new Dictionary<string, string>();
+            tables["OperatorID"] = VersionConfig.Get().appId;
+            tables["RegionName"] = "data";
+            tables["RegionID"] = sid;
+            tables["EventID"] = 9002.ToString();
+            tables["ProductID"] = VersionConfig.Get().gameId;
+            tables["Time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+            tables["IP"] = DeviceUtility.GetIp();
+            tables["AccountID"] = "system";
+            tables["Level"] = "1";
+            tables["RoleID"] = "system";
+            tables["VIPLevel"] = "1";
+            tables["DeviceFlag"] = SDKUtils.Instance.Device.uniqueID;
+
+            var contentPrefix = StringUtility.Concat("IMEI:", DeviceUtility.GetDeviceUniquenessIdentify(), ";");
+            contentPrefix = StringUtility.Concat(contentPrefix, "Version:", StringUtility.Concat(VersionConfig.Get().version, "_",
+                VersionConfig.Get().buildIndex.ToString(), "-", LoginManager.Instance.hotVersion), Language.Id, ";");
+            contentPrefix = StringUtility.Concat(contentPrefix, "Brand:", DeviceUtility.GetDeviceName(), ";");
+            contentPrefix = StringUtility.Concat(contentPrefix, "MI5:", DeviceUtility.GetDeviceModel(), ";");
+            contentPrefix = StringUtility.Concat(contentPrefix, "os_version:", DeviceUtility.GetDeviceOSLevel(), ";");
+
+            tables["Title"] = "system";
+            _content = _content.Replace("0000", "");
+            if (ConfigManager.Instance.isLoadFinished && DTC0102_tagCDBPlayer.playerIdBuf != 0 && LoginManager.Instance.sdkLoginResult != null && !string.IsNullOrEmpty(LoginManager.Instance.sdkLoginResult.account))
             {
-                var config = VersionConfig.config;
-                var tables = new Dictionary<string, string>();
-                tables["OperatorID"] = config.appId;
-                tables["RegionName"] = "data";
-                tables["RegionID"] = "10000";
-                tables["EventID"] = 9002.ToString();
-                tables["ProductID"] = config.gameId;
-                tables["Time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
-                tables["IP"] = ip;
-                tables["AccountID"] = "system";
-                tables["Level"] = "1";
-                tables["RoleID"] = "system";
-                tables["VIPLevel"] = "1";
-                tables["DeviceFlag"] = SDKUtils.Instance.Device.uniqueID;
+                _content = StringUtility.Concat(LoginManager.Instance.sdkLoginResult.account, "@", ServerListCenter.Instance.currentServer.region_flag.ToString(), " ", _content);
+            }
+            
+            tables["Content"] = _content.Substring(0, Math.Min(800, _content.Length));
+            tables["ClientInfo"] = contentPrefix;
 
-                var contentPrefix = StringUtility.Concat("IMEI:", DeviceUtility.GetDeviceUniquenessIdentify(), ";");
-                contentPrefix = StringUtility.Concat(contentPrefix, "Version:", StringUtility.Concat(config.version, "_",
-                    config.buildIndex.ToString(), "-", LoginManager.Instance.hotVersion), Language.Id, ";");
-                contentPrefix = StringUtility.Concat(contentPrefix, "Brand:", DeviceUtility.GetDeviceName(), ";");
-                contentPrefix = StringUtility.Concat(contentPrefix, "MI5:", DeviceUtility.GetDeviceModel(), ";");
-                contentPrefix = StringUtility.Concat(contentPrefix, "os_version:", DeviceUtility.GetDeviceOSLevel(), ";");
-
-                tables["Title"] = "system";
-                _content = _content.Replace("0000", "");
-                if (ConfigManager.Instance.isLoadFinished && DTC0102_tagCDBPlayer.playerIdBuf != 0 && LoginManager.Instance.sdkLoginResult != null && !string.IsNullOrEmpty(LoginManager.Instance.sdkLoginResult.account))
-                {
-                    _content = StringUtility.Concat(LoginManager.Instance.sdkLoginResult.account, "@", ServerListCenter.Instance.currentServer.region_flag.ToString(), " ", _content);
-                }
-                
-                tables["Content"] = _content.Substring(0, Math.Min(800, _content.Length));
-                tables["ClientInfo"] = contentPrefix;
-
-                HttpRequest.Instance.RequestHttpGet(StringUtility.Concat(bugReportUrl, HttpRequest.HashtablaToString(tables)), HttpRequest.defaultHttpContentType);
-            }).Forget();
-
+            HttpRequest.Instance.RequestHttpGet(StringUtility.Concat(bugReportUrl, HttpRequest.HashtablaToString(tables)), HttpRequest.defaultHttpContentType);
         }
         catch (System.Exception ex)
         {
@@ -203,21 +88,20 @@
     }
 
 
-    const string chatReportUrl = "http://gamecenter.secondworld.net.cn:11000/center/eventreport.php?";
-    public async void ChatReport(string content, string channelName, string toPlayer, int chatType)
+    const string chatReportUrl = "http://xssgcenter.secondworld.net.cn:11000/center/eventreport.php?";
+    public void ChatReport(string content, string channelName, string toPlayer, int chatType)
     {
 #if !UNITY_EDITOR
         bool isFairy = chatType == 3;
         var tables = new Dictionary<string, string>();
-        var config = VersionConfig.config;
-        tables["ProductID"] = config.gameId;
-        tables["OperatorID"] = config.appId;
+        tables["ProductID"] = VersionConfig.Get().gameId;
+        tables["OperatorID"] = VersionConfig.Get().appId;
         tables["OperatorName"] = string.Empty;
         tables["RegionName"] = StringUtility.Concat("s", ServerListCenter.Instance.currentServer.region_flag.ToString());
         tables["RegionID"] = ServerListCenter.Instance.currentServer.region_flag.ToString();
         tables["EventID"] = 9003.ToString();
         tables["Time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
-        tables["IP"] = await DeviceUtility.GetIp();
+        tables["IP"] = DeviceUtility.GetIp();
         tables["ChatChannel"] = channelName;
         var sdkLoginResult = LoginManager.Instance.sdkLoginResult;
         tables["AccountID"] = sdkLoginResult == null ? LoginManager.Instance.accountBuf : sdkLoginResult.account;
diff --git a/Main/Utility/TimeUtility.cs b/Main/Utility/TimeUtility.cs
index 587220d..b9db750 100644
--- a/Main/Utility/TimeUtility.cs
+++ b/Main/Utility/TimeUtility.cs
@@ -130,6 +130,12 @@
         get; private set;
     }
 
+    //寮�鏈嶆椂闂存埑
+    public static int openServerTick
+    {
+        get; private set;
+    }
+
     public static DayOfWeek openServerDayOfWeek;
 
     public static int OpenWeekCnt
@@ -168,18 +174,16 @@
     }
 
     public static event Action OnCreateRoleTimeRefresh;
-    // public static void OnRefreshCreateRoleTime(HA124_tagMCPlayerInfo _package)
-    // {
-
-
-    //     createRoleTime = Convert.ToDateTime(UIHelper.GetTime(_package.CreateRoleTime));
-    //     createRoleTimeTail = new DateTime(createRoleTime.Year, createRoleTime.Month, createRoleTime.Day);
-    //     if (OnCreateRoleTimeRefresh != null)
-    //     {
-    //         OnCreateRoleTimeRefresh();
-    //     }
-    //     Debug.LogFormat("CreateRoleTime {0}  CreateDays {1}", createRoleTimeTail, CreateDays);
-    // }
+    public static void OnRefreshCreateRoleTime(HA124_tagMCPlayerInfo _package)
+    {
+        createRoleTime = Convert.ToDateTime(UIHelper.GetTime(_package.CreateRoleTime));
+        createRoleTimeTail = new DateTime(createRoleTime.Year, createRoleTime.Month, createRoleTime.Day);
+        if (OnCreateRoleTimeRefresh != null)
+        {
+            OnCreateRoleTimeRefresh();
+        }
+        Debug.LogFormat("CreateRoleTime {0}  CreateDays {1}", createRoleTimeTail, CreateDays);
+    }
 
     public static event Action OnServerTimeRefresh;
     public static void OnRefreshServerTime(HA004_tagServerDateTime vNetData)
@@ -208,13 +212,12 @@
     public static event Action OnServerOpenDayRefresh;
     public static void OnRefreshServerOpenDay(HA103_tagMCOpenServerDay package)
     {
-        {
-            OpenDay = package.Day;
-            IsMixServer = package.IsMixServer == 1;
-            MixOpenDay = package.MixDay;
-            openServerDayOfWeek = package.OpenWeekday == 7 ? DayOfWeek.Sunday : (DayOfWeek)package.OpenWeekday;
-            WeekOfYear = package.WeekOfYear;
-        }
+        OpenDay = package.Day;
+        IsMixServer = package.IsMixServer == 1;
+        MixOpenDay = package.MixDay;
+        openServerDayOfWeek = package.OpenWeekday == 7 ? DayOfWeek.Sunday : (DayOfWeek)package.OpenWeekday;
+        WeekOfYear = package.WeekOfYear;
+        openServerTick = (int)package.OpenServerTime;
 
         OnRefreshServerTime(new HA004_tagServerDateTime()
         {
@@ -409,7 +412,7 @@
             return StringUtility.Concat(hours.ToString(), Language.Get("L1072"), mins.ToString(), Language.Get("L1073"));
         }
         else if (mins > 0)
-        { 
+        {
             return StringUtility.Concat(mins.ToString(), Language.Get("L1073"));
         }
         return StringUtility.Concat(seconds.ToString(), Language.Get("L1075"));
@@ -515,7 +518,7 @@
     }
 
     // 浠婃棩鍒皒鐐硅繕瑕佸灏戠锛屽鏋滃凡缁忚繃浜唜鐐癸紝杩斿洖0
-    public static int GetToTheHourSeconds(int hour=10)
+    public static int GetToTheHourSeconds(int hour = 10)
     {
         var now = ServerNow;
         if (now.Hour < hour)
@@ -585,5 +588,21 @@
         var now = GetCommServerNow(zoneID).AddDays(1);
         return new DateTime(now.Year, now.Month, now.Day);
     }
+
+    //鑾峰彇褰撳墠鍛ㄥ嚑锛�1-7
+    public static int GetCommonWeekday(int zoneID = 0)
+    {
+        var day = GetCommServerNow(zoneID).DayOfWeek;
+        return day == DayOfWeek.Sunday ? 7 : (int)day;
+    }
+
+    //鏈懆缁撴潫鏃堕棿 绉�
+    public static int GetCommonWeekEndTime(int zoneID = 0)
+    {
+        var now = GetCommServerNow(zoneID);
+        var weekDay = GetCommonWeekday(zoneID);
+        var endDay = now.AddDays(7 - weekDay + 1);
+        return (int)(new DateTime(endDay.Year, endDay.Month, endDay.Day) - now).TotalSeconds;
+    }
     #endregion
 }
diff --git a/Main/Utility/UIHelper.cs b/Main/Utility/UIHelper.cs
index 34ba248..c0dd2b0 100644
--- a/Main/Utility/UIHelper.cs
+++ b/Main/Utility/UIHelper.cs
@@ -1050,6 +1050,8 @@
         {53, PlayerDataType.ChallengeVoucher},
         {54, PlayerDataType.DailySpecials},
         {55, PlayerDataType.OSGalaScore},
+        {57, PlayerDataType.QYScore},
+        {58, PlayerDataType.heroSkin},
         {99, PlayerDataType.ExAttr11},
     };
 
@@ -1208,6 +1210,21 @@
                     //寮�鏈嶅簡鍏哥Н鍒�
                     return PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.OSGalaScore);
                 }
+            case 56:
+                {
+                    //缇よ嫳鎸戞垬浠�
+                    return PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.QunyingWDL);
+                }
+            case 57:
+                {
+                    //缇よ嫳绉垎
+                    return PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.QYScore);
+                }
+            case 58:
+                {
+                    //鏃惰璐у竵
+                    return PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.heroSkin);
+                }
             case 98:
                 {
                     //杩囨湡鍨嬩唬閲戝埜
@@ -1275,6 +1292,34 @@
         return isEnough;
     }
 
+    /// <param name="needTips">0 涓嶅搷搴� 1 寮规彁绀� 2 寮硅幏鍙栭�斿緞tips</param>
+    public static bool CheckItemCount(int itemId, long needCount, int needTips = 0)
+    {
+        if (needCount <= 0)
+        {
+            return true;
+        }
+        long haveCount = PackManager.Instance.GetItemCountByID(PackType.Item, itemId);
+        bool isEnough = haveCount >= needCount;
+
+        if (!isEnough)
+        {
+            if (needTips == 1)
+            {
+                ItemConfig itemConfig = ItemConfig.Get(itemId);
+                if (itemConfig != null)
+                {
+                    SysNotifyMgr.Instance.ShowTip("LackItem", itemConfig.ItemName);
+                }
+            }
+            else if (needTips == 2)
+            {
+                ItemTipUtility.Show(itemId, true);
+            }
+        }
+
+        return isEnough;
+    }
 
     #endregion
 

--
Gitblit v1.8.0