|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |  | <template>  <view class="home-container">    <!-- 開動頁面組件 -->    <SplashScreen @close="onSplashClose" />        <!-- 状态栏安全区域 -->    <uv-status-bar></uv-status-bar>        <!-- 顶部搜索栏 -->    <view class="header">      <view class="search-container" @click="goSearch">        <uv-search           placeholder="请输入要查询的内容"           :show-action="false"          shape="round"          bg-color="#f5f5f5"          color="#666"          height="38"          margin="0 200rpx 0 0"          placeholderColor="#c6c6c6"        ></uv-search>      </view>
    </view>
    <!-- Tab栏 -->    <view class="tab-container">      <scroll-view show-scrollbar="false" class="tab-scroll" scroll-x="true" >        <view class="tab-list">          <view             v-for="(tab, index) in tabs"             :key="index"             class="tab-item"             :class="{ active: activeTab === index }"            @click="switchTab(index)"          >            {{ tab.title }}          </view>        </view>      </scroll-view>    </view>
    <!-- 轮播图 -->    <view class="swiper-container">      <uv-swiper         :list="bannerList"         keyName="image"        height="121"        radius="12"        indicator        ndicatorInactiveColor="#fff"        :loading="false"        indicatorMode="dot"        indicatorActiveColor="#F95A01"        @click="onBannerClick"      ></uv-swiper>    </view>
    <!-- 根据labelBooksData动态渲染书籍区块 -->    <view       v-for="(labelData, labelIndex) in labelBooksData"       :key="labelIndex"       class="section"    >      <view class="section-header" @click="goLabel(labelData.labelInfo)">        <text class="section-title">{{ labelData.labelInfo.title }}</text>        <view class="section-more">          <text>更多</text>          <uv-icon name="arrow-right" size="14" color="#888"></uv-icon>        </view>      </view>            <!-- 第一个label:今日更新样式 -->      <scroll-view         v-if="labelIndex === 0"         show-scrollbar="false"         class="content-scroll"         scroll-x="true"      >        <view class="content-list">          <view             v-for="(item, index) in labelData.books"             :key="index"             class="content-item"            @click="goBook(item)"          >            <view class="item-cover">              <image :src="item.booksImg || '/static/default-image.png'" mode="aspectFill"></image>            </view>            <view class="item-info">              <text class="item-title">{{ item.booksName }}</text>              <text class="item-author">{{ item.booksAuthor }}</text>              <view class="item-duration">                <image src="/static/play-icon.png" class="item-icon" />                <text>{{ item.duration }}</text>              </view>            </view>          </view>        </view>      </scroll-view>            <!-- 第二个label:推荐书籍样式 -->      <scroll-view         v-else-if="labelIndex === 1"         show-scrollbar="false"         class="content-scroll"         scroll-x="true"      >        <view class="book-list">          <view             v-for="(book, index) in labelData.books"             :key="index"             class="book-item"            @click="goBook(book)"          >            <view class="book-cover">              <image :src="book.booksImg || '/static/default-image.png'" mode="aspectFill"></image>              <view class="book-overlay">                <view class="book-duration" v-if="book.duration">                  <image src="/static/alarm-icon.png" class="book-duration-icon" />                  <text class="book-duration-text">{{ book.duration }}</text>                </view>                <view class="book-title">{{ book.booksName }}</view>              </view>            </view>          </view>        </view>      </scroll-view>            <!-- 第三个及以后的label:网格样式 -->      <view v-else class="book-grid">        <view           v-for="(book, index) in labelData.books"           :key="index"           class="book-grid-item"          @click="goBook(book)"        >          <view class="book-grid-cover">            <image :src="book.booksImg || '/static/default-image.png'" mode="aspectFill"></image>          </view>          <!-- <view class="book-grid-info">            <text class="book-grid-title">{{ book.booksName }}</text>            <view class="book-grid-meta">              <text class="book-grid-grade">{{ book.categoryName }}/</text>              <image src="/static/play-icon.png" class="book-grid-duration-icon" />              <text class="book-grid-duration">{{ book.duration }}</text>            </view>          </view> -->        </view>      </view>    </view>
    <!-- 推荐内容列表 -->    <view class="section">      <view class="recommend-list">        <view           @click="goPlan(item.id, item.type)"          v-for="(item, index) in recommendList"           :key="index"           class="recommend-item"        >          <image :src="item.img" mode="aspectFill" class="recommend-image"></image>        </view>      </view>    </view>        <!-- 视频播放弹窗 -->    <uv-modal       ref="videoModal"      title="视频播放"      :show-cancel-button="false"      :show-confirm-button="false"      width="90%"      :close-on-click-overlay="true"      @close="closeVideoModal"    >      <template #default>        <view class="video-container">          <video             v-if="currentVideo"            :src="currentVideo"            controls            autoplay            :show-fullscreen-btn="true"            :show-play-btn="true"            :show-center-play-btn="true"            style="width: 100%; height: 400rpx; border-radius: 8rpx;"            @error="onVideoError"            @play="onVideoPlay"            @pause="onVideoPause"          ></video>          <view v-else class="video-loading">            <text>视频加载中...</text>          </view>        </view>      </template>    </uv-modal>  </view></template>
