xunji-wode-moban.vue 5.59 KB
<template>
  <view class="container">
    <!-- 页面头部 -->
    <view class="header">
      <u-icon name="arrow-left" size="32" color="#333" @click="back"></u-icon>
      <text class="title">我的训练模板</text>
    </view>


    <!-- 筛选标签 + 加号按钮容器 -->
    <view class="filter-wrapper">
      <view class="filter-container">
        <view class="filter-item" @click="toggleFilter('position')">
          <text>部位</text>
          <u-icon name="arrow-down" size="20" color="#999"></u-icon>
        </view>
        <view class="filter-item" @click="toggleFilter('scene')">
          <text>场景</text>
          <u-icon name="arrow-down" size="20" color="#999"></u-icon>
        </view>
      </view>
      <view class="add-btn" @click="addTemplate">
        <uni-icons type="plus" size="35" color="#333"></uni-icons>
      </view>
    </view>

    <!-- 模板列表容器 -->
    <view class="content">
      <!-- 无数据状态 -->
      <view v-if="templates.length === 0" class="empty-state">
        <image src="https://fitness-hcxtec-bucket.oss-cn-shenzhen.aliyuncs.com/20260316/order-empty_1773628059920.png"
          class="empty-image"></image>
        <text class="empty-text">暂无该模板</text>
      </view>

      <!-- 模板卡片列表 -->
      <view v-else class="template-list">
        <view v-for="(item, index) in templates" :key="index" class="template-card">
          <image src="https://fitness-hcxtec-bucket.oss-cn-shenzhen.aliyuncs.com/20260316/order-empty_1773628059920.png"
            class="card-image"></image>
          <view class="card-content">
            <text class="card-title">{{ item.name }}</text>
            <text class="card-desc">{{ item.desc }}</text>
            <view class="card-footer">
              <text class="footer-label">难度:</text>
              <text class="footer-value">{{ item.difficulty }}</text>
              <text class="footer-label">时长:</text>
              <text class="footer-value">{{ item.duration }}分钟</text>
            </view>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted } from 'vue';

// ====== 响应式数据 ======
const templates = ref([]);
const showPositionFilter = ref(false);
const showSceneFilter = ref(false);

// ====== 模拟接口:获取训练模板数据 ======
const fetchTemplates = () => {
  const mockData = [
    {
      id: 1,
      name: '全身燃脂训练',
      desc: '高效燃脂,适合初学者',
      difficulty: '初级',
      duration: 30,
    },
    {
      id: 2,
      name: '核心力量训练',
      desc: '强化腹部与腰部力量',
      difficulty: '中级',
      duration: 25,
    },
    {
      id: 3,
      name: '背部塑形训练',
      desc: '改善体态,塑造完美背影',
      difficulty: '高级',
      duration: 40,
    },
  ];
  templates.value = mockData;
};

// ====== 方法 ======
const back = () => {
  uni.navigateBack();
};

const addTemplate = () => {
  uni.navigateTo({
    url: '/pages/xunji/xunji-muban-xinzeng',
  });
};

const toggleFilter = (type) => {
  if (type === 'position') {
    showPositionFilter.value = !showPositionFilter.value;
  } else if (type === 'scene') {
    showSceneFilter.value = !showSceneFilter.value;
  }
};

// ====== 页面生命周期 ======
onMounted(() => {
  fetchTemplates();
});
</script>

<style scoped lang="scss">
.container {
  margin-top: 80rpx;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  background-color: #f5f5f5;
  box-sizing: border-box;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20rpx 20rpx;
  padding-top: 60rpx;
  background-color: #fff;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
  z-index: 10;
}

.title {
  font-size: 36rpx;
  font-weight: bold;
  color: #333;
  flex: 1;
  text-align: center;
}


.filter-wrapper {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20rpx;
  background-color: #fff;
}

.filter-container {
  display: flex;
  gap: 20rpx;
  padding: 20rpx;
  background-color: #fff;
}

.filter-item {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8rpx;
  padding: 12rpx 20rpx;
  background-color: #f5f5f5;
  border-radius: 20rpx;
  font-size: 28rpx;
  color: #333;
  cursor: pointer;
}

.add-btn {
  display: flex;
  width: 60rpx;
  height: 60rpx;
  background-color: #fff;
  color: #333;
  align-items: center;
  justify-content: center;
  margin-left: 20rpx;
}

.content {
  flex: 1;
  padding: 20rpx;
  overflow-y: auto;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 500rpx;
}

.empty-image {
  width: 180rpx;
  height: 180rpx;
  object-fit: contain;
  margin-bottom: 30rpx;
}

.empty-text {
  font-size: 28rpx;
  color: #999;
  text-align: center;
}

.template-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20rpx;
}

.template-card {
  background-color: #fff;
  border-radius: 20rpx;
  overflow: hidden;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}

.card-image {
  width: 100%;
  height: 200rpx;
  object-fit: cover;
}

.card-content {
  padding: 20rpx;
}

.card-title {
  font-size: 30rpx;
  color: #333;
  font-weight: 500;
  margin-bottom: 10rpx;
}

.card-desc {
  font-size: 24rpx;
  color: #666;
  line-height: 1.5;
  margin-bottom: 15rpx;
}

.card-footer {
  display: flex;
  gap: 10rpx;
  font-size: 24rpx;
  color: #999;
}

.footer-label {
  font-weight: 500;
}

.footer-value {
  color: #333;
}

/* 防止内容溢出 */
.view {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>