修正多处问题,添加骨架屏

This commit is contained in:
2026-06-29 16:41:36 +08:00
parent e85f39ab83
commit 13b99428de
124 changed files with 929 additions and 147 deletions
@@ -1,4 +1,4 @@
<!-- components/LoadingOverlay.vue -->
<!-- components/LoadingOverlay.vue -->
<template>
<view v-if="visible" class="loading-overlay">
<view class="loading-content">
+1 -1
View File
@@ -1,4 +1,4 @@
<template>
<template>
<view class="checkin-page">
<!-- 顶部导航栏固定顶部 -->
<view class="header">
+2 -2
View File
@@ -1,4 +1,4 @@
<!-- pages/course/index.vue -->
<!-- pages/course/index.vue -->
<template>
<view class="scroll-container">
<view class="tab-page">
@@ -270,4 +270,4 @@ function goMyCourses() {
z-index: 1000;
background-color: transparent;
}
</style>
</style>
@@ -1,4 +1,4 @@
<template>
<template>
<view class="course-detail-page">
<!-- 页面头部 -->
<PageHeader title="课程详情" subtitle="团课预约" :show-back="true" />
@@ -64,7 +64,7 @@
<view class="cover-image-wrapper">
<image
v-if="course.coverImage"
:src="course.coverImage"
:src="getCourseCoverUrl(course.coverImage)"
mode="aspectFill"
class="cover-image"
/>
@@ -245,6 +245,7 @@
import { ref, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getGroupCourseDetail, bookGroupCourse } from '@/api/groupCourse.js'
import { getCourseCoverUrl } from '@/utils/request.js'
import { getPrimaryMemberCard } from '@/api/main.js'
import { getMemberId } from '@/utils/request.js'
import PageHeader from '@/components/index/PageHeader.vue'
@@ -46,8 +46,16 @@
</view>
</view>
<scroll-view
v-if="!pageReady"
class="course-list-skel"
>
<ListSkeleton :count="4" layout="card" :show-tabs="false" />
</scroll-view>
<!-- 团课列表 -->
<scroll-view
v-else
scroll-y
class="course-list"
@scrolltolower="onScrollToLower"
@@ -95,6 +103,7 @@ import FilterSection from '@/components/groupCourse/FilterSection.vue'
import TimePeriodSelector from '@/components/groupCourse/TimePeriodSelector.vue'
import TimeRangePicker from '@/components/groupCourse/TimeRangePicker.vue'
import PageHeader from '@/components/index/PageHeader.vue'
import ListSkeleton from '@/components/Skeleton/ListSkeleton.vue'
import { useGroupCourseList } from '@/composables/useGroupCourseList.js'
import { getTypeLabels, getGroupCourseTypes, getMemberBookings } from '@/api/groupCourse.js'
import { getMemberId } from '@/utils/request.js'
@@ -111,6 +120,9 @@ const courseTypeLabelsCache = ref({})
// 已预约课程ID集合
const bookedCourseIds = ref(new Set())
// 页面加载状态
const pageReady = ref(false)
// 使用组合式函数
const {
// 状态
@@ -162,6 +174,7 @@ onMounted(async () => {
])
// 获取所有团课的类型标签
await fetchAllCourseTypeLabels()
pageReady.value = true
console.log('[list.vue] 可用的搜索参数获取方法:')
console.log(' - searchBarRef.getSearchParams()')
console.log(' - filterSectionRef.getFilterParams()')
+2 -2
View File
@@ -1,4 +1,4 @@
<template>
<template>
<!-- 页面头部 -->
<PageHeader title="活氧舱" subtitle="科学训练 · 遇见更好的自己" />
@@ -100,4 +100,4 @@ onMounted(() => {
.bottom-placeholder {
height: 120rpx;
}
</style>
</style>
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="历史对比" @back="onBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="连接设备" @back="onBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="体测报告" @back="onBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="体测" @back="goBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="测量中" @back="onCancel" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="体测报告" @back="onBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="体测设置" @back="onBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="趋势分析" @back="onBack" />
@@ -27,6 +27,9 @@
</view>
<view class="booking-page__body">
<!-- 骨架屏 -->
<ListSkeleton v-if="loading" :count="4" layout="card" />
<!-- 无数据 -->
<view v-if="!displayedBookings.length && !loading" class="booking-page__empty">
<text class="booking-page__empty-text">
@@ -43,7 +46,7 @@
>
<image
class="bk-card__banner"
:src="item.coverImage || item.banner || 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/default-course.png'"
:src="item.banner"
mode="aspectFill"
/>
<view class="bk-card__content">
@@ -114,7 +117,9 @@
<script setup>
import { ref, computed, onMounted } from 'vue'
import PageHeader from '@/components/index/PageHeader.vue'
import ListSkeleton from '@/components/Skeleton/ListSkeleton.vue'
import { getMemberId } from '@/utils/request.js'
import { getCourseCoverUrl } from '@/utils/request.js'
import { getMemberBookings, signinGroupCourse, cancelBooking as cancelBookingApi } from '@/api/main.js'
const tabs = ref([
@@ -175,7 +180,7 @@ function mapBooking(b) {
status: status,
statusLabel: getBookingStatusLabel(b),
schedule: formatBookingTime(b.courseStartTime || b.startTime || b.bookingTime),
banner: b.coverImage || '',
banner: getCourseCoverUrl(b.coverImage) || 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/default-course.png',
coach: b.coachName || b.coach || '教练',
footerText: status === 'ongoing' ? '请准时参加课程' : '',
canSignin: status === 'ongoing',
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="card-detail-page">
<view v-if="card" class="card-detail-page__body">
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<PageHeader title="签到记录" subtitle="" :show-back="true" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="confirm-payment-page">
<view class="cp-scroll-wrap">
<scroll-view scroll-y class="cp-scroll">
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="领券中心" @back="onBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page" v-if="coupon">
<MemberInfoSubNav title="优惠券详情" @back="onBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="我的优惠券" @back="goBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page" v-if="course">
<MemberInfoSubNav title="课程详情" @back="onBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="课程评价" @back="onBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page mi-course-list">
<MemberInfoSubNav title="预约课程" @back="goBack" />
+1 -1
View File
@@ -1,4 +1,4 @@
<template>
<template>
<view class="login-page">
<!-- 自定义Toast弹窗 -->
<view class="custom-toast" :class="{ show: toastShow }">
@@ -1,4 +1,4 @@
<template>
<template>
<view class="member-card-page">
<!-- 固定页面头部 -->
<view class="member-card-page-header">
@@ -1,4 +1,4 @@
<template>
<template>
<scroll-view scroll-y class="scroll-container theme-light">
<view class="member-page">
<!-- Header: 用户信息区 -->
@@ -7,7 +7,10 @@
<!-- 滚动内容区域 -->
<view class="member-scroll-wrap">
<scroll-view scroll-y class="member-scroll">
<!-- 骨架屏 -->
<MemberCenterSkeleton v-if="!pageReady" />
<scroll-view v-else scroll-y class="member-scroll">
<view class="member-page">
<MemberInfoHeader
:user-info="userInfo"
@@ -58,6 +61,7 @@ import { setToken, getToken, clearToken } from '@/utils/request.js'
import MemberInfoHeader from '@/components/memberInfo/MemberInfoHeader.vue'
import MemberInfoMemberCard from '@/components/memberInfo/MemberInfoMemberCard.vue'
import MemberInfoLogout from '@/components/memberInfo/MemberInfoLogout.vue'
import MemberCenterSkeleton from '@/components/Skeleton/MemberCenterSkeleton.vue'
import TabBar from '@/components/TabBar.vue'
import PageHeader from '@/components/index/PageHeader.vue'
@@ -65,6 +69,7 @@ const userInfo = ref({})
const stats = ref({})
const cardInfo = ref({})
const loading = ref(false)
const pageReady = ref(false)
const hasActiveCard = ref(false)
const isLogin = ref(false)
@@ -175,9 +180,11 @@ async function fetchMemberInfo() {
// store
refreshFromStore()
pageReady.value = true
console.log('[memberInfo] fetchMemberInfo 执行完成')
} catch (err) {
console.error('[memberInfo] 获取会员信息失败:', err)
pageReady.value = true
} finally {
loading.value = false
}
@@ -23,6 +23,9 @@
>已完成</text>
</view>
<!-- 骨架屏 -->
<ListSkeleton v-if="loading" :count="4" layout="card" />
<!-- 预约列表 -->
<view
v-for="item in displayedBookings"
@@ -32,7 +35,7 @@
>
<image
class="mi-mod-course-card__banner"
:src="item.coverImage || 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/default-course.png'"
:src="item.coverImage"
mode="aspectFill"
/>
<view class="mi-mod-course-card__content">
@@ -72,8 +75,10 @@
<script setup>
import { ref, computed, onMounted } from 'vue'
import PageHeader from '@/components/index/PageHeader.vue'
import ListSkeleton from '@/components/Skeleton/ListSkeleton.vue'
import PayPasswordModal from '@/components/global/PayPasswordModal.vue'
import { getMemberId } from '@/utils/request.js'
import { getCourseCoverUrl } from '@/utils/request.js'
import { getMemberBookings, qrSignInGroupCourse } from '@/api/groupCourse.js'
import { cancelBooking as cancelBookingApi } from '@/api/groupCourse.js'
import { getConfigByKey } from '@/api/main.js'
@@ -190,7 +195,7 @@ function mapBooking(b) {
statusClass: statusClass,
schedule: formatBookingTime(courseStartTime),
location: b.location || '',
coverImage: b.coverImage || ''
coverImage: getCourseCoverUrl(b.coverImage) || 'https://gymfuture.oss-cn-chengdu.aliyuncs.com/static/images/default-course.png'
}
}
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page" v-if="course">
<MemberInfoSubNav title="线上课程" @back="onBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="我的积分" @back="goBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="积分明细" @back="onBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="积分商城" @back="onBack" />
@@ -11,8 +11,11 @@
<text class="pc-intro__desc">购买后立即生效享受专属会员权益</text>
</view>
<!-- 骨架屏 -->
<ListSkeleton v-if="loadingCards" :count="3" layout="simple" />
<!-- 卡列表 -->
<view class="pc-list">
<view v-else-if="cardTypes.length" class="pc-list">
<view
v-for="card in cardTypes"
:key="card.id"
@@ -268,6 +271,7 @@
<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import ListSkeleton from '@/components/Skeleton/ListSkeleton.vue'
import { purchaseMemberCard, createPayment, createQrCodePayment, getPaymentStatus, queryHuifuTradeByOrderId, getActiveMemberCards } from '@/api/main.js'
import { getMemberId } from '@/utils/request.js'
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="recharge-page">
<MemberInfoSubNav title="储值卡充值" @back="goBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="邀请好友" @back="goBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="set-pay-password-page">
<MemberInfoSubNav :title="isReset ? '修改支付密码' : '设置支付密码'" @back="goBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page">
<MemberInfoSubNav title="训练报告" @back="goBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="bt-page" v-if="session">
<MemberInfoSubNav title="训练详情" @back="onBack" />
@@ -1,4 +1,4 @@
<template>
<template>
<view class="scroll-container theme-light">
<view class="Pixso-frame-2_791">
<PageHeader title="个人信息" subtitle="" :show-back="true" />
+1 -1
View File
@@ -1,4 +1,4 @@
<template>
<template>
<view class="message-detail-page">
<!-- 顶部导航栏 -->
<view class="nav-header" :style="navStyle">
+1 -1
View File
@@ -1,4 +1,4 @@
<template>
<template>
<view class="message-page">
<!-- 顶部导航栏 - 使用自定义导航栏适配胶囊 -->
<view class="nav-header" :style="navStyle">
@@ -1,4 +1,4 @@
<!-- pages/recommendCourses/index.vue -->
<!-- pages/recommendCourses/index.vue -->
<template>
<!-- 页面容器 -->
<view class="recommend-page">