<script>import SplashScreen from '../components/SplashScreen.vue'
export default {  components: {    SplashScreen  },  data() {    return {      // Tab数据
      tabs: [ ],      activeTab: 0,            // 轮播图数据
      bannerList: [
      ],
      // 书籍分类
      labels: [              ],            // 根据label获取的书籍数据(二维数组)
      labelBooksData: [],      
              // 推荐列表数据
       recommendList: [                ],                     currentVideo: ''    }  },    methods: {    // 開動頁面關閉處理
    onSplashClose() {      console.log('開動頁面已關閉')      // 可以在這裡添加其他邏輯,比如統計、初始化等
    },        // 切换Tab
    async switchTab(index) {      this.activeTab = index      await this.getBooksByLabels()    },        // 轮播图点击事件
    onBannerClick(index) {      console.log('点击轮播图:', index)      const bannerItem = this.bannerList[index]      if (!bannerItem) return            // 根据 typ 字段判断跳转类型
      switch(bannerItem.typ) {        case '1': // 课程详情
          if (bannerItem.bookId) {            uni.navigateTo({              url: '/subPages/home/directory?id=' + bannerItem.bookId            })          }          break        case '2': // 视频播放
          if (bannerItem.video) {            this.$refs.videoModal.open()            this.currentVideo = bannerItem.video          }          break        case '0': // 富文本内容
          if (bannerItem.content) {            uni.navigateTo({              url: '/subPages/home/richtext?content=' + encodeURIComponent(bannerItem.content)            })          }          break        default:          console.log('未知的轮播图类型:', bannerItem.typ)      }    },    // 跳转计划定制
    goPlan(id, type) {      uni.navigateTo({        url: '/subPages/home/plan?id=' + id + '&type=' + type      })    },    goSearch() {      uni.navigateTo({        url: '/subPages/home/search'      })    },    goBook(book) {      uni.navigateTo({        url: '/subPages/home/directory?id=' + book.id      })    },    async getBanner() {      const bannerRes = await this.$api.home.getBanner()      if (bannerRes.code === 200){        this.bannerList = bannerRes.result.map(item => ({            image: item.img,            title: item.title,            typ: item.typ,            bookId: item.bookId,            video: item.video,            content: item.content,            id: item.id        }))      }    },    async getSignup() {      const signupRes = await this.$api.home.getLink()      if (signupRes.code === 200){        this.recommendList = signupRes.result.map(item => ({          img: item.img,          id: item.id,          type: item.type        }))      }    },    // 获取书籍分类
    async getCategory() {      const categoryRes = await this.$api.book.category()      if (categoryRes.code === 200){        this.tabs = categoryRes.result.map(item => ({            title:item.title,            id: item.id        }))      }    },    // 获取书籍标签
    async getLabel() {      const labelRes = await this.$api.book.label()      if (labelRes.code === 200){        this.labels = labelRes.result.map(item => ({            title:item.lable,            id: item.id        }))      }    },
        // 根据label数组获取书籍数据
    async getBooksByLabels() {      if (!this.labels || this.labels.length === 0) {        console.log('labels数据为空,无法获取书籍')        return      }            try {        // 创建请求数组,每个label发起一次请求
        const requests = this.labels.map(label =>           this.$api.book.list({            label: label.id,            pageNo: 1,            pageSize: 6,            category: this.tabs[this.activeTab].id          }, false)        )                // 并发执行所有请求
        const responses = await Promise.all(requests)                // 创建二维数组存储结果
        this.labelBooksData = responses.map((response, index) => {          if (response.code === 200) {            return {              labelInfo: this.labels[index],              books: response.result.records || []            }          } else {            console.error(`获取label ${this.labels[index].title} 的书籍失败:`, response)            return {              labelInfo: this.labels[index],              books: []            }          }        })                console.log('根据label获取的书籍数据:', this.labelBooksData)      } catch (error) {        console.error('获取书籍数据失败:', error)        this.labelBooksData = []      }    },    goLabel(label){      uni.navigateTo({        url: '/subPages/home/search?label=' + label.id      })    },        // 关闭视频弹窗
    closeVideoModal() {      this.$refs.videoModal.close()      this.currentVideo = ''    },        // 视频错误处理
    onVideoError(e) {      console.error('视频播放错误:', e)      uni.showToast({        title: '视频播放失败',        icon: 'error'      })      this.closeVideoModal()    },        // 视频开始播放
    onVideoPlay() {      console.log('视频开始播放')    },        // 视频暂停
    onVideoPause() {      console.log('视频暂停播放')    }  },
  async onShow() {    // 先获取基础数据
    await Promise.all([this.getBanner(), this.getSignup(), this.getCategory(), this.getLabel()])        // 根据label数据获取对应的书籍
    await this.getBooksByLabels()  }}</script>
