diff --git a/src/config/security.js b/src/config/security.js index ac93f2e..142873e 100644 --- a/src/config/security.js +++ b/src/config/security.js @@ -21,6 +21,7 @@ export const PUBLIC_PATHS = Object.freeze([ '/daily-recharge', '/activities/gulben-festival', '/activities/bounty-football', + '/activities/world-cup', '/activities/lucky-dollars-season5', '/activities/lucky-dollars-season4', '/activities/lesser-bairam', diff --git a/src/router/index.js b/src/router/index.js index 20458d5..7c4909f 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -446,6 +446,12 @@ const router = createRouter({ }, //2026年3月14日上午5点结束 //游戏活动 + { + path: '/activities/world-cup', + name: 'world-cup', + component: () => import('../views/Activities/WorldCup/index.vue'), + meta: { requiresAuth: false }, + }, // WorldCup { path: '/activities/bounty-football', name: 'bounty-football', diff --git a/src/utils/permissionManager.js b/src/utils/permissionManager.js index 826de3c..5a2032d 100644 --- a/src/utils/permissionManager.js +++ b/src/utils/permissionManager.js @@ -65,6 +65,7 @@ const ACTIVITIES = [ '/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', // 斋月打榜 diff --git a/src/views/Activities/WorldCup/components/topUser.vue b/src/views/Activities/WorldCup/components/topUser.vue new file mode 100644 index 0000000..b5369e2 --- /dev/null +++ b/src/views/Activities/WorldCup/components/topUser.vue @@ -0,0 +1,182 @@ + + + + + diff --git a/src/views/Activities/WorldCup/index.vue b/src/views/Activities/WorldCup/index.vue new file mode 100644 index 0000000..d4eab6a --- /dev/null +++ b/src/views/Activities/WorldCup/index.vue @@ -0,0 +1,573 @@ + + + + + diff --git a/src/views/Activities/WorldCup/page.config.js b/src/views/Activities/WorldCup/page.config.js new file mode 100644 index 0000000..f4592ce --- /dev/null +++ b/src/views/Activities/WorldCup/page.config.js @@ -0,0 +1,47 @@ +export const pageConfig = { + name: 'WorldCup', + routePath: '/activities/world-cup', + routeName: 'world-cup', + assetPath: 'Activities/WorldCup/', + + activity: { + activityId: '', + activityCode: '', + activityType: 19, + rankingActivityType: '', + rewardActivityType: '', + }, + + preload: { + blocking: [], + background: [], + }, + + modules: { + tabs: { + enabled: false, + defaultValue: '', + items: [], + }, + sections: [], + popups: [], + features: [ + { + name: 'countdown', + enabled: false, + deadline: '', + images: ['timeBg'], + fields: { + endTime: '', + remainingText: '', + }, + remark: + '倒计时模块占位;本地图片清单尚未扫描到 timeBg,待补充素材和截止时间后再启用。', + }, + ], + }, + + images: { + localized: {}, + }, +} diff --git a/src/views/Activities/WorldCup/页面创建信息.md b/src/views/Activities/WorldCup/页面创建信息.md new file mode 100644 index 0000000..0a59954 --- /dev/null +++ b/src/views/Activities/WorldCup/页面创建信息.md @@ -0,0 +1,279 @@ +# 页面创建信息 + +## 1. 基础信息 + +- 页面类型:Activities +- 页面名称:WorldCup +- 页面目录:src/views/Activities/WorldCup +- 参考页面: +- 备注:已生成 `index.vue` 可预览页面底座,目前完成头部和排行榜模块;排行榜接口和字段规则参考 `GulbenFestival` 的 personalRank / Ranking。 + +## 2. 路由和权限 + +- route path:/activities/world-cup +- route name:world-cup +- 是否需要登录:否 +- 是否加入 `src/config/security.js`:是 +- 是否加入 `src/utils/permissionManager.js`:是 + +### 2.1 路由代码片段 + +```js +{ + path: '/activities/world-cup', + name: 'world-cup', + component: () => import('../views/Activities/WorldCup/index.vue'), + meta: { requiresAuth: false }, +} +``` + +### 2.2 安全白名单片段 + +```js +'/activities/world-cup', +``` + +### 2.3 权限页面片段 + +```js +'/activities/world-cup', // WorldCup +``` + +## 3. OSS 图片目录 + +- OSS 相对路径:Activities/WorldCup/ +- 本地开发目录:public/oss/h5/Azizi/Activities/WorldCup/ +- 是否需要 Codex 自动创建本地开发目录:是 +- 图片是否已放入本地目录:是 + +说明:本地开发目录只作为开发期 OSS 图片镜像使用,方便页面优先读取本地资源;发布时图片由你上传到真实 OSS,不随项目提交 Git。新建本地目录时不生成 `.gitkeep`,空目录不被 Git 跟踪是正常现象。 + +### 3.1 多语言图片清单 + +| 图片名 | 支持语言 | 备注 | +| --- | --- | --- | +| bg | 默认 | 头部主背景图 | +| bg2 | 默认 | 页面最低层背景图,拉伸铺满 100vh 视口 | +| RankingMain | 默认 | 排行榜主背景,内部上方展示前三名,下方展示 Show All Users | +| RankingItem | 默认 | 第四名以后排行榜列表项背景 | +| RankingBottomBorder | 默认 | 排行榜底边框 | +| frameTop1 | 默认 | 第一名头像框 | +| frameTop2 | 默认 | 第二名头像框 | +| frameTop3 | 默认 | 第三名头像框 | +| ruleBt | 默认 | 规则按钮 | +| showMoreBt | 默认 | 展开/收起排行榜按钮图标 | +| vip1-vip6 | 默认 | VIP 等级图片 | +| userLevel1Bg-userLevel5Bg | 默认 | 魅力等级背景 | +| wealthLevel1Bg-wealthLevel5Bg | 默认 | 财富等级背景 | + +### 3.2 进入页面前同步预加载图片 + +| 图片名 | 是否包含多语言 | 备注 | +| --- | --- | --- | +| bg2 | 否 | 页面最低层背景 | +| bg | 否 | 头部背景 | +| ruleBt | 否 | 规则按钮 | +| RankingMain | 否 | 排行榜主背景 | +| RankingItem | 否 | 排行榜列表项背景 | +| RankingBottomBorder | 否 | 排行榜底边框 | +| showMoreBt | 否 | 展开/收起按钮图标 | +| frameTop1 | 否 | 第一名头像框 | +| frameTop2 | 否 | 第二名头像框 | +| frameTop3 | 否 | 第三名头像框 | +| vip1-vip6 | 否 | VIP 等级图片 | +| userLevel1Bg-userLevel5Bg | 否 | 魅力等级背景 | +| wealthLevel1Bg-wealthLevel5Bg | 否 | 财富等级背景 | + +### 3.3 进入页面后后台预加载图片 + +| 图片名 | 是否包含多语言 | 备注 | +| --- | --- | --- | +| footballSign | 否 | 后续模块素材,当前未使用 | +| giftBt | 否 | 后续模块素材,当前未使用 | +| matchBg | 否 | 后续模块素材,当前未使用 | +| myRankingBg | 否 | 后续我的排名素材,当前未使用 | +| numPeople | 否 | 后续模块素材,当前未使用 | +| rewardBg | 否 | 后续奖励模块素材,当前未使用 | +| ruleBg | 否 | 后续规则弹窗素材,当前未接弹窗 | +| statusEndedfail | 否 | 后续状态素材,当前未使用 | +| statusEndedWin | 否 | 后续状态素材,当前未使用 | +| statusInProgress | 否 | 后续状态素材,当前未使用 | +| statusNotStarted | 否 | 后续状态素材,当前未使用 | + +## 4. 模块配置 + +当前页面按用户逐步补充需求生成,只处理已明确指定模块。 + +### 4.1 标签页模块 + +```json +{ + "enabled": false, + "defaultValue": "", + "items": [] +} +``` + +### 4.2 页面区块模块 + +```json +[ + { + "name": "header", + "enabled": true, + "images": ["bg", "ruleBt"], + "layout": { + "container": "itemCenter", + "containerStyle": "width: 100vw", + "contentStyle": "padding: 87vw 0 0; align-items: flex-start; justify-content: flex-start; box-sizing: border-box;", + "ruleRowStyle": "width: 100%; display: flex; justify-content: flex-end", + "ruleButtonStyle": "width: 13.6vw; display: block" + }, + "remark": "头部背景使用 bg,内部只放贴右 ruleBt。" + }, + { + "name": "ranking", + "enabled": true, + "images": [ + "RankingMain", + "RankingItem", + "RankingBottomBorder", + "frameTop1", + "frameTop2", + "frameTop3", + "showMoreBt", + "vip1-vip6", + "userLevel1Bg-userLevel5Bg", + "wealthLevel1Bg-wealthLevel5Bg" + ], + "layout": { + "sectionStyle": "position: relative; width: 100vw", + "backgroundStyle": "position: absolute; inset: 15vw 2vw 4vw; z-index: 0; background-color: #053126", + "rankingMainStyle": "width: 100vw", + "rankingMainContentStyle": "direction: ltr; padding: 0; flex-direction: column; align-items: center; justify-content: space-between; box-sizing: border-box;", + "topModuleStyle": "width: 100%; padding: 20vw 6vw 0; display: flex; align-items: flex-start; justify-content: center; box-sizing: border-box;", + "topThreeStyle": "width: 100%; height: 45vw; display: flex; align-items: flex-end; justify-content: space-between; gap: 1vw;", + "topUserOrder": "左二、中一、右三;第二名 width:24vw order:1,第一名 width:26vw order:2,第三名 width:24vw order:3", + "showMoreStyle": "width: 100%; padding: 0 0 4vw; position: relative; z-index: 2; display: flex; align-items: center; justify-content: center; gap: 2vw; color: #fff; font-size: 1.2em; font-weight: 800; line-height: 1;", + "showMoreImageStyle": "width: 10vw; display: block", + "rankingItemStyle": "width: 100vw; margin-top: -2vw", + "rankingItemContentStyle": "padding: 3vw 8vw 0; box-sizing: border-box; justify-content: space-between;", + "collapseStyle": "position: relative; z-index: 2; width: 100vw; padding: 2vw 0 4vw; display: flex; align-items: center; justify-content: center; gap: 2vw; color: #fff; font-size: 1.2em; font-weight: 800; line-height: 1;", + "collapseImageStyle": "width: 10vw; display: block; transform: scaleY(-1)", + "bottomBorderStyle": "position: relative; z-index: 1; display: block; width: 100vw; margin-top: -9vw; pointer-events: none" + }, + "interaction": { + "defaultExpanded": false, + "showText": "Show All Users", + "collapseText": "Collapse List", + "showAction": "点击 Show All Users 后 showRankingList=true,开始展示 RankingItem 列表。", + "collapseAction": "点击 Collapse List 后 showRankingList=false,隐藏 RankingItem 列表。" + }, + "remark": "RankingMain 内部从上到下分为前三名模块和展示更多模块;第四名以后列表默认隐藏。" + } +] +``` + +倒计时模块占位: + +```json +{ + "name": "countdown", + "enabled": false, + "deadline": "", + "images": ["timeBg"], + "fields": { + "endTime": "", + "remainingText": "" + }, + "remark": "倒计时模块占位;本地图片清单尚未扫描到 timeBg,待补充素材和截止时间后再启用。" +} +``` + +### 4.3 弹窗模块 + +```json +[] +``` + +## 5. 接口参数 + +```json +{ + "activityId": "", + "activityCode": "", + "activityType": 19, + "rankingActivityType": "", + "rewardActivityType": "", + "otherParams": {} +} +``` + +## 6. 组件需求 + +需要哪一个就填“是”,不需要或没填写的初版页面先不接。 + +```json +[ + { + "name": "BackgroundLayer", + "enabled": "是", + "remark": "长背景分段" + }, + { + "name": "itemCenter", + "enabled": "是", + "remark": "图片容器" + }, + { + "name": "topUser / TopUser", + "enabled": "是", + "remark": "前三名用户展示" + }, + { + "name": "Barrage", + "enabled": "", + "remark": "弹幕" + }, + { + "name": "ActivityTabs", + "enabled": "", + "remark": "标签页" + }, + { + "name": "ActivityLotteryGrid", + "enabled": "", + "remark": "抽奖格子" + } +] +``` + +## 7. 建页后记录 + +### 7.1 已完成 + +- 创建页面目录:`src/views/Activities/WorldCup/` +- 创建专属页面信息文件:`src/views/Activities/WorldCup/页面创建信息.md` +- 创建初始配置文件:`src/views/Activities/WorldCup/page.config.js` +- 创建本地开发图片目录:`public/oss/h5/Azizi/Activities/WorldCup/` +- 写入路由:`/activities/world-cup` +- 写入 `src/config/security.js` 白名单 +- 写入 `src/utils/permissionManager.js` 活动页权限列表 +- 创建并持续更新 `index.vue` 可预览页面 +- 创建 `components/topUser.vue` 私有前三名组件 +- 完成统一加载动画、页面背景、头部模块、排行榜前三名、排行榜接口和展开/收起列表交互 + +### 7.2 未填写所以跳过 + +- 规则弹窗暂未接点击事件和弹窗内容。 +- 赛事、奖励、任务、我的排名等素材暂未生成对应业务模块。 + +### 7.3 待你微调 + +- 继续按预览效果微调排行榜位置、间距和展开/收起按钮位置。 +- 后续补规则弹窗、赛事、奖励、任务、我的排名等模块时继续先更新本 md,再同步 Vue。 + +### 7.4 验证结果 + +- `npm run build`:已运行并通过。 +- 备注:构建中存在项目原有 warning:`secondBg.png` 运行时解析提示,以及 `src/utils/http.js` 动静态混用 chunk 提示。