train-history-button.vue 4.59 KB
<template>
    <!-- 历史按钮 + 弹窗 全部封装 -->
    <view>
        <!-- 历史按钮 -->
        <button class="history-btn" @click="openPopup">历史</button>

        <!-- 弹窗(组件内部管理) -->
        <u-popup :show="showPopup" mode="bottom" :mask-click="false" :safe-area-inset-bottom="true"
            @update:modelValue="showPopup = $event">
            <view class="history-section">
                <view class="popup-header">
                    <u-icon name="close" size="24" color="#333" @click="closePopup"></u-icon>
                </view>

                <view v-if="historyList.length > 0" class="history-list">
                    <view v-for="(item, index) in historyList" :key="index" class="history-card">
                        <view class="card-date">
                            <text class="date-text">{{ item.date ? `${item.date[0]}/${item.date[1]}/${item.date[2]}` :
                                '未知日期' }}</text>
                        </view>
                        <view class="card-body">
                            <view class="card-header">
                                <text class="history-name">{{ item.name }}</text>
                                <text class="history-set">{{ item.setCount }}组</text>
                            </view>
                            <view class="card-config">
                                <text class="config-text">配置数: {{ item.setConfigList?.length || 0 }}</text>
                            </view>
                        </view>
                    </view>
                </view>

                <view v-else class="empty-container">
                    <image :src="lostImage" class="empty-img"></image>
                    <text class="empty-text">暂无历史数据</text>
                </view>
            </view>
        </u-popup>
    </view>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import TrainingApi from '@/sheep/api/Training/traininghistory';

// 接收外部传入的 动作ID
const props = defineProps({
    exerciseId: {
        type: [String, Number],
        required: true
    }
});

// 内部状态(页面完全不需要知道)
const showPopup = ref(false);
const historyList = ref([]);
const lostImage = ref('https://fitness-hcxtec-bucket.oss-cn-shenzhen.aliyuncs.com/20260316/order-empty_1773628059920.png');

// 打开弹窗 + 加载数据
const openPopup = async () => {
    showPopup.value = true;
    await loadHistory(); // 打开时才加载,不打开不请求
};

// 关闭弹窗
const closePopup = () => {
    showPopup.value = false;
};

// 组件自己加载历史记录(核心!你页面彻底不用管)
const loadHistory = async () => {
    try {
        const res = await TrainingApi.getTrainHistoryList(props.exerciseId);
        historyList.value = res.data || [];
    } catch (err) {
        console.error('加载历史失败', err);
        historyList.value = [];
    }
};
</script>

<style scoped lang="scss">
/* 按钮样式和你原来完全一样 */
.history-btn {
    flex: 1;
    height: 60rpx;
    background-color: #eaeaea;
    color: #333;
    font-size: 28rpx;
    border-radius: 30rpx;
    border: none;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* 下面是你原来的全部弹窗样式,完整保留 */
.history-section {
    width: 100%;
    margin-top: 0;
    background-color: #ffffff;
    padding: 30rpx;
    box-sizing: border-box;
}

.popup-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 30rpx 0;
}

.history-list {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 20rpx;
}

.history-card {
    width: 100%;
    box-sizing: border-box;
    background: #f0f0f0;
    border-radius: 16rpx;
    padding: 30rpx;
    border: 1rpx solid #e5e5e5;
}

.card-date {
    margin-bottom: 16rpx;
}

.date-text {
    font-size: 28rpx;
    color: #333333;
    font-weight: 500;
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12rpx;
}

.history-name {
    font-size: 32rpx;
    color: #333333;
    font-weight: bold;
}

.history-set {
    font-size: 26rpx;
    color: #ffd700;
    padding: 6rpx 14rpx;
    border-radius: 8rpx;
}

.card-config .config-text {
    font-size: 26rpx;
    color: #666666;
}

.empty-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 60rpx 0;
}

.empty-img {
    width: 200rpx;
    height: 200rpx;
    margin-bottom: 30rpx;
    opacity: 0.6;
}

.empty-text {
    font-size: 28rpx;
    color: #999999;
}
</style>