|
|
@@ -151,21 +151,21 @@
|
|
|
<view class="odds-btn" v-for="(opt, optIndex) in getVisibleValues(
|
|
|
item.odds[0].values
|
|
|
)" :key="optIndex" :class="{
|
|
|
- 'is-locked': isOptionLocked(item, opt),
|
|
|
- 'is-active': isSelected(
|
|
|
- item.id,
|
|
|
- item.odds[0].id,
|
|
|
- opt
|
|
|
- ),
|
|
|
- 'odds-up':
|
|
|
- isOddsUp(
|
|
|
- getOddsKey(item.id, item.odds[0].id, opt)
|
|
|
- ) && !isOptionLocked(item, opt),
|
|
|
- 'odds-down':
|
|
|
- isOddsDown(
|
|
|
- getOddsKey(item.id, item.odds[0].id, opt)
|
|
|
- ) && !isOptionLocked(item, opt),
|
|
|
- }" @click.stop="handleOddsClick(item, opt)">
|
|
|
+ 'is-locked': isOptionLocked(item, opt),
|
|
|
+ 'is-active': isSelected(
|
|
|
+ item.id,
|
|
|
+ item.odds[0].id,
|
|
|
+ opt
|
|
|
+ ),
|
|
|
+ 'odds-up':
|
|
|
+ isOddsUp(
|
|
|
+ getOddsKey(item.id, item.odds[0].id, opt)
|
|
|
+ ) && !isOptionLocked(item, opt),
|
|
|
+ 'odds-down':
|
|
|
+ isOddsDown(
|
|
|
+ getOddsKey(item.id, item.odds[0].id, opt)
|
|
|
+ ) && !isOptionLocked(item, opt),
|
|
|
+ }" @click.stop="handleOddsClick(item, opt)">
|
|
|
<view class="locked-overlay" v-if="isOptionLocked(item, opt)">
|
|
|
<u-icon name="lock" color="#fff" size="24"></u-icon>
|
|
|
</view>
|
|
|
@@ -330,70 +330,212 @@
|
|
|
</view>
|
|
|
</scroll-view>
|
|
|
</view>
|
|
|
- <!-- 其他游戏专区 -->
|
|
|
- <view class="roll-ball-section" v-for="(gameSection, index) in otherGamesList" :key="'other-' + index">
|
|
|
+ <view class="roll-ball-section" v-for="(gameSection, index) in dzLoopList" :key="'dz-' + index">
|
|
|
+
|
|
|
<view class="roll-ball-header">
|
|
|
+
|
|
|
<view class="header-left">
|
|
|
+
|
|
|
<u-image :src="gameSection.icon" width="20px" height="20px"></u-image>
|
|
|
- <text class="roll-ball-title">{{ t(gameSection.name) }}</text>
|
|
|
+
|
|
|
+
|
|
|
+ <text class="roll-ball-title">
|
|
|
+ {{ t(gameSection.typeName) }}
|
|
|
+ </text>
|
|
|
+
|
|
|
</view>
|
|
|
- <view class="more-roll-btn" @click="handleOtherGameClick(gameSection, 1)">
|
|
|
- <text class="more-text">{{ t("更多") }} >></text>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ <view class="more-roll-btn" @click="handleOtherGameClick(gameSection, 2)">
|
|
|
+
|
|
|
+ <text class="more-text">
|
|
|
+ {{ t("更多") }} >>
|
|
|
+ </text>
|
|
|
+
|
|
|
</view>
|
|
|
+
|
|
|
+
|
|
|
</view>
|
|
|
|
|
|
- <view class="game-container">
|
|
|
- <!-- 数据 ≤3 条:flex 靠左 -->
|
|
|
- <view v-if="gameSection.platforms && gameSection.platforms.length <= 3" class="game-flex-left">
|
|
|
- <view class="other-game-item" v-for="(item, itemIndex) in gameSection.platforms" :key="itemIndex"
|
|
|
- @click="goGame(item, gameSection.gameType)">
|
|
|
- <u-image :src="item.logo" width="110px" height="110px" mode="aspectFit"></u-image>
|
|
|
- </view>
|
|
|
+
|
|
|
+
|
|
|
+ <!-- 1、2个游戏 -->
|
|
|
+ <view v-if="gameSection.platforms.length <= 2" class="other-games-flex">
|
|
|
+
|
|
|
+ <view class="other-game-item" v-for="(item, itemIndex) in gameSection.platforms" :key="itemIndex"
|
|
|
+ @click="goTypeGame(gameSection, itemIndex)">
|
|
|
+
|
|
|
+ <u-image :src="item.logo" width="120px" height="120px" mode="aspectFit"></u-image>
|
|
|
+
|
|
|
+
|
|
|
</view>
|
|
|
|
|
|
- <!-- 数据 >3 条:swiper 无限循环手动滑动 -->
|
|
|
- <swiper v-else class="game-swiper" :circular="true" :autoplay="false" :display-multiple-items="3"
|
|
|
- :previous-margin="'0px'" :next-margin="'0px'">
|
|
|
- <swiper-item v-for="(item, itemIndex) in getSwiperData(gameSection.platforms)" :key="itemIndex">
|
|
|
- <view class="other-game-item"
|
|
|
- @click="goGame(getRealItem(gameSection.platforms, itemIndex), gameSection.gameType)">
|
|
|
- <u-image :src="item.logo" width="100%" height="110px" mode="aspectFit"></u-image>
|
|
|
- </view>
|
|
|
- </swiper-item>
|
|
|
- </swiper>
|
|
|
+
|
|
|
</view>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ <!-- 超过2个无限循环 -->
|
|
|
+ <scroll-view v-else scroll-x class="other-games-scroll" :show-scrollbar="false"
|
|
|
+ :scroll-left="gameScrollLeft[index] || 0" @scroll="
|
|
|
+ handleGameScroll(
|
|
|
+ $event,
|
|
|
+ index,
|
|
|
+ gameSection.platforms.length
|
|
|
+ )
|
|
|
+ ">
|
|
|
+
|
|
|
+
|
|
|
+ <view class="other-games-flex">
|
|
|
+
|
|
|
+
|
|
|
+ <view class="other-game-item" v-for="(item, itemIndex) in gameSection.loopPlatforms" :key="itemIndex"
|
|
|
+ @click="
|
|
|
+ goTypeGame(
|
|
|
+ gameSection,
|
|
|
+ itemIndex % gameSection.platforms.length
|
|
|
+ )
|
|
|
+ ">
|
|
|
+
|
|
|
+
|
|
|
+ <u-image :src="item.logo" width="120px" height="120px" mode="aspectFit"></u-image>
|
|
|
+
|
|
|
+
|
|
|
+ </view>
|
|
|
+
|
|
|
+
|
|
|
+ </view>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ </scroll-view>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
</view>
|
|
|
+ <view class="roll-ball-section" v-for="(gameSection, index) in otherLoopList" :key="'other-' + index">
|
|
|
+
|
|
|
|
|
|
- <!-- 电子游戏专区 -->
|
|
|
- <view class="roll-ball-section" v-for="(gameSection, index) in dzGamesList" :key="'dz-' + index">
|
|
|
<view class="roll-ball-header">
|
|
|
+
|
|
|
+
|
|
|
<view class="header-left">
|
|
|
+
|
|
|
+
|
|
|
<u-image :src="gameSection.icon" width="20px" height="20px"></u-image>
|
|
|
- <text class="roll-ball-title">{{ t(gameSection.typeName) }}</text>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ <text class="roll-ball-title">
|
|
|
+
|
|
|
+ {{ t(gameSection.name) }}
|
|
|
+
|
|
|
+ </text>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
</view>
|
|
|
- <view class="more-roll-btn" @click="handleOtherGameClick(gameSection, 2)">
|
|
|
- <text class="more-text">{{ t("更多") }} >></text>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ <view class="more-roll-btn" @click="handleOtherGameClick(gameSection, 1)">
|
|
|
+
|
|
|
+
|
|
|
+ <text class="more-text">
|
|
|
+
|
|
|
+ {{ t("更多") }} >>
|
|
|
+
|
|
|
+ </text>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
</view>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
</view>
|
|
|
|
|
|
- <view class="game-container">
|
|
|
- <view v-if="gameSection.platforms && gameSection.platforms.length <= 3" class="game-flex-left">
|
|
|
- <view class="other-game-item" v-for="(item, itemIndex) in gameSection.platforms" :key="itemIndex"
|
|
|
- @click="goTypeGame(gameSection, itemIndex)">
|
|
|
- <u-image :src="item.logo" width="110px" height="110px" mode="aspectFit"></u-image>
|
|
|
- </view>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ <!-- 1、2个游戏正常展示 -->
|
|
|
+
|
|
|
+ <view v-if="gameSection.platforms.length <= 2" class="other-games-flex">
|
|
|
+
|
|
|
+
|
|
|
+ <view class="other-game-item" v-for="(item, itemIndex) in gameSection.platforms" :key="itemIndex"
|
|
|
+ @click="goGame(item, gameSection.gameType)">
|
|
|
+
|
|
|
+
|
|
|
+ <u-image :src="item.logo" width="120px" height="120px" mode="aspectFit"></u-image>
|
|
|
+
|
|
|
+
|
|
|
</view>
|
|
|
|
|
|
- <swiper v-else class="game-swiper" :circular="true" :autoplay="false" :display-multiple-items="3"
|
|
|
- :previous-margin="'0px'" :next-margin="'0px'">
|
|
|
- <swiper-item v-for="(item, itemIndex) in getSwiperData(gameSection.platforms)" :key="itemIndex">
|
|
|
- <view class="other-game-item"
|
|
|
- @click="goTypeGame(gameSection, getRealItemIndex(gameSection.platforms, itemIndex))">
|
|
|
- <u-image :src="item.logo" width="100%" height="110px" mode="aspectFit"></u-image>
|
|
|
- </view>
|
|
|
- </swiper-item>
|
|
|
- </swiper>
|
|
|
+
|
|
|
+
|
|
|
</view>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ <!-- 3个以上无限循环 -->
|
|
|
+
|
|
|
+ <scroll-view v-else scroll-x class="other-games-scroll" :show-scrollbar="false"
|
|
|
+ :scroll-left="gameScrollLeft[index + dzLoopList.length] || 0" @scroll="
|
|
|
+
|
|
|
+ handleGameScroll(
|
|
|
+
|
|
|
+ $event,
|
|
|
+
|
|
|
+ index + dzLoopList.length,
|
|
|
+
|
|
|
+ gameSection.platforms.length
|
|
|
+
|
|
|
+ )
|
|
|
+
|
|
|
+ ">
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ <view class="other-games-flex">
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ <view class="other-game-item" v-for="(item, itemIndex) in gameSection.loopPlatforms" :key="itemIndex"
|
|
|
+ @click="goGame(item, gameSection.gameType)">
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ <u-image :src="item.logo" width="120px" height="120px" mode="aspectFit"></u-image>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ </view>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ </view>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ </scroll-view>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
</view>
|
|
|
</view>
|
|
|
<view style="height: 20px"></view>
|
|
|
@@ -516,24 +658,124 @@ const handleLotteryGameClick = (item) => {
|
|
|
|
|
|
const otherGamesList = ref([]);
|
|
|
const dzGamesList = ref([]);
|
|
|
-// 获取 swiper 数据(复制一份实现无限循环)
|
|
|
-const getSwiperData = (data) => {
|
|
|
- if (!data || data.length <= 3) return data || [];
|
|
|
- return [...data, ...data]; // 复制一份即可
|
|
|
-};
|
|
|
|
|
|
-// 获取真实 item(点击时使用)
|
|
|
-const getRealItem = (data, index) => {
|
|
|
- if (!data || data.length === 0) return null;
|
|
|
- if (data.length <= 3) return data[index];
|
|
|
- return data[index % data.length];
|
|
|
+
|
|
|
+// ===============================
|
|
|
+// 游戏横向无限循环处理
|
|
|
+// 规则:
|
|
|
+// 1、2个以内:正常展示
|
|
|
+// 3个以上:复制三份,实现无感循环
|
|
|
+// ===============================
|
|
|
+
|
|
|
+
|
|
|
+const getLoopPlatforms = (list) => {
|
|
|
+
|
|
|
+ if (!list || list.length <= 2) {
|
|
|
+ return list || [];
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ return [
|
|
|
+ ...list,
|
|
|
+ ...list,
|
|
|
+ ...list
|
|
|
+ ];
|
|
|
+
|
|
|
};
|
|
|
|
|
|
-const getRealItemIndex = (data, index) => {
|
|
|
- if (!data || data.length === 0) return 0;
|
|
|
- if (data.length <= 3) return index;
|
|
|
- return index % data.length;
|
|
|
+
|
|
|
+
|
|
|
+// DZ游戏循环数据
|
|
|
+const dzLoopList = computed(() => {
|
|
|
+
|
|
|
+ return dzGamesList.value.map((item) => {
|
|
|
+
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ loopPlatforms: getLoopPlatforms(item.platforms)
|
|
|
+ };
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+});
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// 其他游戏循环数据
|
|
|
+const otherLoopList = computed(() => {
|
|
|
+
|
|
|
+ return otherGamesList.value.map((item) => {
|
|
|
+
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ loopPlatforms: getLoopPlatforms(item.platforms)
|
|
|
+ };
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+});
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// 保存每个scroll-view的位置
|
|
|
+const gameScrollLeft = ref({});
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// 横向滚动监听
|
|
|
+const handleGameScroll = (
|
|
|
+ e,
|
|
|
+ index,
|
|
|
+ length
|
|
|
+) => {
|
|
|
+
|
|
|
+
|
|
|
+ // 1、2个不处理
|
|
|
+ if (length <= 2) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ const itemWidth = 130;
|
|
|
+ // 图片120 + gap10
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ const scrollLeft = e.detail.scrollLeft;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // 滑动到第三组后
|
|
|
+ // 无动画回到第二组
|
|
|
+ if (
|
|
|
+ scrollLeft >= itemWidth * length * 2
|
|
|
+ ) {
|
|
|
+
|
|
|
+
|
|
|
+ gameScrollLeft.value[index] =
|
|
|
+ scrollLeft - itemWidth * length;
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // 防止往左滑出边界
|
|
|
+
|
|
|
+ if (scrollLeft <= 0) {
|
|
|
+
|
|
|
+
|
|
|
+ gameScrollLeft.value[index] =
|
|
|
+ itemWidth * length;
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
};
|
|
|
+
|
|
|
const getGames = async () => {
|
|
|
const res = await getPlatforms();
|
|
|
const resDZ = await dzList();
|
|
|
@@ -2013,45 +2255,59 @@ onQuery();
|
|
|
}
|
|
|
|
|
|
/* 其他游戏专区横向滚动及正方形图片样式 */
|
|
|
-.game-container {
|
|
|
+/* ================================
|
|
|
+ 其他游戏横向滚动
|
|
|
+ 图片120×120
|
|
|
+ 间距10px
|
|
|
+ 无背景
|
|
|
+================================ */
|
|
|
+
|
|
|
+
|
|
|
+.other-games-scroll {
|
|
|
+
|
|
|
width: 100%;
|
|
|
+
|
|
|
+ white-space: nowrap;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
-// 数据 ≤3 条时的 flex 靠左布局
|
|
|
-.game-flex-left {
|
|
|
+
|
|
|
+
|
|
|
+.other-games-flex {
|
|
|
+
|
|
|
+
|
|
|
display: flex;
|
|
|
+
|
|
|
flex-direction: row;
|
|
|
- justify-content: flex-start; // 靠左
|
|
|
- align-items: center;
|
|
|
- gap: 8px;
|
|
|
- padding: 4px 0;
|
|
|
-}
|
|
|
|
|
|
-// swiper 容器
|
|
|
-.game-swiper {
|
|
|
- width: 100%;
|
|
|
- height: 120px; // 比图片高度稍高,避免截断
|
|
|
+ gap: 10px;
|
|
|
+
|
|
|
|
|
|
- // 让每个 swiper-item 内的卡片居中,但卡片宽度自动填满
|
|
|
- :deep(.uni-swiper-slide) {
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
-// 游戏卡片样式
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
.other-game-item {
|
|
|
- width: 100%; // 在 swiper 中自适应宽度
|
|
|
- height: 110px;
|
|
|
- border-radius: 8px;
|
|
|
- overflow: hidden;
|
|
|
- background: #f5f6fa;
|
|
|
+
|
|
|
+
|
|
|
+ width: 120px;
|
|
|
+
|
|
|
+
|
|
|
+ height: 120px;
|
|
|
+
|
|
|
+
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
- // 在 flex 模式下固定宽度
|
|
|
- .game-flex-left & {
|
|
|
- width: 110px;
|
|
|
- }
|
|
|
+
|
|
|
+ display: flex;
|
|
|
+
|
|
|
+
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+
|
|
|
+ justify-content: center;
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
</style>
|