<style lang="scss" scoped>.home-container {  background: #fff;  min-height: 100vh;  padding-bottom: 80rpx;}
// 顶部搜索栏
.header {
  display: flex;  align-items: center;  padding: 6rpx 32rpx;  background: #fff;    .search-container {    flex: 1;  }
}
// Tab栏
.tab-container {  background: #fff;  // border-bottom: 1px solid #f0f0f0;
    top: 0;  left: 0;  right: 0;  z-index: 999;  .tab-scroll {    white-space: nowrap;        .tab-list {      display: flex;      padding: 0 20rpx;            .tab-item {        flex-shrink: 0;        padding: 20rpx 20rpx;        font-size: 32rpx;        color: #666;        position: relative;                &.active {          color: $primary-text-color;          font-weight: 700;                    &::after {            content: '';            position: absolute;            bottom: 0;            left: 50%;            transform: translateX(-50%);            width: 22rpx;            height: 4rpx;            background: $primary-text-color;            border-radius: 2rpx;          }        }      }    }  }}
// 轮播图容器
.swiper-container {  margin: 20rpx;  border-radius: 12rpx;  overflow: hidden;}
// 内容区块
.section {  margin-top: 40rpx;    .section-header {    display: flex;    align-items: center;    justify-content: space-between;    padding: 0 30rpx ;    margin-bottom: 24rpx;    .section-title {      font-size: 36rpx;      // font-weight: 600;
      color: $primary-text-color;    }        .section-more {      display: flex;      align-items: center;      gap: 4rpx;            text {        font-size: 24rpx;        color: $secondary-text-color;      }    }  }    .content-scroll {    white-space: nowrap;  }}
// 今日更新列表
.content-list {  display: flex;  padding: 0 30rpx;  gap: 32rpx;    .content-item {    flex-shrink: 0;    width: 602rpx;    height: 212rpx;    display: flex;    align-items: center;    background: #F8F8F8;    padding: 16rpx;    border-radius: 16rpx;    gap: 16rpx;    .item-cover {      width: 136rpx;      height: 200rpx;      border-radius: 16rpx;      // overflow: hidden;
            image {        width: 136rpx;      height: 200rpx;      }    }        .item-info {      // padding-top: 20rpx;
      gap: 16rpx;      display: flex;      flex-direction: column;      .item-title {                font-size: 32rpx;        font-weight: 700;        color: $primary-text-color;        letter-spacing: 0;        line-height: 48rpx;        // margin-bottom: 12rpx;
        overflow: hidden;        text-overflow: ellipsis;        white-space: nowrap;      }            .item-author {                font-size: 24rpx;        color: $secondary-text-color;        // margin-bottom: 8rpx;
        letter-spacing: 0;        overflow: hidden;        text-overflow: ellipsis;        white-space: nowrap;      }            .item-duration {        gap: 12rpx;        display: flex;        align-items: center;        font-size: 22rpx;        letter-spacing: 0;        color: $secondary-text-color;        .item-icon{          width: 22rpx;          height: 25rpx;        }      }    }  }}
// 推荐书籍列表
.book-list {  display: flex;  padding: 0 30rpx;  gap: 32rpx;    .book-item {    flex-shrink: 0;    width: 270rpx;    transition: transform 0.3s ease, box-shadow 0.3s ease;        &:active {      transform: scale(0.98);    }        .book-cover {      width: 100%;      height: 360rpx;      border-radius: 16rpx;      overflow: hidden;      position: relative;      box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.15);      transition: box-shadow 0.3s ease, transform 0.3s ease;            &:active {        box-shadow: 0 8rpx 30rpx rgba(0, 0, 0, 0.25);        transform: translateY(-2rpx);      }            image {        width: 100%;        height: 100%;        transition: transform 0.3s ease;      }      
      .book-overlay {        position: absolute;        bottom: 0;        left: 0;        right: 0;        width: 100%;        height: 140rpx;        padding: 20rpx 16rpx 12rpx;        box-sizing: border-box;                /* 优化的渐变遮罩效果 */        background: linear-gradient(          180deg,           rgba(0, 0, 0, 0) 0%,           rgba(0, 0, 0, 0.3) 30%,           rgba(0, 0, 0, 0.7) 70%,           rgba(0, 0, 0, 0.85) 100%        );                /* 增强的毛玻璃效果 */        backdrop-filter: blur(8px) saturate(1.2);        -webkit-backdrop-filter: blur(8px) saturate(1.2);                /* 添加微妙的边框 */        border-top: 1px solid rgba(255, 255, 255, 0.1);                /* 平滑过渡效果 */        transition: all 0.3s ease;
        .book-duration{          display: flex;          align-items: center;          gap: 6rpx;          margin-bottom: 8rpx;                    &-icon{            width: 22rpx;            height: 22rpx;            opacity: 0.9;          }          &-text{            font-size: 20rpx;            font-weight: 500;            color: rgba(255, 255, 255, 0.9);            text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);          }        }
        .book-title {          max-width: 220rpx;          font-size: 24rpx;          font-weight: 600;          line-height: 1.3;          color: #ffffff;          text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);                    /* 文本截断优化 */          display: -webkit-box;          -webkit-box-orient: vertical;          -webkit-line-clamp: 2;          overflow: hidden;          word-break: break-word;          white-space: normal;        }      }    }      }}
// 书籍网格布局
.book-grid {  display: flex;  flex-wrap: wrap;  padding: 0 30rpx;  gap: 32rpx;    .book-grid-item {    width: 208rpx;    display: flex;    flex-direction: column;    // backdrop-filter: red;
    .book-grid-cover {      box-shadow: 0px 4px 4px 0px #C0BCBA75;
      width: 100%;      height: 278rpx;      border-radius: 16rpx;      overflow: hidden;      margin-bottom: 16rpx;            image {        width: 100%;        height: 100%;      }    }        .book-grid-info {      width: 208rpx;      padding: 6rpx;      overflow: hidden;        text-overflow: ellipsis;        white-space: nowrap;      .book-grid-title {        font-size: 28rpx;        font-weight: 700;        color: $primary-text-color;        margin-bottom: 14rpx;             }            .book-grid-meta {        display: flex;        align-items: center;        // gap: 16rpx;
        .book-grid-duration-icon {          width: 24rpx;          height: 24rpx;          margin-right: 12rpx;        }        .book-grid-grade {          font-size: 24rpx;          color: $secondary-text-color;          margin-right: 8rpx;        }                .book-grid-duration {          font-size: 24rpx;          color: $secondary-text-color;        }      }    }  }}
// 推荐列表样式
.recommend-list {  padding: 0 30rpx;    .recommend-item {    width: 100%;    height: 200rpx;    margin-bottom: 48rpx;    border-radius: 32rpx;    overflow: hidden;        &:last-child {      margin-bottom: 0;    }        .recommend-image {      width: 100%;      height: 100%;    }  }}
// 视频弹窗样式
.video-container {  position: relative;  padding: 20rpx 0;    .video-loading {    display: flex;    align-items: center;    justify-content: center;    height: 400rpx;    background: #f5f5f5;    border-radius: 8rpx;        text {      font-size: 28rpx;      color: #999;    }  }}</style>
 |