xunji.vue 9.85 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>

    <TrainingFloating />
  </view>

</template>

<script setup>
import { ref, shallowRef, computed, onMounted } from 'vue';
import { onLoad, onHide, onShow } 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'
import { useTrainingStore } from '@/sheep/store/trainingStore';
const trainingStore = useTrainingStore();

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

// --- 补全缺失的响应式变量定义 ---
const currentTab = ref(1);
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);
  }
});

onShow(() => {
  const targetTab = uni.getStorageSync('xunjiTargetTab');
  if (targetTab !== '' && targetTab != null) {
    const tabNum = Number(targetTab);
    currentTab.value = tabNum;
    handleTabClick(tabNum);
    // 使用后清空缓存,避免下次进来自动跳转
    uni.removeStorageSync('xunjiTargetTab');
  }

})

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

// 打开抽屉
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 = () => { };

defineExpose({
  switchTabIndex: handleTabClick
})
</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>