# 建页资料库 这份文档存放建页时常用但不需要每次都手写的信息:组件用法、常用图片名、配置片段。 ## 1. 常用组件用法 ### 1.1 BackgroundLayer 用途:长页面背景分段渲染,适合 `bg0/bg1/bg2/bg3` 这类长活动页。 ```vue ``` ### 1.2 itemCenter 用途:背景图 + 内部绝对定位内容,是活动页最常用的图片容器。 ```vue ``` ### 1.3 topUser / TopUser 用途:前三名用户展示。不同页面可能有自己的 `components/topUser.vue`,新页面可先从参考页面复制一份再微调。 ```vue ``` ```js import TopUser from './components/topUser.vue' ``` ### 1.4 Barrage 用途:中奖用户、活动动态等弹幕。LuckyDollars 页面常用。 ```vue ``` ```js import Barrage from './components/Barrage.vue' ``` ### 1.5 ActivityTabs 用途:图片背景标签页。适合初始页面快速搭标签切换。 ```vue ``` ### 1.6 ActivityLotteryGrid 用途:抽奖格子、高亮框和中心按钮区域。不同抽奖背景只改 `page.config.js` 里的布局。 ```vue ``` ## 2. 常用图片名清单 下面的图片名来自 `src/views/Activities` 和 `src/views/Ranking` 中常见的 `imageUrl('xxx')`、`webpUrl('xxx')`、`getImgName('xxx')` 用法。新页面不需要全部准备,按模块挑选即可。 注意:图片名大小写必须和文件名一致。项目里已有一些历史命名,例如 `RankingItem`、`RankingBottomBorder`、`rechargehidden`,这里按现有代码保留。 ### 2.1 页面背景和顶部 ```js imageUrl('bg') // 页面主背景 imageUrl('bg0') // 页面背景第 0 段 imageUrl('bg1') // 页面背景第 1 段 imageUrl('bg2') // 页面背景第 2 段 imageUrl('bg3') // 页面背景第 3 段 webpUrl('pageTop') // 页面顶部 WebP 背景 imageUrl('timeBg') // 活动时间背景 imageUrl('dayBg') // 日期/天数背景 imageUrl('TimeBg') // 活动时间背景,历史大写命名 ``` ### 2.1.1 排行榜前几名展示区 推荐新页面使用 `rankingTopBg`,含义更明确:排行榜前几名展示区背景,不限定一定是前三名。 ```js imageUrl('rankingTopBg') // 排行榜前几名展示区背景,推荐新命名 imageUrl('topBg') // 排行榜前几名展示区背景,历史命名,不再作为页面顶部背景理解 imageUrl('top1') // 第一名头像/排名装饰 imageUrl('top2') // 第二名头像/排名装饰 imageUrl('top3') // 第三名头像/排名装饰 imageUrl('top1Bg') // 第一名独立背景 imageUrl('top2Bg') // 第二名独立背景 imageUrl('top3Bg') // 第三名独立背景 ``` ### 2.2 标签页和按钮 ```js imageUrl('tagsBg') // 标签页整体背景 imageUrl('tagBtBg') // 标签页选中底图 imageUrl(getImgName('rankBt')) // 排行榜未选中按钮 imageUrl(getImgName('rankBtActive')) // 排行榜选中按钮 imageUrl(getImgName('rankingBt')) // 排行按钮 imageUrl(getImgName('rankingBtActive')) // 排行选中按钮 imageUrl(getImgName('lotteryBt')) // 抽奖未选中按钮 imageUrl(getImgName('lotteryBtActive')) // 抽奖选中按钮 imageUrl(getImgName('rewardBt')) // 奖励未选中按钮 imageUrl(getImgName('rewardBtActive')) // 奖励选中按钮 imageUrl(getImgName('rechargeBt')) // 充值未选中按钮 imageUrl(getImgName('rechargeBtActive')) // 充值选中按钮 imageUrl(getImgName('redeemBt')) // 兑换按钮 imageUrl(getImgName('withdrawalBt')) // 提现未选中按钮 imageUrl(getImgName('withdrawalBtActive')) // 提现选中按钮 ``` ### 2.3 排行榜 ```js imageUrl('RankingMain') // 排行榜主体背景 imageUrl('RankingItem') // 排行榜列表项背景 imageUrl('rankingItemBg') // 排行榜列表项背景,另一套命名 imageUrl('RankingTopBorder') // 排行榜顶部边框 imageUrl('RankingBottomBorder') // 排行榜底部边框 imageUrl('RankingBorder') // 排行榜通用边框 imageUrl('myRankingBg') // 我的排名固定栏背景 imageUrl('rankingNumBg') // 排名数字背景 imageUrl('rankingTopBg') // 排行榜前几名展示区背景,推荐新命名 imageUrl('topBg') // 排行榜前几名展示区背景,历史命名 imageUrl('top1') // 第一名头像/排名装饰 imageUrl('top2') // 第二名头像/排名装饰 imageUrl('top3') // 第三名头像/排名装饰 imageUrl('top1Bg') // 第一名独立背景 imageUrl('top2Bg') // 第二名独立背景 imageUrl('top3Bg') // 第三名独立背景 imageUrl('top1-charm') // 魅力榜第一名装饰 imageUrl('top2-charm') // 魅力榜第二名装饰 imageUrl('top3-charm') // 魅力榜第三名装饰 imageUrl('top1-wealth') // 财富榜第一名装饰 imageUrl('top2-wealth') // 财富榜第二名装饰 imageUrl('top3-wealth') // 财富榜第三名装饰 imageUrl('top1-room') // 房间榜第一名装饰 imageUrl('top2-room') // 房间榜第二名装饰 imageUrl('top3-room') // 房间榜第三名装饰 imageUrl('myRankingBg-charm') // 魅力榜我的排名背景 imageUrl('myRankingBg-wealth') // 财富榜我的排名背景 imageUrl('myRankingBg-room') // 房间榜我的排名背景 imageUrl('RankingItem-charm') // 魅力榜列表项背景 imageUrl('RankingItem-wealth') // 财富榜列表项背景 imageUrl('RankingItem-room') // 房间榜列表项背景 imageUrl('tabSelectedBg') // 榜单分类选中底图 imageUrl('rankingSeasonBt') // 赛季榜按钮 imageUrl('rankingSeasonBtActive') // 赛季榜选中按钮 imageUrl('rankingWeeklyBt') // 周榜按钮 imageUrl('rankingWeeklyBtActive') // 周榜选中按钮 ``` ### 2.4 抽奖 ```js imageUrl('lottery') // 抽奖机/抽奖盘背景 imageUrl('lotteryBg') // 抽奖区域背景 imageUrl('prizeActiveFrame') // 抽奖高亮框 imageUrl('draw1BtBg') // 单抽按钮背景 imageUrl('draw5BtBg') // 五连抽按钮背景 imageUrl('draw10BtBg') // 十连抽按钮背景 imageUrl('resultBg') // 中奖结果弹窗背景 imageUrl('resultBack') // 中奖结果上一页按钮 imageUrl('resultNext') // 中奖结果下一页按钮 imageUrl('resultBt') // 中奖结果确认按钮 imageUrl('resultGoOnBt') // 继续抽奖按钮 ``` ### 2.5 奖励和奖品 ```js imageUrl('rewardBg') // 奖励模块背景 imageUrl('reward_banner') // 奖励横幅 imageUrl('rewards') // 奖励集合图 imageUrl('rewardBack') // 奖励上一页按钮 imageUrl('rewardNext') // 奖励下一页按钮 imageUrl(getImgName('rewardReceive')) // 奖励领取按钮 imageUrl(getImgName('rewardReceived')) // 奖励已领取按钮 imageUrl(getImgName('rewardReceiveNot')) // 奖励不可领取按钮 imageUrl(getImgName('receiveBt')) // 领取按钮 imageUrl(getImgName('receivedBt')) // 已领取按钮 imageUrl('reward_gift') // 礼物奖励图标 imageUrl('reward_frame') // 头像框奖励图标 imageUrl('reward_ride') // 座驾奖励图标 imageUrl('ticket') // 抽奖券图标 imageUrl('crystal') // 水晶/活动货币图标 imageUrl('debris') // 碎片/道具图标 imageUrl('giftBg') // 礼物背景 imageUrl('giftItemBg') // 礼物列表项背景 imageUrl('RewardRecharge100') // 充值 100 奖励图 imageUrl('RewardRecharge500') // 充值 500 奖励图 imageUrl('RewardRecharge1000') // 充值 1000 奖励图 imageUrl('RewardRecharge3000') // 充值 3000 奖励图 imageUrl('RewardRecharge5000') // 充值 5000 奖励图 imageUrl('RewardRecharge10000') // 充值 10000 奖励图 imageUrl('rechargeReward100') // 充值 100 奖励图,另一套命名 imageUrl('rechargeReward500') // 充值 500 奖励图,另一套命名 imageUrl('rechargeReward1000') // 充值 1000 奖励图,另一套命名 imageUrl('rechargeReward3000') // 充值 3000 奖励图,另一套命名 imageUrl('rechargeReward5000') // 充值 5000 奖励图,另一套命名 imageUrl('rechargeReward10000') // 充值 10000 奖励图,另一套命名 ``` ### 2.6 任务 ```js imageUrl('taskBtGo') // 任务去完成按钮 imageUrl('taskBtReceive') // 任务领取按钮 imageUrl('taskBtReceived') // 任务已领取按钮 imageUrl('taskGame') // 游戏任务图标 imageUrl('taskGift') // 送礼任务图标 imageUrl('taskRecharge') // 充值任务图标 imageUrl('taskTalk') // 聊天/上麦任务图标 imageUrl('taskItemBg') // 任务列表项背景 imageUrl('taskListBg') // 任务列表背景 imageUrl('taskTypeGame') // 游戏任务类型图标 imageUrl('taskTypeGift') // 礼物任务类型图标 ``` ### 2.7 弹窗、规则、帮助和历史 弹窗遮罩统一使用公共组件 `src/components/MaskLayer.vue`,不要在页面里重复手写固定定位遮罩、背景滚动锁定和滚动阻止逻辑。弹窗内容放入默认插槽;如果要点击空白关闭,在插槽内包一层全屏容器并绑定 `@click.self`。 ```vue
``` ```js imageUrl(getImgName('helpInfo')) // 帮助说明图片 imageUrl('helpBg') // 帮助弹窗背景 imageUrl('helpBt') // 帮助按钮 imageUrl(getImgName('ruleInfo')) // 规则说明图片 imageUrl('ruleInfoBg') // 规则弹窗背景 imageUrl(getImgName('ruleTitle')) // 规则标题图 imageUrl(getImgName('rulesBt')) // 规则按钮 imageUrl(getImgName('historyBt')) // 历史按钮 imageUrl(getImgName('historyBg')) // 历史弹窗背景 imageUrl('historyTopBg') // 历史弹窗顶部背景 imageUrl('recordBg') // 记录列表背景 imageUrl('closeBt') // 关闭按钮 ``` ### 2.8 用户信息、充值和收益 ```js imageUrl('myInfoBg') // 我的信息背景 imageUrl('myAvatarFrame') // 我的头像框 imageUrl('userNameBorder') // 用户名边框 imageUrl('userFrame') // 用户头像框 imageUrl('earningInfoBg') // 收益信息背景 imageUrl('earningsBg') // 收益背景 imageUrl('distribution') // 分发/派奖图标 imageUrl('rechargehidden') // 充值金额隐藏图标 imageUrl('rechargeShow') // 充值金额显示图标 imageUrl('rechargeNumHidden') // 充值数字隐藏图标 imageUrl('rechargeNumShow') // 充值数字显示图标 imageUrl('amountHiddenBt') // 金额隐藏按钮 imageUrl('amountShowBt') // 金额显示按钮 ``` ### 2.9 游戏玩法和特殊模块 ```js imageUrl('gameLotteryBt') // 游戏玩法-抽奖按钮 imageUrl('gameLotteryBtActive') // 游戏玩法-抽奖选中按钮 imageUrl('gameSignInBt') // 游戏玩法-签到按钮 imageUrl('gameSignInBtActive') // 游戏玩法-签到选中按钮 imageUrl('gameExchangeBt') // 游戏玩法-兑换按钮 imageUrl('gameExchangeBtActive') // 游戏玩法-兑换选中按钮 imageUrl('goodsItem') // 兑换商品项背景 imageUrl('makeUpBtBg') // 补签按钮背景 imageUrl('rewardGoodsBg') // 奖励物品背景 imageUrl('progressBar') // 进度条图片 imageUrl('timeBack') // 时间/日期上一页按钮 imageUrl('timeNext') // 时间/日期下一页按钮 ``` ## 3. 模块预设 这些预设用于创建“页面创建信息 md”时自动填充,目标是少问、少填、先生成能跑的初版。图片字段优先从 `3.1 多语言图片清单` 中匹配;没有匹配到的图片名可以留空或标记待确认。 ### 3.1 Activities 通用活动页 适用:`src/views/Activities` 下类似 LuckyDollars、LesserBairam、SpringFestival 的活动页。 ```json { "reward": { "enabledWhenAnyImageExists": ["rewardBg", "rewardReceive", "rewardReceived", "rewardReceiveNot"], "apis": ["activityRewardConfigs", "myRecharge", "receiveRechargeReward"], "defaultImages": ["rewardBg", "rewardReceive", "rewardReceived", "rewardReceiveNot", "ticket", "reward_gift", "reward_frame", "reward_ride"], "remark": "充值/消费奖励模块" }, "ranking": { "enabledWhenAnyImageExists": ["RankingItem", "myRankingBg", "rankingTopBg", "topBg", "top1", "top2", "top3", "rankBt", "rankBtActive"], "apis": ["ranklist"], "loadMode": "remote", "pageSize": 20, "topCount": 3, "myRankingPath": "ranklist.body.currentUser", "fieldMap": { "avatar": "userAvatar", "name": "userName", "value": "amount", "userId": "userId", "rank": "rank" }, "defaultImages": ["RankingItem", "myRankingBg", "rankingTopBg", "top1", "top2", "top3"], "remark": "活动内排行榜,常见为接口分页" }, "lottery": { "enabledWhenAnyImageExists": ["lottery", "lotteryBg", "prizeActiveFrame", "lotteryBt", "lotteryBtActive"], "drawApis": ["onceDraw", "multiDraw"], "prizePoolApi": "activityDetail", "drawCountApi": "myTickets", "extraApis": ["myTotalDrawCount", "rewardConfigsBadge", "winnerHistory"], "historyApi": "drawRecords", "displayMode": "track-only", "slotCount": 8, "historyButtonPosition": "inside", "defaultImages": { "background": "lottery", "activeFrame": "prizeActiveFrame", "historyButton": "historyBt", "resultBackground": "resultBg" }, "remark": "抽奖接口基本固定;奖品展示方式按页面图片调整" }, "task": { "enabledWhenAnyImageExists": ["taskBtGo", "taskBtReceive", "taskBtReceived", "taskGame", "taskGift", "taskRecharge", "taskTalk"], "apis": ["ActTaskList", "receiveTickets"], "defaultImages": ["taskBtGo", "taskBtReceive", "taskBtReceived", "taskGame", "taskGift", "taskRecharge", "taskTalk"], "remark": "任务列表和任务领奖" }, "withdraw": { "enabledWhenAnyImageExists": ["earningInfoBg", "myInfoBg"], "apis": ["withdrawableAmount", "transferActivityDollar", "exchangeCoin"], "defaultImages": ["earningInfoBg", "myInfoBg"], "remark": "提现、转账或兑换模块" }, "popups": { "rule": { "enabledWhenAnyImageExists": ["rulesBt", "ruleInfo"], "triggerImage": "rulesBt", "contentImage": "ruleInfo" }, "help": { "enabledWhenAnyImageExists": ["helpBt", "helpInfo"], "triggerImage": "helpBt", "contentImage": "helpInfo" }, "history": { "enabledWhenAnyImageExists": ["historyBt", "historyBg"], "triggerImage": "historyBt", "backgroundImage": "historyBg", "apis": ["drawRecords"] } } } ``` ### 3.2 Ranking 独立排行榜页 适用:`src/views/Ranking` 下独立排行榜页。这里要特别区分加载方式: - `remote`:接口支持 `pageNo/pageSize`,上拉时继续请求下一页。 - `local`:接口一次返回完整榜单,前端先展示一段,上拉时 `slice` 下一段,例如 `src/views/Ranking/Overall/Ranking.vue`。 ```json { "ranking": { "loadMode": "local / remote", "topCount": 3, "pageSize": 10, "fieldMap": { "avatar": "avatar", "name": "nickname", "value": "quantityFormat", "userId": "id", "rank": "rank" }, "commonImages": [ "RankingItem", "myRankingBg", "top1", "top2", "top3", "tabSelectedBg" ], "remark": "如果接口差异不明确,先问用户参考哪个 Ranking 页面" } } ``` ### 3.3 什么时候需要问用户 ```text 同一模块存在多个接口版本时,问参考页面。 抽奖模块不是 8 格或不是 track-only 时,问抽奖展示方式。 排行榜接口不知道是 remote 还是 local 时,问参考页面或看接口是否传 pageNo/pageSize。 图片名看不出用途且无法从参考页面推断时,标记待确认,不阻塞初版生成。 ``` ## 4. 页面配置片段 ### 4.1 图片工具 ```js import { useActivityAssets } from '@/composables/activity/useActivityAssets.js' import { pageConfig } from './page.config.js' const currentLangType = computed(() => { return langStore.selectedLang?.type || 'en' }) const { imageUrl, webpUrl, getImageName: getImgName } = useActivityAssets( pageConfig, currentLangType, ) ``` ### 4.2 标签页 ```js import { useActivityTabs } from '@/composables/activity/useActivityTabs.js' const { currentTab, visibleTabs, isTab, changeTab } = useActivityTabs(pageConfig.tabs, { translate: t, }) ``` #### 4.2.1 嵌套标签 children 用途:描述“一级标签下还有二级标签/子区块”的页面结构,例如 Gulben Festival 的 `Personal Rank` 和 `Room Rank` 下再分 `Reward / Ranking`。 推荐配置形态: ```js modules: { tabs: { enabled: true, defaultValue: 'Personal Rank', items: ['CollectCards to Win Prizes', 'Personal Rank', 'Room Rank'], }, sections: [ { name: 'personalRank', enabled: true, images: ['tagActiveBg', 'tagBg'], children: { tabs: { enabled: true, defaultValue: 'Reward', items: ['Reward', 'Ranking'], }, sections: [ { name: 'Reward', enabled: true, images: ['moduleActiveBg', 'moduleBg'], children: {}, }, { name: 'Ranking', enabled: true, images: ['moduleActiveBg', 'moduleBg'], children: {}, }, ], }, }, ], } ``` 生成规则: ```text children 为空对象时,不生成子标签。 children.tabs 控制当前 section 内部的二级标签状态。 children.sections 控制当前 section 内部的二级内容。 children.tabs.defaultValue 必须能匹配 children.sections 里的 name/value。 items 是字符串时,直接用字符串作为 value 和显示文本;items 是对象时,优先使用 value、label、labelKey、buttonImage、activeButtonImage。 备注写明“开发期间不加翻译”时,页面直接展示 md 里的英文文本。 标签图片为背景时,优先用 itemCenter 或等价图片容器承载文本,不把整段文字做成图片。 ``` ### 4.3 排行榜 ```js import { useActivityRanking } from '@/composables/activity/useActivityRanking.js' const rankingState = useActivityRanking({ loadMode: pageConfig.ranking.loadMode, pageSize: pageConfig.ranking.pageSize, topCount: pageConfig.ranking.topCount, fetchPage: ({ pageNo, pageSize }) => { return ranklist({ activityId: pageConfig.activity.activityId, pageNo, pageSize, }) }, }) ``` ### 4.4 抽奖 ```js import { useLotteryDraw } from '@/composables/activity/useLotteryDraw.js' const { activeIndex, isRolling, startLottery } = useLotteryDraw({ getSlotCount: () => prizeList.value.length || pageConfig.lottery.slotCount, }) ``` ### 4.5 分阶段图片预加载 用途:把首屏关键图片和后续图片拆开。首屏关键图片参与进入页面加载动画;弹窗、非默认标签页、下方长背景等图片在页面进入后后台继续预加载。 ```js // 进入页面前必须完成的图片,加载完成后再结束 loading 动画。 const blockingPreloadImageNames = pageConfig.preload?.blocking || [] // 进入页面后继续后台加载的图片,不阻塞页面展示。 const backgroundPreloadImageNames = pageConfig.preload?.background || [] // 统一走 imageUrl 和 getImgName,保证本地 OSS、线上 OSS、缓存版本、多语言后缀规则一致。 const resolvePreloadUrls = (names = []) => { return [...new Set(names)].map((name) => imageUrl(getImgName(name))) } const preloadImageList = (urls = []) => { return Promise.all( urls.map((url) => new Promise((resolve) => { const img = new Image() img.onload = resolve img.onerror = resolve img.src = url })), ) } const preloadBlockingImages = async () => { await preloadImageList(resolvePreloadUrls(blockingPreloadImageNames)) } const preloadBackgroundImages = () => { const urls = resolvePreloadUrls(backgroundPreloadImageNames) if (!urls.length) return // 后台预加载不影响当前页面展示,所以失败也只吞掉。 const run = () => preloadImageList(urls).catch(() => {}) if (window.requestIdleCallback) { window.requestIdleCallback(run) return } setTimeout(run, 0) } onMounted(async () => { await preloadBlockingImages() isLoading.value = false preloadBackgroundImages() }) ```