feat(世界杯活动): 调整接口参数,补充itemcenter组件的max-height,防止图片未加载时高度过高

This commit is contained in:
hzj 2026-06-09 11:48:57 +08:00
parent 12d78b82bd
commit 9422640aca
7 changed files with 48 additions and 40 deletions

View File

@ -21,7 +21,10 @@ export const apiPostWorldCupMatchList = async (data) => {
// 提交世界杯比赛押注betOption 为 1 主胜、2 平局、3 客胜。
export const apiPostWorldCupBet = async (data) => {
try {
const response = await post(`${WORLD_CUP_API_PREFIX}/bet`, data)
const response = await post(`${WORLD_CUP_API_PREFIX}/bet`, {
...data,
matchId: data?.matchId == null ? '' : String(data.matchId),
})
return response
} catch (error) {
logWorldCupApiError('Failed to submit world cup bet:', error)
@ -32,7 +35,10 @@ export const apiPostWorldCupBet = async (data) => {
// 获取我的世界杯竞猜记录matchId 为空时查询全部比赛记录。
export const apiPostWorldCupMyBetList = async (data) => {
try {
const response = await post(`${WORLD_CUP_API_PREFIX}/my/bet/list`, data)
const response = await post(`${WORLD_CUP_API_PREFIX}/my/bet/list`, {
...data,
matchId: data?.matchId == null || data.matchId === '' ? data?.matchId : String(data.matchId),
})
return response
} catch (error) {
logWorldCupApiError('Failed to get world cup my bet list:', error)

View File

@ -71,7 +71,7 @@
>
<!-- 赛事结果模块按未开始进行中已结束中奖已结束未中奖/未参与展示不同状态 -->
<itemCenter
style="position: relative; width: 100%; min-height: 53vw"
style="position: relative; width: 100%; min-height: 53vw; max-height: 54vw"
:imgUrl="pngUrl(resultStatusConfig.image)"
contentStyle=" padding: 9vw 5vw 2vw 5vw; box-sizing: border-box; display: flex; flex-direction: column; align-items: stretch; justify-content: space-between; gap: 0vw;"
>
@ -784,7 +784,7 @@ const connectToAppHandler = async () => {
const submitWorldCupBet = async (betOption, betAmount) => {
if (!matchId.value) return
return apiPostWorldCupBet({
matchId: Number(matchId.value),
matchId: String(matchId.value),
betOption,
betAmount,
})

View File

@ -21,6 +21,7 @@
- 路由 name`world-cup-event-detail`
- 进入来源WorldCup 首页赛事列表项下方的 `TOTAL PRIZE POOL` 模块。
- Query 参数:`matchId`,来自比赛列表接口返回的 `matchId`
- `matchId` 必须按字符串处理和传参,禁止使用 `Number(matchId)`;比赛 ID 可能超过 JS 安全整数范围,转数字会丢失精度。
## 2. 业务规则
@ -42,7 +43,7 @@
- 第一模块为赛事结果模块,使用 `itemCenter` 组件承载不同状态背景图。
- 第二模块为押注模块,负责展示押注对象、押注状态和未开赛时的押注金额入口。
- 第三模块为押注记录模块,负责展示当前赛事内用户押注对象、金额和押注时间。
- 本页 `itemCenter``min-height``Math.ceil(实际展示宽度vw * 图片高度 / 图片宽度)` 计算;赛事结果模块在主内容区左右 `2vw` padding 后实际宽度为 `96vw``statusNotStarted` / `statusInProgress` / `statusEndedWin` / `statusEndedfail` 图片比例一致,计算后设置 `min-height: 53vw`。
- 本页 `itemCenter``min-height``Math.ceil(实际展示宽度vw * 图片高度 / 图片宽度)` 计算;赛事结果模块在主内容区左右 `2vw` padding 后实际宽度为 `96vw``statusNotStarted` / `statusInProgress` / `statusEndedWin` / `statusEndedfail` 图片比例一致,计算后设置 `min-height: 53vw; max-height: 54vw`,避免图片加载出来之前容器高度异常撑高
## 4. 赛事结果模块
@ -68,7 +69,7 @@
- 已开始或已结束赛事中,押注对象不可点击,选中态用于展示用户已押注过的选项。
- 已结束赛事中,根据接口 `result` 字段判断胜方或平局结果,`1` 主胜、`2` 平局、`3` 客胜,并在对应押注项图片容器内叠加 `frameWinner`;该用法和首页 `Ended` 列表项保持一致。
- 押注金额模块只在未开始赛事展示,金额选项为 `100``1000``10000``100000`,每个金额左侧展示 coin 图片。
- 押注流程为:先选择押注对象,再点击押注金额;点击金额时调用 `apiPostWorldCupBet({ matchId, betOption, betAmount })`。
- 押注流程为:先选择押注对象,再点击押注金额;点击金额时调用 `apiPostWorldCupBet({ matchId: String(matchId), betOption, betAmount })`。
- 押注成功后清空当前选中押注对象,并重新拉取 `apiGetWorldCupMatchDetail``apiPostWorldCupMyBetList` 刷新页面状态。
## 6. 押注记录模块

View File

@ -66,7 +66,7 @@
<itemCenter
:imgUrl="charmLevelUrl"
class="level-badge"
style="width: 30%; min-height: 4vw"
style="width: 30%; min-height: 4vw; max-height: 5vw"
contentStyle="padding: 0 0 0 42%; align-items: center; justify-content: center; box-sizing: border-box;"
>
<span>{{ charmLevel || 0 }}</span>
@ -74,7 +74,7 @@
<itemCenter
:imgUrl="wealthLevelUrl"
class="level-badge"
style="width: 30%; min-height: 4vw"
style="width: 30%; min-height: 4vw; max-height: 5vw"
contentStyle="padding: 0 0 0 36%; align-items: center; justify-content: center; box-sizing: border-box;"
>
<span>{{ wealthLevel || 0 }}</span>

View File

@ -61,7 +61,7 @@
<!-- 头部模块使用 bg 大图承载内部放置右侧规则按钮 -->
<itemCenter
style="width: 100vw; min-height: 151vw"
style="width: 100vw; min-height: 151vw; max-height: 152vw"
:imgUrl="pngUrl('bg')"
contentStyle="padding: 87vw 0 0; align-items: flex-start; justify-content: flex-start; box-sizing: border-box;"
>
@ -87,7 +87,7 @@
<!-- 排行榜主图区RankingMain 内展示前三名头像框 -->
<itemCenter
style="width: 100vw; min-height: 92vw"
style="width: 100vw; min-height: 92vw; max-height: 93vw"
:imgUrl="pngUrl('RankingMain')"
contentStyle="direction: ltr; padding: 0; flex-direction: column; align-items: center; justify-content: space-between; box-sizing: border-box;"
>
@ -212,7 +212,7 @@
<itemCenter
v-for="(rankingItem, index) in rankingListAfterTop3"
:key="rankingItem.userId || index"
style="width: 100vw; min-height: 23vw; margin-top: -2vw"
style="width: 100vw; min-height: 23vw; max-height: 24vw; margin-top: -2vw"
:imgUrl="pngUrl('RankingItem')"
contentStyle="padding: 3vw 8vw 0; box-sizing: border-box; justify-content: space-between;"
@click="handleRankingClick(rankingItem)"
@ -261,7 +261,7 @@
/>
<itemCenter
:imgUrl="pngUrl(getLevelBgImageName('userLevel', rankingItem.charmLevel))"
style="width: 12vw; min-height: 7vw"
style="width: 12vw; min-height: 7vw; max-height: 8vw"
contentStyle="direction: ltr;padding: 0 0 0 42%; align-items: center; justify-content: center; box-sizing: border-box;"
>
<span style="color: #fff; font-size: 1em; font-weight: 700; line-height: 1">
@ -270,7 +270,7 @@
</itemCenter>
<itemCenter
:imgUrl="pngUrl(getLevelBgImageName('wealthLevel', rankingItem.wealthLevel))"
style="width: 12vw; min-height: 6vw"
style="width: 12vw; min-height: 6vw; max-height: 7vw"
contentStyle="direction: ltr;padding: 0 0 0 36%; align-items: center; justify-content: center; box-sizing: border-box;"
>
<span style="color: #fff; font-size: 1em; font-weight: 700; line-height: 1">
@ -350,7 +350,7 @@
<section style="width: 100vw">
<!-- 赛事列表背景容器使用 EventlistBg 承载切换按钮和比赛列表 -->
<itemCenter
style="width: 100vw; min-height: 244vw"
style="width: 100vw; min-height: 244vw; max-height: 245vw"
:imgUrl="pngUrl('EventlistBg')"
contentStyle="display: flex; flex-direction: column; justify-content: flex-start; align-items: center; gap: 2vw; padding: 18vw 8vw 12vw; box-sizing: border-box;"
>
@ -409,7 +409,7 @@
"
>
<itemCenter
style="width: 100%; min-height: 52vw"
style="width: 100%; min-height: 52vw; max-height: 53vw"
:imgUrl="pngUrl('matchBg')"
contentStyle="width: 100%; height: 100%; padding: 0; box-sizing: border-box; display: flex; flex-direction: column; justify-content: space-between; align-items: center;"
>
@ -914,7 +914,7 @@
<!-- 我的排名贴底模块固定在视口底部展示当前用户排名信息 -->
<itemCenter
v-if="!isLoading"
style="position: fixed; left: 0; bottom: 0; z-index: 10; width: 100vw; min-height: 21vw"
style="position: fixed; left: 0; bottom: 0; z-index: 10; width: 100vw; min-height: 21vw; max-height: 22vw"
:imgUrl="pngUrl('myRankingBg')"
contentStyle="padding: 2vw 8vw; box-sizing: border-box; justify-content: space-between;"
>
@ -959,7 +959,7 @@
/>
<itemCenter
:imgUrl="pngUrl(getLevelBgImageName('userLevel', myRanking.charmLevel))"
style="width: 12vw; min-height: 7vw; margin: 0; padding: 0"
style="width: 12vw; min-height: 7vw; max-height: 8vw; margin: 0; padding: 0"
contentStyle="padding: 0 0 0 5vw; align-items: center; justify-content: center;"
>
<div style="color: #fff; font-size: 1em; font-weight: 700; line-height: 1">
@ -968,7 +968,7 @@
</itemCenter>
<itemCenter
:imgUrl="pngUrl(getLevelBgImageName('wealthLevel', myRanking.wealthLevel))"
style="width: 12vw; min-height: 6vw; margin: 0; padding: 0"
style="width: 12vw; min-height: 6vw; max-height: 7vw; margin: 0; padding: 0"
contentStyle="padding: 0 0 0 4vw; align-items: center; justify-content: center;"
>
<div style="color: #fff; font-size: 1em; font-weight: 700; line-height: 1">
@ -1020,7 +1020,7 @@
>
<!-- 奖励弹窗内容rewardBg 靠上展示上下保留遮罩空白用于点击退出 -->
<itemCenter
style="width: 100vw; min-height: 225vw"
style="width: 100vw; min-height: 225vw; max-height: 226vw"
:imgUrl="pngUrl('rewardBg')"
contentStyle="display: flex; flex-direction: column;justify-content: flex-start; gap: 12.5vw; padding: 34vw 6vw 0vw; box-sizing: border-box;"
>
@ -1172,7 +1172,7 @@
>
<!-- 规则弹窗内容ruleBg 高度较长宽度占满 100vw顶部和底部空白用于点击退出 -->
<itemCenter
style="width: 100vw; min-height: 178vw"
style="width: 100vw; min-height: 178vw; max-height: 179vw"
:imgUrl="pngUrl('ruleBg')"
contentStyle="padding: 0; box-sizing: border-box;"
/>
@ -1390,7 +1390,7 @@ const normalizeRankingItem = (item = {}) => {
// apiPostWorldCupMatchList
const normalizeMatchItem = (item = {}) => {
return {
matchId: item.matchId ?? '',
matchId: item.matchId == null ? '' : String(item.matchId),
homeTeam: item.homeTeam ?? '',
awayTeam: item.awayTeam ?? '',
homeFlag: item.homeFlag ?? '',

View File

@ -119,7 +119,7 @@ Body 参数:
```json
{
"matchId": 0,
"matchId": "0",
"betOption": 0,
"betAmount": 0
}
@ -129,7 +129,7 @@ Body 参数:
| 字段 | 必填 | 说明 |
| --- | --- | --- |
| matchId | 是 | 比赛 ID |
| matchId | 是 | 比赛 ID,必须使用字符串格式传参,避免大整数精度丢失 |
| betOption | 是 | 押注选项:`1` 主胜,`2` 平局,`3` 客胜 |
| betAmount | 是 | 押注金额:`100` / `1000` / `10000` / `100000` |
@ -146,7 +146,7 @@ Body 参数:
{
"size": 0,
"current": 0,
"matchId": 0
"matchId": "0"
}
```
@ -156,7 +156,7 @@ Body 参数:
| --- | --- | --- |
| size | 是 | 每页数量 |
| current | 是 | 当前页 |
| matchId | 否 | 比赛 ID为空查全部 |
| matchId | 否 | 比赛 ID为空查全部;有值时必须使用字符串格式传参,避免大整数精度丢失 |
返回示例:

View File

@ -76,23 +76,23 @@
页面进入时必须展示统一加载动画,阻塞预加载完成后再展示主内容。
### 3.3 itemCenter 最小高度
### 3.3 itemCenter 高度约束
`itemCenter``min-height``Math.ceil(实际展示宽度vw * 图片高度 / 图片宽度)` 计算,当前页面已补充以下值
`itemCenter``min-height``Math.ceil(实际展示宽度vw * 图片高度 / 图片宽度)` 计算;为避免图片加载出来之前容器高度异常撑高,同步设置接近的 `max-height`,当前页面默认按 `max-height = min-height + 1vw` 补充
| 使用位置 | 图片 | 实际展示宽度 | min-height |
| --- | --- | --- | --- |
| 头部模块 | `bg` | `100vw` | `151vw` |
| 排行榜主图区 | `RankingMain` | `100vw` | `92vw` |
| 第四名以后排行榜项 | `RankingItem` | `100vw` | `23vw` |
| 首页魅力等级徽章 | `userLevel1Bg-userLevel5Bg` | `12vw` | `7vw` |
| 首页财富等级徽章 | `wealthLevel1Bg-wealthLevel5Bg` | `12vw` | `6vw` |
| 赛事列表模块 | `EventlistBg` | `100vw` | `244vw` |
| Predict Now 赛事卡片 | `matchBg` | `84vw`,来自 `EventlistBg` 内容区左右 `8vw` padding 后的可用宽度 | `52vw` |
| 我的排名贴底模块 | `myRankingBg` | `100vw` | `21vw` |
| 奖励弹窗 | `rewardBg` | `100vw` | `225vw` |
| 规则弹窗 | `ruleBg` | `100vw` | `178vw` |
| `components/topUser.vue` 等级徽章 | `userLevel*Bg` / `wealthLevel*Bg` | 当前父级最大 `26vw``30%` | `4vw` |
| 使用位置 | 图片 | 实际展示宽度 | min-height | max-height |
| --- | --- | --- | --- | --- |
| 头部模块 | `bg` | `100vw` | `151vw` | `152vw` |
| 排行榜主图区 | `RankingMain` | `100vw` | `92vw` | `93vw` |
| 第四名以后排行榜项 | `RankingItem` | `100vw` | `23vw` | `24vw` |
| 首页魅力等级徽章 | `userLevel1Bg-userLevel5Bg` | `12vw` | `7vw` | `8vw` |
| 首页财富等级徽章 | `wealthLevel1Bg-wealthLevel5Bg` | `12vw` | `6vw` | `7vw` |
| 赛事列表模块 | `EventlistBg` | `100vw` | `244vw` | `245vw` |
| Predict Now 赛事卡片 | `matchBg` | `84vw`,来自 `EventlistBg` 内容区左右 `8vw` padding 后的可用宽度 | `52vw` | `53vw` |
| 我的排名贴底模块 | `myRankingBg` | `100vw` | `21vw` | `22vw` |
| 奖励弹窗 | `rewardBg` | `100vw` | `225vw` | `226vw` |
| 规则弹窗 | `ruleBg` | `100vw` | `178vw` | `179vw` |
| `components/topUser.vue` 等级徽章 | `userLevel*Bg` / `wealthLevel*Bg` | 当前父级最大 `26vw``30%` | `4vw` | `5vw` |
## 4. 页面结构
@ -148,6 +148,7 @@
- Predict Now 和 Ended 的单条列表都使用新的 column wrapper上方是原赛事卡片下方是总奖池入口`gap` 控制上下间距。
- 总奖池入口样式为金色描边渐变背景,内部一行展示 `TOTAL PRIZE POOL`、coin 图片、总奖池金额和右侧 `rightBt`;金额优先展示 `totalPoolFormat`,没有格式化字段时回退 `totalPool`
- 点击总奖池入口进入 `/activities/world-cup/event-detail?matchId=...`,详情页目录为 `src/views/Activities/WorldCup/EventDetail`
- 赛事 `matchId` 必须按字符串保留和传递,禁止使用 `Number(matchId)`;比赛 ID 可能超过 JS 安全整数范围,转数字会丢失精度。
Predict Now 列表项规则: