diff --git a/src/config/security.js b/src/config/security.js index 142873e..8e4db63 100644 --- a/src/config/security.js +++ b/src/config/security.js @@ -19,6 +19,7 @@ export const PUBLIC_PATHS = Object.freeze([ '/login-reward', '/activities/poker-ace', '/daily-recharge', + '/activities/games/the-greedy-king', '/activities/gulben-festival', '/activities/bounty-football', '/activities/world-cup', diff --git a/src/locales/ar.json b/src/locales/ar.json index 40aa93f..328380b 100644 --- a/src/locales/ar.json +++ b/src/locales/ar.json @@ -488,6 +488,11 @@ "gulben_room_rule_1": "1. سيتم احتساب إيرادات غرفتك خلال النشاط. بعد انتهاء النشاط، ستحصل أفضل 10 غرف في الترتيب على مكافآت سخية من العملات و VIP بناء على مستوى إيراداتها.", "gulben_room_rule_2": "2. هذا الحدث غير مرتبط ب iPhone أو Google.", "gulben_room_rule_3": "3. تحتفظ الجهة الرسمية بحق التفسير النهائي لهذا الحدث.", + "greedy_king_help_rule_1": "١. كلما جمع المستخدم المزيد من العملات خلال الحدث، ارتفع ترتيبه.", + "greedy_king_help_rule_2": "٢. سيستمر الحدث لمدة 15 يوما. بعد انتهاء الحدث، سيتم توزيع المكافآت على أفضل ثلاثة مستخدمين في لوحة الترتيب.", + "greedy_king_help_rule_3": "٣. يجب على أفضل ثلاثة مستخدمين التواصل مع الموظفين الرسميين في الوقت المناسب لمناقشة كيفية الحصول على مكافأة الدولار الأمريكي.", + "greedy_king_help_rule_4": "(1) السحب: يرجى تقديم معرف حساب استقبال USDT الخاص بك أو رمز QR للاستلام.", + "greedy_king_help_rule_5": "(2) بدون سحب: إذا تم تحويلها إلى عملات، سنمنحك 5% عملات ذهبية إضافية فوق المبلغ الأصلي ($1:10500 عملة).", "bounty_football_help_rule_1": "1. كلما جمع المستخدم المزيد من العملات خلال الحدث، ارتفع ترتيبه.", "bounty_football_help_rule_2": "2. سيستمر الحدث لمدة 7 أيام. بعد انتهاء الحدث، سيتم توزيع المكافآت على أفضل ثلاثة مستخدمين في لوحة الترتيب.", "bounty_football_help_rule_3": "3.إشعار: إذا تم العثور على لاعب يشارك في النشاط باستخدام وسائل غير مناسبة، تحتفظ الجهة الرسمية بالحق في استبعاد اللاعب المشارك أو المخالف من القائمة، وحظر الحساب، وسحب جميع المكافآت من اللاعب وفقا لخطورة الحالة دون إشعار مسبق، بما في ذلك على سبيل المثال لا الحصر: a) تعليقات خبيثة أو شائعات أو تلميحات وما إلى ذلك ضد اللاعبين المشاركين أثناء النشاط. b) الحصول على العملات والهدايا المحددة بطرق غير قانونية. *هذا النشاط لا علاقة له بشركة Apple Inc." diff --git a/src/locales/bn.json b/src/locales/bn.json index ab13023..1d9ac34 100644 --- a/src/locales/bn.json +++ b/src/locales/bn.json @@ -488,6 +488,11 @@ "gulben_room_rule_1": "1. অ্যাক্টিভিটি চলাকালীন আপনার রুমের আয় গণনা করা হবে। অ্যাক্টিভিটি শেষ হওয়ার পরে, শীর্ষ 10 র‍্যাঙ্ক করা রুম তাদের আয়ের স্তর অনুযায়ী উদার কয়েন এবং VIP পুরস্কার পাবে।", "gulben_room_rule_2": "2. এই ইভেন্টটি iPhone বা Google-এর সাথে সম্পর্কিত নয়।", "gulben_room_rule_3": "3. এই ইভেন্টের চূড়ান্ত ব্যাখ্যার অধিকার অফিসিয়াল পক্ষ সংরক্ষণ করে।", + "greedy_king_help_rule_1": "১. ইভেন্ট চলাকালীন একজন ব্যবহারকারী যত বেশি কয়েন জমা করবেন, তার র‍্যাঙ্কিং তত বেশি হবে।", + "greedy_king_help_rule_2": "২. ইভেন্টটি ১৫ দিন চলবে। ইভেন্ট শেষ হওয়ার পর, লিডারবোর্ডের শীর্ষ তিন ব্যবহারকারীকে পুরস্কার বিতরণ করা হবে।", + "greedy_king_help_rule_3": "৩. শীর্ষ তিন ব্যবহারকারীকে USD পুরস্কার কীভাবে গ্রহণ করবেন তা আলোচনা করার জন্য সময়মতো অফিসিয়াল স্টাফের সাথে যোগাযোগ করতে হবে।", + "greedy_king_help_rule_4": "(1) উত্তোলন: অনুগ্রহ করে আপনার USDT গ্রহণকারী অ্যাকাউন্ট ID বা গ্রহণকারী QR কোড প্রদান করুন।", + "greedy_king_help_rule_5": "(2) উত্তোলন নয়: কয়েনে রূপান্তর করলে, আমরা মূল পরিমাণের উপর অতিরিক্ত ৫% গোল্ড কয়েন দেব ($1:10500 কয়েন)।", "bounty_football_help_rule_1": "১. ইভেন্ট চলাকালীন একজন ব্যবহারকারী যত বেশি কয়েন জমা করবেন, তার র‍্যাঙ্কিং তত বেশি হবে।", "bounty_football_help_rule_2": "২. ইভেন্টটি ৭ দিন চলবে। ইভেন্ট শেষ হওয়ার পরে, লিডারবোর্ডের শীর্ষ তিন ব্যবহারকারীকে পুরস্কার বিতরণ করা হবে।", "bounty_football_help_rule_3": "৩.নোটিশ: যদি কোনো খেলোয়াড়কে অনুচিত উপায়ে কার্যকলাপে অংশগ্রহণ করতে পাওয়া যায়, তবে অফিসিয়াল পক্ষ ঘটনার গুরুতরতা অনুযায়ী পূর্ব নোটিশ ছাড়াই অংশগ্রহণকারী খেলোয়াড় বা লঙ্ঘনকারীকে তালিকা থেকে অযোগ্য ঘোষণা, অ্যাকাউন্ট নিষিদ্ধ এবং খেলোয়াড়ের সব পুরস্কার প্রত্যাহার করার অধিকার সংরক্ষণ করে, যার মধ্যে রয়েছে কিন্তু সীমাবদ্ধ নয়: a) কার্যকলাপ চলাকালীন অংশগ্রহণকারী খেলোয়াড়দের বিরুদ্ধে বিদ্বেষপূর্ণ মন্তব্য, গুজব, ইঙ্গিত ইত্যাদি। b) অবৈধভাবে কয়েন এবং নির্দিষ্ট উপহার সংগ্রহ। *এই কার্যকলাপের Apple Inc.-এর সঙ্গে কোনো সম্পর্ক নেই।" diff --git a/src/locales/en.json b/src/locales/en.json index 3bff2eb..39a6c24 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -488,6 +488,11 @@ "gulben_room_rule_1": "1.Your room's revenue will be tallied during the activity. After the activity ends, the top 10 ranked rooms will receive generous coins and VIP rewards based on their revenue level.", "gulben_room_rule_2": "2. This event is not related to iPhone or Google.", "gulben_room_rule_3": "3. The official party reserves the final right of interpretation for this event.", + "greedy_king_help_rule_1": "1. The more coins a user accumulates during the event, the higher their ranking will be.", + "greedy_king_help_rule_2": "2. The event will last for 15 days. After the event ends, rewards will be distributed to the top three users on the leaderboard.", + "greedy_king_help_rule_3": "3. The top three users should contact the official staff in a timely manner to discuss how to obtain the USD reward.", + "greedy_king_help_rule_4": "(1) Withdrawal: Please provide your USDT receiving account ID or receiving QR code.", + "greedy_king_help_rule_5": "(2) No withdrawal: If converted to coins, we will give you an additional 5% gold coins on top of the original amount ($1:10500 coins).", "bounty_football_help_rule_1": "1. The more coins a user accumulates during the event, the higher their ranking will be.", "bounty_football_help_rule_2": "2. The event will last for 7 days. After the event ends, rewards will be distributed to the top three users on the leaderboard.", "bounty_football_help_rule_3": "3.Notice:If a player is found to be participating in an activity using improper means, the official reserves the right to disqualify the participating player or violator from the list, ban the account, and withdraw all rewards from the player according to the seriousness of the case without prior notice,including but not limited to:a) Malicious comments, rumors, insinuations, etc.to participating players during the activity.b) Illegally obtaining coins and designated gifts.*This activity has nothing to do with Apple Inc." diff --git a/src/locales/tr.json b/src/locales/tr.json index ba6cb0a..744daeb 100644 --- a/src/locales/tr.json +++ b/src/locales/tr.json @@ -488,7 +488,13 @@ "gulben_room_rule_1": "1. Etkinlik süresince odanızın geliri hesaplanacaktır. Etkinlik sona erdikten sonra, ilk 10 sıradaki odalar gelir seviyelerine göre cömert coin ve VIP ödülleri alacaktır.", "gulben_room_rule_2": "2. Bu etkinliğin iPhone veya Google ile ilgisi yoktur.", "gulben_room_rule_3": "3. Bu etkinliğin nihai yorum hakkı resmi tarafa aittir.", + "greedy_king_help_rule_1": "1. Bir kullanıcı etkinlik boyunca ne kadar çok coin biriktirirse sıralaması o kadar yüksek olur.", + "greedy_king_help_rule_2": "2. Etkinlik 15 gün sürecektir. Etkinlik sona erdikten sonra ödüller liderlik tablosundaki ilk üç kullanıcıya dağıtılacaktır.", + "greedy_king_help_rule_3": "3. İlk üç kullanıcı, USD ödülünü nasıl alacaklarını görüşmek için resmi personelle zamanında iletişime geçmelidir.", + "greedy_king_help_rule_4": "(1) Para çekme: Lütfen USDT alıcı hesap kimliğinizi veya alıcı QR kodunuzu sağlayın.", + "greedy_king_help_rule_5": "(2) Para çekmeme: Coin'e dönüştürülürse, orijinal tutarın üzerine ek %5 gold coin vereceğiz ($1:10500 coin).", "bounty_football_help_rule_1": "1. Bir kullanıcı etkinlik boyunca ne kadar çok coin biriktirirse sıralaması o kadar yüksek olur.", "bounty_football_help_rule_2": "2. Etkinlik 7 gün sürecektir. Etkinlik sona erdikten sonra ödüller liderlik tablosundaki ilk üç kullanıcıya dağıtılacaktır.", "bounty_football_help_rule_3": "3.Duyuru: Bir oyuncunun uygunsuz yollarla etkinliğe katıldığı tespit edilirse resmi taraf, durumun ciddiyetine göre önceden haber vermeksizin katılımcı oyuncuyu veya ihlal edeni listeden diskalifiye etme, hesabı yasaklama ve oyuncunun tüm ödüllerini geri alma hakkını saklı tutar; bunlara şunlar dahildir ancak bunlarla sınırlı değildir: a) Etkinlik sırasında katılımcı oyunculara yönelik kötü niyetli yorumlar, söylentiler, imalar vb. b) Coin ve belirlenmiş hediyeleri yasa dışı yollarla elde etmek. *Bu etkinliğin Apple Inc. ile hiçbir ilgisi yoktur." } + diff --git a/src/locales/zh.json b/src/locales/zh.json index 5ac1338..7421a56 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -488,6 +488,11 @@ "gulben_room_rule_1": "1.活动期间将统计你的房间流水。活动结束后,排名前 10 的房间将根据其流水等级获得丰厚金币和 VIP 奖励。", "gulben_room_rule_2": "2. 本活动与 iPhone 或 Google 无关。", "gulben_room_rule_3": "3. 本活动最终解释权归官方所有。", + "greedy_king_help_rule_1": "1. 活动期间用户累计的金币越多,排名越高。", + "greedy_king_help_rule_2": "2. 活动将持续 15 天。活动结束后,奖励将发放给排行榜前三名用户。", + "greedy_king_help_rule_3": "3. 排行榜前三名用户应及时联系官方工作人员,沟通如何领取美元奖励。", + "greedy_king_help_rule_4": "(1) 提现:请提供你的 USDT 收款账号 ID 或收款二维码。", + "greedy_king_help_rule_5": "(2) 不提现:如果兑换为金币,我们将在原金额基础上额外赠送 5% 金币($1:10500 金币)。", "bounty_football_help_rule_1": "1. 活动期间用户累计的金币越多,排名越高。", "bounty_football_help_rule_2": "2. 活动将持续7天。活动结束后,奖励将发放给排行榜前三名用户。", "bounty_football_help_rule_3": "3.注意:如果发现玩家使用不正当手段参与活动,官方保留根据情节严重程度在不提前通知的情况下,将参与玩家或违规者从榜单中取消资格、封禁账号并收回其全部奖励的权利,包括但不限于:a) 在活动期间对参与玩家进行恶意评论、散布谣言、影射等。b) 非法获取金币和指定礼物。*本活动与 Apple Inc. 无关。" diff --git a/src/router/index.js b/src/router/index.js index 7c4909f..2ab8c0c 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -452,6 +452,12 @@ const router = createRouter({ component: () => import('../views/Activities/WorldCup/index.vue'), meta: { requiresAuth: false }, }, // WorldCup + { + path: '/activities/games/the-greedy-king', + name: 'games-the-greedy-king', + component: () => import('../views/Activities/Games/TheGreedyKing/index.vue'), + meta: { requiresAuth: true }, + }, //2025年xx月xx日上午5点结束 { path: '/activities/bounty-football', name: 'bounty-football', diff --git a/src/utils/permissionManager.js b/src/utils/permissionManager.js index 5a2032d..6506027 100644 --- a/src/utils/permissionManager.js +++ b/src/utils/permissionManager.js @@ -60,16 +60,18 @@ const ACTIVITIES = [ '/recharge-reward', //充值奖励 '/login-reward', // 登录奖励 - '/activities/poker-ace', // 扑克王牌排行榜 '/daily-recharge', // 每日充值页面 '/activities/lucky-dollars-season5', // 幸运美金活动 '/activities/gulben-festival', // 古尔邦节活动 - '/activities/bounty-football', // BountyFootball - '/activities/world-cup', // WorldCup '/activities/lucky-dollars-season4', // 幸运美金活动 '/activities/lesser-bairam', // 开斋节打榜 '/activities/lucky-dollars-season3', // 斋月打榜 '/activities/spring-festival', // 春节打榜 + + '/activities/world-cup', // WorldCup + '/activities/games/the-greedy-king', //贪金王游戏排行榜 + '/activities/bounty-football', // BountyFootball + '/activities/poker-ace', // 扑克王牌排行榜 ] // 🎯 核心改变:基于身份的权限配置 diff --git a/src/views/Activities/Games/TheGreedyKing/components/topUser.vue b/src/views/Activities/Games/TheGreedyKing/components/topUser.vue new file mode 100644 index 0000000..6e310ed --- /dev/null +++ b/src/views/Activities/Games/TheGreedyKing/components/topUser.vue @@ -0,0 +1,235 @@ + + + + + diff --git a/src/views/Activities/Games/TheGreedyKing/index.vue b/src/views/Activities/Games/TheGreedyKing/index.vue new file mode 100644 index 0000000..55b622e --- /dev/null +++ b/src/views/Activities/Games/TheGreedyKing/index.vue @@ -0,0 +1,824 @@ + + + + + diff --git a/src/views/Activities/Games/TheGreedyKing/page.config.js b/src/views/Activities/Games/TheGreedyKing/page.config.js new file mode 100644 index 0000000..1ba1474 --- /dev/null +++ b/src/views/Activities/Games/TheGreedyKing/page.config.js @@ -0,0 +1,114 @@ +export const pageConfig = { + name: 'TheGreedyKing', + routePath: '/activities/games/the-greedy-king', + routeName: 'games-the-greedy-king', + assetPath: 'Activities/Games/TheGreedyKing/', + + activity: { + templateId: '1994334094730010626', + activityType: 1068, + cycleType: 3, + cycleKey: '202511', + }, + + preload: { + blocking: [ + 'bg', + 'helpBt', + 'timeBg', + 'rankingBt', + 'rewardsBt', + 'RankingMain', + 'RankingItem', + 'RankingBottomBorder', + 'myRankingBg', + 'helpInfoBg', + 'frameTop1', + 'frameTop2', + 'frameTop3', + 'rewardBgTop1', + 'rewardBgTop2', + 'rewardBgTop3', + 'giftItemBg', + ], + background: [], + }, + + modules: { + tabs: { + enabled: true, + defaultValue: 'ranking', + items: [ + { + value: 'ranking', + label: 'Ranking', + buttonImage: 'rankingBt', + activeButtonImage: 'rankingBt', + remark: '排行榜按钮只有一张图片,非展示模块时页面置灰。', + }, + { + value: 'reward', + label: 'Rewards', + buttonImage: 'rewardsBt', + activeButtonImage: 'rewardsBt', + remark: '奖励按钮只有一张图片,非展示模块时页面置灰。', + }, + ], + }, + sections: [ + { + name: 'ranking', + label: 'Ranking', + enabled: true, + apis: ['getRankingListAndMyRanking'], + loadMode: 'client-incremental', + pageSize: 10, + images: ['RankingMain', 'RankingItem', 'RankingBottomBorder', 'myRankingBg'], + previewImages: ['frameTop1', 'frameTop2', 'frameTop3'], + remark: '保留旧页排行榜布局:前三名、第四名之后列表和底部我的排名。', + children: {}, + }, + { + name: 'reward', + label: 'Rewards', + enabled: true, + apis: ['getThisWeekRewardsAndGifts'], + images: ['rewardBgTop1', 'rewardBgTop2', 'rewardBgTop3', 'giftItemBg'], + previewImages: [], + remark: '保留旧页奖励列表布局,并沿用旧页追加前三名美元奖励的逻辑。', + children: {}, + }, + ], + popups: [ + { + name: 'help', + triggerImage: 'helpBt', + backgroundImage: 'helpInfoBg', + contentImage: '', + apis: [], + remark: '规则说明弹窗使用 itemCenter 承载 helpInfoBg,内部通过 greedy_king_help_rule_* 多语言 key 渲染。', + }, + ], + features: [ + { + name: 'countdown', + enabled: true, + deadline: '2026-06-08 05:00:00', + images: ['timeBg'], + fields: { + endTime: '2026-06-08 05:00:00', + remainingText: '', + }, + remark: '倒计时截止时间和计算方式按 BountyFootball/index.vue 对齐。', + }, + ], + }, + + images: { + localized: { + ar: ['helpInfoBg', 'rankingBt', 'RankingMain', 'rewardsBt'], + bn: ['helpInfoBg', 'rankingBt', 'RankingMain', 'rewardsBt'], + tr: ['helpInfoBg', 'rankingBt', 'RankingMain', 'rewardsBt'], + }, + }, +} diff --git a/src/views/Activities/Games/TheGreedyKing/页面创建信息.md b/src/views/Activities/Games/TheGreedyKing/页面创建信息.md new file mode 100644 index 0000000..6e15584 --- /dev/null +++ b/src/views/Activities/Games/TheGreedyKing/页面创建信息.md @@ -0,0 +1,463 @@ +# 页面创建信息 + +## 1. 基础信息 + +- 页面类型:Activities / Games +- 页面名称:TheGreedyKing +- 页面目录:`src/views/Activities/Games/TheGreedyKing` +- 页面入口:`src/views/Activities/Games/TheGreedyKing/index.vue` +- 配置文件:`src/views/Activities/Games/TheGreedyKing/page.config.js` +- 资源路径:`Activities/Games/TheGreedyKing/` +- 本地资源目录:`public/oss/h5/Azizi/Activities/Games/TheGreedyKing/` +- 页面主背景色:`#2A1046`,Vue 中使用 `#2a1046` +- 当前同步来源:以当前 `index.vue` 为准 + +## 2. 路由信息 + +```js +{ + path: '/activities/games/the-greedy-king', + name: 'games-the-greedy-king', + component: () => import('../views/Activities/Games/TheGreedyKing/index.vue'), + meta: { requiresAuth: false }, +} +``` + +安全白名单和权限页面中应保留: + +```js +'/activities/games/the-greedy-king', +``` + +```js +'/activities/games/the-greedy-king', // TheGreedyKing +``` + +## 3. 活动参数 + +当前参数来自 `page.config.js`,后续真实上线如有新活动模板,需要再确认替换。 + +```json +{ + "templateId": "1994334094730010626", + "activityType": 1068, + "cycleType": 3, + "cycleKey": "202511" +} +``` + +## 4. 图片资源 + +### 4.1 图片清单 + +| 图片名 | 实际文件 | 用途 | 多语言 | +| --- | --- | --- | --- | +| bg | bg.png | 首屏主背景,使用 `itemCenter` 承载 | 否 | +| helpBt | helpBt.png | 首屏帮助按钮 | 否 | +| timeBg | timeBg.png | 倒计时数字背景 | 否 | +| rankingBt | rankingBt.png / rankingBt_ar.png / rankingBt_bn.png / rankingBt_tr.png | 排行榜切换按钮,非当前模块置灰 | 是 | +| rewardsBt | rewardsBt.png / rewardsBt_ar.png / rewardsBt_bn.png / rewardsBt_tr.png | 奖励切换按钮,非当前模块置灰 | 是 | +| RankingMain | RankingMain.png / RankingMain_ar.png / RankingMain_bn.png / RankingMain_tr.png | 排行榜前三名背景 | 是 | +| frameTop1 | frameTop1.png | 第一名头像框 | 否 | +| frameTop2 | frameTop2.png | 第二名头像框 | 否 | +| frameTop3 | frameTop3.png | 第三名头像框 | 否 | +| RankingItem | RankingItem.png | 第四名及之后排行榜列表项背景 | 否 | +| RankingBottomBorder | RankingBottomBorder.png | 排行榜底部边框 | 否 | +| myRankingBg | myRankingBg.png | 底部固定我的排名背景 | 否 | +| rewardBgTop1 | rewardBgTop1.png | 第一名奖励模块背景 | 否 | +| rewardBgTop2 | rewardBgTop2.png | 第二名奖励模块背景 | 否 | +| rewardBgTop3 | rewardBgTop3.png | 第三名奖励模块背景 | 否 | +| giftItemBg | giftItemBg.png | 奖励单项背景 | 否 | +| helpInfoBg | helpInfoBg.png / helpInfoBg_ar.png / helpInfoBg_bn.png / helpInfoBg_tr.png | 帮助弹窗背景 | 是 | + +### 4.2 多语言图片规则 + +页面通过 `currentLangType` 和 `pageConfig.images.localized` 判断图片是否有语言版本。 + +```js +const getImgName = (filename) => { + const lang = currentLangType.value + const localizedNames = localizedImageMap[lang] || [] + + if (lang === 'en' || !localizedNames.includes(filename)) { + return filename + } + + return `${filename}_${lang}` +} +``` + +当前多语言图片: + +```json +{ + "ar": ["helpInfoBg", "rankingBt", "RankingMain", "rewardsBt"], + "bn": ["helpInfoBg", "rankingBt", "RankingMain", "rewardsBt"], + "tr": ["helpInfoBg", "rankingBt", "RankingMain", "rewardsBt"] +} +``` + +### 4.3 预加载配置 + +进入页面前阻塞预加载: + +```json +[ + "bg", + "helpBt", + "timeBg", + "rankingBt", + "rewardsBt", + "RankingMain", + "RankingItem", + "RankingBottomBorder", + "myRankingBg", + "helpInfoBg", + "frameTop1", + "frameTop2", + "frameTop3", + "rewardBgTop1", + "rewardBgTop2", + "rewardBgTop3", + "giftItemBg" +] +``` + +后台空闲预加载:当前为空数组。 + +## 5. itemCenter 高度规则 + +使用 `itemCenter` 承载图片背景时,必须设置 `min-height`,避免图片未加载出来时内部信息挤在一起。 + +计算方式: + +```text +min-height = Math.ceil(展示宽度vw * 图片高度 / 图片宽度) + 'vw' +``` + +如果 `itemCenter` 放在网格或固定宽度容器中,展示宽度按该容器实际占用宽度计算;如果同一背景存在多语言图片,取对应语言图片中最高的计算结果。 + +当前页面实际使用: + +| 图片 / 区域 | 图片尺寸 | 展示宽度 | 当前 min-height | 备注 | +| --- | --- | --- | --- | --- | +| bg | 1125 x 1689 | 100vw | 151vw | 首屏主背景 | +| timeBg | 216 x 216 | 20vw | 20vw | 倒计时每个数字格 | +| RankingMain | 1125 x 1110 | 100vw | 99vw | 前三名背景 | +| RankingItem | 1125 x 309 | 100vw | 28vw | 排行榜列表项 | +| rewardBgTop1/2/3 | 1125 x 1470 | 100vw | 131vw | 奖励模块背景 | +| giftItemBg | 450 x 450 | 约 40.25vw | 41vw | 奖励网格内两列项 | +| myRankingBg | 1125 x 306 | 100vw | 28vw | 底部固定我的排名 | +| helpInfoBg | 1125 x 1266 | 100vw | 113vw | 帮助弹窗背景 | + +## 6. 页面结构 + +### 6.1 Loading + +- `isLoading` 为 true 时展示 `LoadingContent`。 +- loading 容器使用内联样式撑满 `100vw` / `100vh`,居中显示。 +- 数据和阻塞图片加载完成后切换为页面主体。 + +### 6.2 主滚动容器 + +- 外层 `.fullPage` 固定 `100vw` / `100vh`,背景色 `#2a1046`。 +- 内容容器 `.bg` 负责纵向滚动,隐藏滚动条。 +- `.bg` 监听 `scroll.passive`,用于排行榜增量加载触发检查。 +- `MaskLayer` 在 `.bg :deep(.mask-layer)` 中修正为 fixed 全屏遮罩。 + +### 6.3 顶部背景和帮助按钮 + +顶部背景: + +```vue + +``` + +帮助按钮位置: + +- 按钮容器:`padding: 90vw 0 0; width: 100%; display: flex; justify-content: flex-end; align-items: center;` +- 按钮图片:`width: 10vw; margin-right: 4vw` +- 仅在页面内展示一个 `helpBt`,点击后 `maskLayerShow = true` +- 如果在 App 内,顶部额外占位 `height: 30px` + +### 6.4 倒计时 + +- 倒计时计算方式对齐 `src/views/Activities/Games/BountyFootball/index.vue`。 +- 截止时间:`2026-06-08 05:00:00` +- 代码写法:`new Date(2026, 5, 8, 5, 0, 0).getTime()` +- 倒计时展示字段:`Days`、`Hours`、`Minutes`、`Seconds` +- 天数后追加 `D`,时分秒之间使用英文冒号 `:` +- 倒计时区域内联样式: + - `margin-top: -10vw` + - `direction: ltr` + - `gap: 1vw` + - `padding: 0 4vw` +- 每个时间格外层宽度 `20vw`,内部 `itemCenter` 使用 `timeBg`,`min-height: 20vw`。 +- `timeText` 目前为 `font-size: 2em`、`font-weight: 600`。 + +### 6.5 模块切换按钮 + +当前有两个模块: + +| value | label | 图片 | 当前策略 | +| --- | --- | --- | --- | +| ranking | Ranking | rankingBt | 只有一张按钮图,非当前模块置灰 | +| reward | Rewards | rewardsBt | 只有一张按钮图,非当前模块置灰 | + +按钮区域: + +- `display: flex` +- `gap: 2vw` +- `margin-top: 4vw` +- `padding: 0 2vw` +- 每个按钮 `flex: 1` +- 非当前模块图片使用 `.grayscale-container`:`filter: grayscale(100%) brightness(90%)` + +### 6.6 排行榜模块 + +模块显示条件:`rankingShow` + +前三名: + +- 背景图:`RankingMain`,通过 `itemCenter` 承载。 +- `min-height: 99vw` +- `contentStyle="padding: 22vw 5vw 0; flex-direction: column;"` +- 第一名 `TopUser` 宽度 `55%`,头像框 `frameTop1` +- 第二名 `TopUser` 宽度 `34%`,头像框 `frameTop2` +- 第三名 `TopUser` 宽度 `34%`,头像框 `frameTop3` +- 第二、三名容器 `margin-top: -30%` +- 点击用户调用 `viewUserInfo(userId)` + +第四名及之后: + +- 使用 `RankingItem` 作为每条背景,`min-height: 28vw` +- `contentStyle="padding: 2vw 13vw 0;"` +- 使用 `v-for="(listItem, index) in showRanking"` +- 懒加载图片:`:lazy="true"`,前两条 `:immediate="index < 2"` +- 展示字段:排名、头像、昵称、用户 ID、金币值 +- 用户 ID 前缀使用 `$t('user_id_prefix')` +- 头像加载失败调用 `handleAvatarImageError` + +分页和增量加载: + +- 排行榜完整数据在 `rankingAllData` +- 当前渲染数据在 `Ranking` +- 初始和后续每批数量:`pageSize = 10` +- `appendRankingBatch()` 追加下一批 +- 触底判断同时使用滚动监听和 `IntersectionObserver` +- `IntersectionObserver` root 为 `bgRef`,`rootMargin: '0px 0px 150px 0px'` +- 防抖方法:`useDebounce(handleRankingLoadTrigger, 300)` + +底部边框: + +- 图片:`RankingBottomBorder` +- `width: 100%` +- `margin-top: -40vw` +- `z-index: 1` + +### 6.7 奖励模块 + +模块显示条件:`!rankingShow` + +- 外层 `display: flex; flex-direction: column; align-items: center` +- 每个奖励块 `width: 100%; margin: 10px 0` +- 背景图按排名取: + - `rewardBgTop1` + - `rewardBgTop2` + - `rewardBgTop3` +- 奖励背景 `itemCenter`:`min-height: 131vw` +- 内容网格: + - `grid-template-columns: repeat(2, minmax(0, 1fr))` + - `gap: 3.5vw` + - `padding: 25vw 8vw 6vw` +- 每个奖励项使用 `giftItemBg`,`min-height: 41vw` +- 奖励图片 `width: 70%` +- 奖励展示文本使用 `showDetail(reward.type, reward)`,内部调用 `formatRewardDisplay` +- 奖励图片失败调用 `handleRewardImageError(event, reward.type)` + +额外美元奖励逻辑: + +```js +const dollarRewards = [50, 30, 10] +``` + +接口返回 `butOneRewards` 后,会给前三个奖励组分别追加: + +- 第 1 组:`DOLLARS` 50 +- 第 2 组:`DOLLARS` 30 +- 第 3 组:`DOLLARS` 10 + +### 6.8 底部我的排名 + +- 固定在底部:`position: fixed; bottom: 0; left: 0; z-index: 2` +- 背景图:`myRankingBg` +- `min-height: 28vw` +- `contentStyle="padding: 2vw 8vw 0;"` +- 底部占位:`
` +- 默认排名:`myRanking.rank || 999` +- 默认金币值:`myRanking.quantity || 0` + +### 6.9 帮助弹窗 + +- 弹窗使用 `maskLayer` +- 背景图:`helpInfoBg`,支持多语言图片 +- 弹窗外层:`width: 100%; margin: 20% 0` +- `itemCenter`:`min-height: 113vw` +- `contentStyle="inset: 25vw 7vw 10vw; overflow-y: auto; display: block;"` +- 文案不再硬编码在 Vue 中,当前使用多语言 key: + +```js +const helpRuleKeys = [ + 'greedy_king_help_rule_1', + 'greedy_king_help_rule_2', + 'greedy_king_help_rule_3', + 'greedy_king_help_rule_4', + 'greedy_king_help_rule_5', +] +``` + +模板渲染: + +```vue +

{{ $t(ruleKey) }}

+``` + +当前已补充语言文件: + +- `src/locales/en.json` +- `src/locales/zh.json` +- `src/locales/ar.json` +- `src/locales/tr.json` +- `src/locales/bn.json` + +英文文案: + +1. The more coins a user accumulates during the event, the higher their ranking will be. +2. The event will last for 15 days. After the event ends, rewards will be distributed to the top three users on the leaderboard. +3. The top three users should contact the official staff in a timely manner to discuss how to obtain the USD reward. +4. (1) Withdrawal: Please provide your USDT receiving account ID or receiving QR code. +5. (2) No withdrawal: If converted to coins, we will give you an additional 5% gold coins on top of the original amount ($1:10500 coins). + +## 7. 接口和字段映射 + +### 7.1 排行榜接口 + +接口:`getRankingListAndMyRanking` + +请求参数: + +```js +{ + activityType: pageConfig.activity.activityType, + cycleKey: pageConfig.activity.cycleKey, + cycleType: pageConfig.activity.cycleType, +} +``` + +返回字段: + +- 我的排名:`body.currentUserRank` +- 排行榜列表:`body.rankingList` + +字段归一化: + +```js +{ + userId: user.userId || user.uid || user.id || '', + avatar: user.avatar || user.userAvatar || '', + nickname: user.nickname || user.userName || user.userNickname || '', + quantity: user.quantity ?? user.amount ?? user.total ?? 0, + rank: user.rank ?? user.ranking ?? (index === null ? '' : index + 1), + account: user.account || user.specialAccount || '', +} +``` + +### 7.2 奖励接口 + +接口:`getThisWeekRewardsAndGifts` + +请求参数: + +```js +pageConfig.activity.templateId +``` + +返回使用: + +- `resRewards.body.butOneRewards` +- 经过 `appendLegacyDollarRewards()` 追加前三名美元奖励后写入 `rewardsList` + +## 8. 组件依赖 + +| 组件 / 方法 | 来源 | 当前用途 | +| --- | --- | --- | +| itemCenter | `@/components/itemCenter.vue` | 承载背景图和绝对定位内容 | +| maskLayer | `@/components/MaskLayer.vue` | 帮助弹窗遮罩 | +| TopUser | `./components/topUser.vue` | 展示排行榜前三名 | +| LoadingContent | 全局组件 | 页面阻塞加载提示 | +| getPngUrl | `@/config/imagePaths.js` | 生成 OSS 图片路径 | +| preloadImages / preloadImagesIdle | `@/utils/image/imagePreloader.js` | 阻塞和空闲图片预加载 | +| handleAvatarImageError | `@/utils/image/imageHandler.js` | 头像兜底 | +| handleRewardImageError | `@/utils/image/imageHandler.js` | 奖励图片兜底 | +| formatRewardDisplay | `@/utils/rewardFormatter.js` | 奖励文本格式化 | +| useDebounce | `@/utils/useDebounce.js` | 排行榜触底加载防抖 | +| connectToApp / isInApp / viewUserInfo | `@/utils/appBridge.js` / `@/utils/appConnector.js` | App 连接、环境判断、跳转用户信息 | + +## 9. 样式记录 + +- 当前页面开发阶段以“结构附近内联样式”为主。 +- 一次性布局、尺寸、间距、定位基本写在模板内联样式里,方便继续按图微调。 +- 保留 class 的部分: + - `.fullPage` + - `.bg` + - `.timeText` + - `.grayscale-container` + - `.ranking-user` + - `.ranking-rank` + - `.ranking-name-box` + - `.ranking-name` + - `.ranking-account` + - `.ranking-value` + - `.coin-icon` + - `.helpInfo` + - `.UserNickname` + - 响应式基础字号 media query +- 响应式字号: + - `max-width: 360px`:`10px` + - `min-width: 360px`:`14px` + - `min-width: 768px`:`24px` + - `min-width: 1024px`:`32px` + +## 10. 当前已完成 + +- 已按当前 `index.vue` 同步页面创建信息。 +- 已使用 `itemCenter :imgUrl="imageUrl('bg')"` 承载主背景。 +- 已按实际图片宽高比为所有 `itemCenter` 背景设置 `min-height`。 +- 已将模块按钮改为单图置灰策略。 +- 已接入多语言图片规则。 +- 已将帮助弹窗文本改为 `greedy_king_help_rule_*` 多语言 key。 +- 已按 BountyFootball 方式实现倒计时,截止时间为 `2026-06-08 05:00:00`。 +- 已保留旧页面的前三名美元奖励追加逻辑:`50 / 30 / 10`。 + +## 11. 待确认 + +- 活动参数 `templateId`、`activityType`、`cycleType`、`cycleKey` 是否需要替换为新活动真实参数。 +- 当前排行榜和奖励接口字段是否与最终后端返回完全一致。 +- 后续预览后可继续微调: + - 顶部帮助按钮位置 + - 倒计时整体 `margin-top` + - 排行榜前三名布局间距 + - 奖励网格内边距 + - 帮助弹窗文本内边距和滚动区域 + +## 12. 验证记录 + +- 最近一次 `npm run build`:通过。 +- 已验证 locale JSON 可解析。 +- 构建中仍保留项目既有提示: + - `../assets/images/Azizi/secondBg.png` 运行时解析提示 + - `src/utils/http.js` 动态 / 静态导入提示