StuTrainingDetailDialog.vue 5.16 KB
<template>
  <el-dialog v-model="dialogVisible" title="训练记录详情" width="600px">
    <div v-loading="loading">
      <!-- 基础信息(一列) -->
      <el-descriptions v-if="detailData" border :column="1" label-width="120px">
        <el-descriptions-item label="学员">
          {{ detailData.username || '-' }}
        </el-descriptions-item>
        <el-descriptions-item label="手机号">
          {{ detailData.phone || '-' }}
        </el-descriptions-item>
      </el-descriptions>

      <!-- 训练单元列表 -->
      <div v-if="detailData.units && detailData.units.length > 0" class="unit-section">
        <h3 style="margin: 20px 0 10px; color: #333;">训练单元列表</h3>

        <!-- 循环每个训练单元 -->
        <div v-for="(unit, unitIndex) in detailData.units" :key="unit.id || unitIndex" class="unit-card">
          <!-- 单元基础信息(改成一列) -->
          <el-descriptions border :column="1" label-width="120px" size="small">
            <!-- <el-descriptions-item label="单元ID">
              {{ unit.id || '-' }}
            </el-descriptions-item> -->
            <el-descriptions-item label="单元名称">
              {{ unit.name || '-' }}
            </el-descriptions-item>
            <el-descriptions-item label="单元类型">
              {{ formatUnitType(unit.unitType) }}
            </el-descriptions-item>
            <el-descriptions-item label="单元顺序">
              {{ unit.sortOrder || '-' }}
            </el-descriptions-item>
          </el-descriptions>

          <!-- 动作列表(改成一列描述列表) -->
          <div v-if="unit.exercises && unit.exercises.length > 0" class="exercise-section">
            <h4 style="margin: 15px 0 8px; color: #409EFF;">动作列表</h4>

            <!-- 循环每个动作 -->
            <div v-for="(exercise, exIndex) in unit.exercises" :key="exercise.exerciseId || exIndex"
              class="exercise-card">
              <el-descriptions border :column="1" label-width="120px" size="small">
                <!-- <el-descriptions-item label="动作ID">
                  {{ exercise.exerciseId || '-' }}
                </el-descriptions-item> -->
                <el-descriptions-item label="排序">
                  {{ exercise.innerOrder || '-' }}
                </el-descriptions-item>
                <el-descriptions-item label="动作名称">
                  {{ exercise.name || '-' }}
                </el-descriptions-item>
                <!-- 训练组详情(一列) -->
                <el-descriptions-item label="训练组详情">
                  <el-table v-if="exercise.sets && exercise.sets.length > 0" :data="exercise.sets" border size="small"
                    stripe style="width: 100%;">
                    <el-table-column label="组号" width="80">
                      <template #default="scope">
                        {{ scope.$index + 1 }}
                      </template>
                    </el-table-column>
                    <el-table-column prop="weight" label="重量(kg)" width="100" />
                    <el-table-column prop="reps" label="次数" width="80" />
                    <el-table-column label="时长(分钟)" width="100">
                      <template #default="scope">
                        {{ scope.row.duration ? (scope.row.duration / 60).toFixed(1) : 0 }}
                      </template>
                    </el-table-column>
                    <el-table-column prop="restTime" label="休息(秒)" width="100" />
                  </el-table>
                  <div v-else>无训练组数据</div>
                </el-descriptions-item>
                <!--  -->
              </el-descriptions>
            </div>
          </div>
        </div>
      </div>
    </div>

    <template #footer>
      <el-button @click="dialogVisible = false">关闭</el-button>
    </template>
  </el-dialog>
</template>


<script setup>
import { ref, watch, computed } from 'vue'
import { stuTrainingRecordsApi } from '@/api/store/training/stuTrainingRecord'

const loading = ref(false)
const detailData = ref({})

const props = defineProps({
  visible: { type: Boolean, default: false },
  id: { type: [Number, String], default: null }
})

const emit = defineEmits(['update:visible'])

const dialogVisible = computed({
  get: () => props.visible,
  set: (val) => emit('update:visible', val)
})

watch(() => props.id, (newId) => {
  if (newId) getStuTrainingDetail(newId)
})
// 转换单元类型
const formatUnitType = (type) => {
  if (type === 1) return '动作组'
  if (type === 2) return '超级组'
  return '未知类型'
}
const getStuTrainingDetail = async (id) => {
  loading.value = true
  try {
    const res = await stuTrainingRecordsApi.getStuTrainingRecordDetail(id)
    detailData.value = res || {}
  } catch (err) {
    console.error('请求失败', err)
  } finally {
    loading.value = false
  }
}
</script>

<style scoped>
/* 单元卡片 */
.unit-card {
  padding: 15px;
  margin-bottom: 20px;
  background: #fafafa;
  border: 1px solid #ebeef5;
  border-radius: 8px;
}

/* 动作卡片 */
.exercise-card {
  padding: 10px;
  margin-top: 15px;
  background: #fff;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
}
</style>