xunji.vue 9.94 KB
<template>
  <view class="home-page" v-if="userStore.isLogin">
    <view class="tab-bar" :style="{ paddingTop: menuButtonHeight + topSafeArea + 'px' }">
      <view class="tab-item" :class="{ active: currentTab === 0 }" @click="handleTabClick(0)"
        >训记</view
      >
      <view class="tab-item" :class="{ active: currentTab === 1 }" @click="handleTabClick(1)"
        >计划</view
      >
      <view class="tab-item" :class="{ active: currentTab === 2 }" @click="handleTabClick(2)"
        >日历</view
      >
      <view class="tab-item" :class="{ active: currentTab === 3 }" @click="handleTabClick(3)"
        >动作</view
      >
      <view class="tab-item" :class="{ active: currentTab === 4 }" @click="handleTabClick(4)"
        >模板</view
      >
      <view class="tab-item" :class="{ active: currentTab === 5 }" @click="handleTabClick(5)"
        >数据</view
      >
      <view class="menu-btn" @click="openDrawer">
        <uni-icons type="bars" size="20"></uni-icons>
      </view>
    </view>

    <view class="content">
      <xunjiXunji v-if="currentTab === 0" />
      <xunjiXunlianjihua v-if="currentTab === 1" />
      <xunjiRili v-if="currentTab === 2" />
      <xunjiDongzuo v-if="currentTab === 3" />
      <xunjiMoban v-if="currentTab === 4" />
      <xunjiShuju v-if="currentTab === 5" />
    </view>

    <Tabbar />

    <uni-drawer ref="drawer" mode="right" :mask="true" :width="280">
      <view class="drawer-content" :style="{ paddingTop: menuButtonHeight + topSafeArea + 'px' }">
        <view class="user-header">
          <image
            class="avatar"
            :src="
              userInfo.avatar ||
              'https://fitness-hcxtec-bucket.oss-cn-shenzhen.aliyuncs.com/20260526/默认头像_1779779926983.png'
            "
            mode="aspectFill"
          ></image>
          <view class="user-info">
            <text class="nickname">{{ userInfo.nickname || '未登录' }}</text>
          </view>
        </view>

        <image
          class="ad-banner"
          src="https://fitness-hcxtec-bucket.oss-cn-shenzhen.aliyuncs.com/20260316/37_1773628025534.png"
          mode="aspectFill"
        ></image>

        <view class="menu-list">
          <view class="menu-item" @click="navigateTo('/pages4/pages/xunji/xunji-wode-zhuye')">
            <uni-icons type="person" size="18"></uni-icons>
            <text class="menu-text">我的主页</text>
            <uni-icons type="right" size="14"></uni-icons>
          </view>
          <view class="menu-item" @click="navigateTo('/pages4/pages/xunji/xunji-wode-moban')">
            <uni-icons type="wallet" size="18"></uni-icons>
            <text class="menu-text">我的模板</text>
            <uni-icons type="right" size="14"></uni-icons>
          </view>
          <view class="menu-item" @click="navigateTo('/pages4/pages/xunji/xunji-wode-jihua')">
            <uni-icons type="list" size="18"></uni-icons>
            <text class="menu-text">我的计划</text>
            <uni-icons type="right" size="14"></uni-icons>
          </view>
          <view class="menu-item" @click="goWidgetLib">
            <uni-icons type="more" size="18"></uni-icons>
            <text class="menu-text">小组件库</text>
            <uni-icons type="right" size="14"></uni-icons>
          </view>
          <view class="menu-item" @click="goFeedback">
            <uni-icons type="chat" size="18"></uni-icons>
            <text class="menu-text">训记反馈建议</text>
            <uni-icons type="right" size="14"></uni-icons>
          </view>
          <view class="menu-item" @click="goUserGroup">
            <uni-icons type="chatboxes" size="18"></uni-icons>
            <text class="menu-text">训记内测用户群</text>
            <uni-icons type="right" size="14"></uni-icons>
          </view>
          <view class="menu-item" @click="goTutorial">
            <uni-icons type="help" size="18"></uni-icons>
            <text class="menu-text">训记使用教程</text>
            <uni-icons type="right" size="14"></uni-icons>
          </view>
        </view>
      </view>
    </uni-drawer>
  </view>
</template>

