wode-jihua-libiao-tancuang.vue 3.16 KB
<template>
  <up-popup :show="props.show" mode="bottom" round="24rpx" @close="emit('close')">
    <view class="planList-contain">
      <view class="popup-indicator"></view>
      <view class="title">选择训练计划</view>
      <!-- 计划列表 -->
      <view class="plan-list">
        <view class="plan-item" v-for="(item, index) in props.MyPlanList" :key="item.id"
          @tap="selectedIndex = index; emit('select', item.id)">
          <image class="plan-cover" :src="item.urlCover" mode="aspectFill"></image>
          <view class="plan-info">
            <view class="plan-name">{{ item.name }}</view>
            <view class="plan-desc">
              {{ getDifficultyText(item.difficultyLevel) }} · 一周{{ item.frequencyPerWeek }}练
            </view>
          </view>
          <view class="radio-btn" :class="{ active: selectedIndex === index }">
            <view class="radio-dot"></view>
          </view>
        </view>
      </view>
    </view>
  </up-popup>
</template>

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

const props = defineProps({
  show: { type: Boolean, default: false },
  MyPlanList: { type: Array, default: () => [] }
})

const emit = defineEmits(['close', 'select'])

// 选中的索引,默认选中第一个
const selectedIndex = ref(0)

// 难度等级转文字
const getDifficultyText = (level) => {
  const map = {
    1: '初阶',
    2: '中阶',
    3: '高阶'
  }
  return map[level] || '未知'
}

onMounted(() => {
  console.log('================挂载计划列表弹窗');


})
</script>

<style lang="scss" scoped>
.planList-contain {
  width: 100%;
  max-height: 80vh;
  padding: 30rpx;
  box-sizing: border-box;
  overflow: auto;


  .popup-indicator {
    width: 80rpx;
    height: 8rpx;
    background: #ddd;
    border-radius: 4rpx;
    margin: 0 auto 30rpx;
  }

  .title {
    font-size: 36rpx;
    font-weight: 500;
    text-align: center;
    margin-bottom: 40rpx;
  }

  .plan-list {
    display: flex;
    flex-direction: column;
    gap: 30rpx;

    .plan-item {
      position: relative;
      width: 100%;
      height: 300rpx;
      border-radius: 16rpx;
      overflow: hidden;

      .plan-cover {
        width: 100%;
        height: 100%;
        filter: brightness(0.7); // 给图片压暗,让文字更清晰
      }

      .plan-info {
        position: absolute;
        left: 30rpx;
        bottom: 30rpx;
        color: #fff;

        .plan-name {
          font-size: 32rpx;
          font-weight: 500;
          margin-bottom: 10rpx;
        }

        .plan-desc {
          font-size: 26rpx;
          opacity: 0.9;
        }
      }

      .radio-btn {
        position: absolute;
        right: 30rpx;
        top: 30rpx;
        width: 40rpx;
        height: 40rpx;
        border-radius: 50%;
        background: rgba(255, 255, 255, 0.8);
        display: flex;
        align-items: center;
        justify-content: center;

        .radio-dot {
          width: 24rpx;
          height: 24rpx;
          border-radius: 50%;
          background: transparent;
        }

        &.active {
          background: #ffd100;

          .radio-dot {
            background: #fff;
          }
        }
      }
    }
  }
}
</style>