pxb 21 ore fa
parent
commit
c191d61cfd
1 ha cambiato i file con 355 aggiunte e 99 eliminazioni
  1. 355 99
      src/pages/Tabbar/Home/index.vue

+ 355 - 99
src/pages/Tabbar/Home/index.vue

@@ -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>