<script setup>
  import { ref, shallowRef, computed, onMounted } from 'vue';
  import { onLoad, onHide } from '@dcloudio/uni-app';
  import useUserStore from '@/sheep/store/user';
  import { getMenuButtonHeight, getTopSafeArea } from '@/utils/safeArea';

  // 组件导入
  import xunjiRili from '@/pages/xunji/components/xunji-rili.vue';
  import xunjiDongzuo from '@/pages/xunji/components/xunji-dongzuo.vue';
  import xunjiMoban from '@/pages/xunji/components/xunji-moban.vue';
  import xunjiShuju from '@/pages/xunji/components/xunji-shuju.vue';
  import xunjiXunji from '@/pages/xunji/components/xunji-xunji.vue';
  import xunjiXunlianjihua from '@/pages/xunji/components/xunji-xunlianjihua.vue';
  import TrainingFloating from '@/pages/TrainingFloating.vue';

  // 状态管理
  const userStore = useUserStore();

  // --- 补全缺失的响应式变量定义 ---
  const currentTab = ref(0);
  const currentComponent = shallowRef(xunjiXunji); // 用于 H5 端动态组件切换(如保留原功能逻辑)
  const drawer = ref(null); // uni-drawer 的组件实例引用

  // 安全区域相关变量(从工具函数异步或同步获取)
  const menuButtonHeight = ref(getMenuButtonHeight ? getMenuButtonHeight() : 0);
  const topSafeArea = ref(getTopSafeArea ? getTopSafeArea() : 0);

  // 用户信息计算属性(防止 store 异步更新时报错)
  const userInfo = computed(() => userStore.userInfo || {});

  // --- 原有页面生命周期维护 ---
  onHide(() => {
    if (drawer.value) {
      drawer.value.close();
    }
  });

  onLoad((options) => {
    if (!userStore.isLogin) {
      uni.redirectTo({
        url: '/pages7/pages/index/login',
      });
      return;
    }
    // 确保解析路由参数的正确性
    if (options && options.currentTab) {
      currentTab.value = Number(options.currentTab);
    }
  });

  // --- 原有业务方法补充与修复 ---

  // 打开抽屉
  const openDrawer = () => {
    if (drawer.value) {
      drawer.value.open();
    }
  };

  // 修复模板直接调用 uni.navigateTo 的多端兼容问题
  const navigateTo = (url) => {
    uni.navigateTo({ url });
  };

  // 处理标签点击
  const handleTabClick = (index) => {
    currentTab.value = index;
    // #ifdef H5
    switch (index) {
      case 0:
        currentComponent.value = xunjiXunji;
        break;
      case 1:
        currentComponent.value = xunjiXunlianjihua;
        break;
      case 2:
        currentComponent.value = xunjiRili;
        break;
      case 3:
        currentComponent.value = xunjiDongzuo;
        break;
      case 4:
        currentComponent.value = xunjiMoban;
        break;
      case 5:
        currentComponent.value = xunjiShuju;
        break;
      default:
        currentComponent.value = xunjiXunlianjihua;
    }
    // #endif
  };

  // 空实现占位(防止模板点击报错,保持你原有的未给出的方法定义)
  const goWidgetLib = () => {
    uni.navigateTo({ url: '/pages4/pages/xunji/widget' });
  };
  const goFeedback = () => {};
  const goUserGroup = () => {};
  const goTutorial = () => {};
</script>
<style scoped lang="scss">
  .home-page {
    width: 100%;
    height: 100vh;
    // #ifdef H5
    padding-bottom: 90rpx;
    // #endif
    background-color: #f5f5f5;
    box-sizing: border-box;
    overflow: hidden;
    display: flex;
    flex-direction: column;

    .content {
      flex: 1;
      box-sizing: border-box;
      overflow: hidden;
      padding-top: 70rpx;
      //    #ifdef MP-WEIXIN
      padding-top: 200rpx;
      //    #endif
    }
  }

  .tab-bar {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    padding: 0px 20px;
    padding-top: 20rpx;
    background-color: #fff;

    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 999;
    box-sizing: border-box;
  }

  /* 标签项:默认样式 */
  .tab-item {
    font-size: 16px;
    color: #666;
    padding: 5px 0;
    padding-top: 30rpx;
  }

  /* 激活态标签:下划线+深色文字 */
  .tab-item.active {
    color: #333;
    border-bottom: 2px solid #000;
    font-weight: 500;
  }

  /* 菜单按钮:样式 */
  .menu-btn {
    font-size: 20px;
    color: #666;
  }

  .card-subtitle {
    font-size: 24rpx;
    color: #666;
    margin-bottom: 10rpx;
  }

  .plan-btn {
    width: 100%;
    height: 50rpx;
    background-color: #2eaa8a;
    color: white;
    font-size: 24rpx;
    font-weight: bold;
    border-radius: 25rpx;
    line-height: 50rpx;
    text-align: center;
    margin-top: 10rpx;
  }

  .card-value {
    font-size: 36rpx;
    color: #333;
    margin-bottom: 10rpx;
  }

  .card-desc {
    font-size: 24rpx;
    color: #666;
  }

  /* 抽屉样式 */
  .drawer-content {
    background-color: #ffffff;
    height: 100%;
    padding: 20rpx;
    box-sizing: border-box;
  }

  /* 用户头像和信息区域 */
  .user-header {
    display: flex;
    align-items: center;
    padding: 20rpx 0;
    border-bottom: 1px solid #f0f0f0;
  }

  .user-header .avatar {
    width: 80rpx;
    height: 80rpx;
    border-radius: 50%;
    margin-right: 20rpx;
    margin-top: 0;
    justify-content: flex-start;
  }

  .user-info {
    display: flex;
    flex-direction: column;
  }

  .nickname {
    font-size: 28rpx;
    font-weight: 500;
    color: #333333;
    margin-bottom: 8rpx;
  }

  .user-id {
    font-size: 24rpx;
    color: #999999;
  }

  /* 广告横幅 */
  .ad-banner {
    width: 100%;
    height: 200rpx;
    margin: 20rpx 0;
    border-radius: 12rpx;
  }

  /* 菜单列表 */
  .menu-list {
    margin-top: 20rpx;
  }

  .menu-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 30rpx 0;
    border-bottom: 1px solid #f0f0f0;
  }

  .menu-item:last-child {
    border-bottom: none;
  }

  .menu-text {
    font-size: 28rpx;
    color: #333333;
    margin-left: 20rpx;
    flex: 1;
  }

  /* 覆盖uni-icons默认颜色 */
  :deep(.uni-icons) {
    color: #666666;
  }
</style>