|
@@ -3,99 +3,131 @@
|
|
|
<!-- 标签页切换 -->
|
|
<!-- 标签页切换 -->
|
|
|
<view class="tabs">
|
|
<view class="tabs">
|
|
|
<view class="tab-item" :class="{ active: currentTab === 'registered' }" @click="switchTab('registered')">
|
|
<view class="tab-item" :class="{ active: currentTab === 'registered' }" @click="switchTab('registered')">
|
|
|
- <text class="tab-text">已报名</text>
|
|
|
|
|
|
|
+ <text class="tab-text">我的活动</text>
|
|
|
<view class="tab-badge" v-if="registeredCount > 0">{{ registeredCount }}</view>
|
|
<view class="tab-badge" v-if="registeredCount > 0">{{ registeredCount }}</view>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="tab-item" :class="{ active: currentTab === 'joined' }" @click="switchTab('joined')">
|
|
<view class="tab-item" :class="{ active: currentTab === 'joined' }" @click="switchTab('joined')">
|
|
|
- <text class="tab-text">已参加</text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <view class="tab-item" :class="{ active: currentTab === 'favorite' }" @click="switchTab('favorite')">
|
|
|
|
|
- <text class="tab-text">我的收藏</text>
|
|
|
|
|
|
|
+ <text class="tab-text">我的课程</text>
|
|
|
|
|
+ <view class="tab-badge" v-if="purchasedCourses.length > 0">{{ purchasedCourses.length }}</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- 活动列表 -->
|
|
|
|
|
|
|
+ <!-- 活动/课程列表 -->
|
|
|
<view class="activities-list">
|
|
<view class="activities-list">
|
|
|
- <view class="activity-card" v-for="activity in filteredActivities" :key="activity.id" @click="goToActivityDetail(activity)">
|
|
|
|
|
- <image :src="activity.coverImage" class="activity-cover" mode="aspectFill"></image>
|
|
|
|
|
|
|
+ <!-- 活动卡片 -->
|
|
|
|
|
+ <view class="activity-card" v-for="item in registeredActivities" :key="`activity-${item.id}`" @click="goToActivityDetail(item.activityId)" v-if="currentTab === 'registered'">
|
|
|
|
|
+ <image :src="item.coverImage" class="activity-cover" mode="aspectFill"></image>
|
|
|
<view class="activity-info">
|
|
<view class="activity-info">
|
|
|
<view class="activity-header">
|
|
<view class="activity-header">
|
|
|
- <text class="activity-name">{{ activity.name }}</text>
|
|
|
|
|
- <el-tag :type="getStatusType(activity.status)" size="small">{{ getStatusText(activity.status) }}</el-tag>
|
|
|
|
|
|
|
+ <text class="activity-name">{{ item.name }}</text>
|
|
|
|
|
+ <!-- 修复:改用数组+字符串拼接的合法 :class 格式 -->
|
|
|
|
|
+ <view class="status-tag" :class="['status-' + getStatusType(item.status)]">{{ getStatusText(item.status) }}</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <view class="activity-meta">
|
|
|
|
|
|
|
+ <view class="activity-meta activity-meta--activity">
|
|
|
<view class="meta-item">
|
|
<view class="meta-item">
|
|
|
<text class="meta-icon">📅</text>
|
|
<text class="meta-icon">📅</text>
|
|
|
- <text class="meta-text">{{ formatDate(activity.startTime) }}</text>
|
|
|
|
|
|
|
+ <text class="meta-text">{{ formatDate(item.startTime) }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="meta-item" v-if="activity.location">
|
|
|
|
|
|
|
+ <view class="meta-item" v-if="item.location">
|
|
|
<text class="meta-icon">📍</text>
|
|
<text class="meta-icon">📍</text>
|
|
|
- <text class="meta-text">{{ activity.location }}</text>
|
|
|
|
|
|
|
+ <text class="meta-text">{{ item.location }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="meta-item">
|
|
<view class="meta-item">
|
|
|
<text class="meta-icon">👥</text>
|
|
<text class="meta-icon">👥</text>
|
|
|
- <text class="meta-text">{{ activity.actualParticipants }}/{{ activity.maxParticipants }}人</text>
|
|
|
|
|
|
|
+ <text class="meta-text">{{ item.actualParticipants }}/{{ item.maxParticipants }}人</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
<view class="activity-footer">
|
|
<view class="activity-footer">
|
|
|
- <text class="activity-price">¥{{ activity.price || 0 }}</text>
|
|
|
|
|
|
|
+ <text class="activity-price">¥{{ item.price || 0 }}</text>
|
|
|
<view class="activity-actions">
|
|
<view class="activity-actions">
|
|
|
- <button class="action-btn" size="mini" v-if="currentTab === 'registered'" @click.stop="cancelActivity(activity)">取消报名</button>
|
|
|
|
|
- <button class="action-btn primary" size="mini" @click.stop="goToActivityDetail(activity)">查看详情</button>
|
|
|
|
|
|
|
+ <button class="action-btn primary" size="mini" @click.stop="goToActivityDetail(item.activityId,item)">查看详情</button>
|
|
|
|
|
+ <!-- <button class="action-btn cancel" size="mini" @click.stop="cancelActivity(item)" v-if="item.status === 1">取消报名</button> -->
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <!-- 空状态 -->
|
|
|
|
|
- <view class="empty-state" v-if="filteredActivities.length === 0">
|
|
|
|
|
- <text class="empty-icon">📭</text>
|
|
|
|
|
- <text class="empty-text">{{ getEmptyText() }}</text>
|
|
|
|
|
|
|
+ <!-- 课程卡片 -->
|
|
|
|
|
+ <view class="course-card" v-for="item in purchasedCourses" :key="`course-${item.id}`" @click="goToDetail(item.id,item)" v-if="currentTab === 'joined'">
|
|
|
|
|
+ <image :src="item.cover_image" class="course-cover" mode="aspectFill"></image>
|
|
|
|
|
+ <view class="course-info">
|
|
|
|
|
+ <view class="course-header">
|
|
|
|
|
+ <text class="course-name">{{ item.name }}</text>
|
|
|
|
|
+ <view class="course-rating" v-if="item.rating">
|
|
|
|
|
+ <text class="meta-icon">⭐</text>
|
|
|
|
|
+ <text class="rating-text">{{ item.rating }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="course-meta">
|
|
|
|
|
+ <view class="meta-item">
|
|
|
|
|
+ <text class="meta-icon">👤</text>
|
|
|
|
|
+ <text class="meta-text">讲师: {{ item.teacher_name || '未知讲师' }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="meta-item">
|
|
|
|
|
+ <text class="meta-icon">⭐</text>
|
|
|
|
|
+ <text class="meta-text">{{item.rating}}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="meta-item">
|
|
|
|
|
+ <text class="meta-icon">👥</text>
|
|
|
|
|
+ <text class="meta-text">{{ item.student_count || 0 }}人已学习</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="course-footer">
|
|
|
|
|
+ <text class="course-price">¥{{ item.price || 0 }}</text>
|
|
|
|
|
+ <view class="course-actions">
|
|
|
|
|
+ <button class="action-btn primary course-btn" @click.stop="goToDetail(item.id,item)">查看详情</button>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 活动空状态 -->
|
|
|
|
|
+ <view class="empty-state" v-if="currentTab === 'registered' && registeredActivities.length === 0">
|
|
|
|
|
+ <text class="empty-icon">📅</text>
|
|
|
|
|
+ <text class="empty-text">暂无已报名的活动</text>
|
|
|
<button class="browse-btn" @click="goToActivityList">浏览活动</button>
|
|
<button class="browse-btn" @click="goToActivityList">浏览活动</button>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 课程空状态 -->
|
|
|
|
|
+ <view class="empty-state" v-if="currentTab === 'joined' && purchasedCourses.length === 0">
|
|
|
|
|
+ <text class="empty-icon">📚</text>
|
|
|
|
|
+ <text class="empty-text">暂无已购买的课程</text>
|
|
|
|
|
+ <button class="browse-btn" @click="goToCourseList">浏览课程</button>
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
<script>
|
|
|
|
|
+import api from '@/utils/api'
|
|
|
|
|
+
|
|
|
export default {
|
|
export default {
|
|
|
data() {
|
|
data() {
|
|
|
return {
|
|
return {
|
|
|
currentTab: 'registered',
|
|
currentTab: 'registered',
|
|
|
|
|
+ // 活动相关
|
|
|
registeredActivities: [],
|
|
registeredActivities: [],
|
|
|
- joinedActivities: [],
|
|
|
|
|
- favoriteActivities: [],
|
|
|
|
|
- registeredCount: 0
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
- computed: {
|
|
|
|
|
- filteredActivities() {
|
|
|
|
|
- if (this.currentTab === 'registered') {
|
|
|
|
|
- return this.registeredActivities
|
|
|
|
|
- } else if (this.currentTab === 'joined') {
|
|
|
|
|
- return this.joinedActivities
|
|
|
|
|
- } else {
|
|
|
|
|
- return this.favoriteActivities
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ registeredCount: 0,
|
|
|
|
|
+ // 课程相关
|
|
|
|
|
+ purchasedCourses: [], // 已购买的课程
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
onLoad() {
|
|
onLoad() {
|
|
|
- this.loadMyActivities()
|
|
|
|
|
|
|
+ this.loadMyData()
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
methods: {
|
|
methods: {
|
|
|
- // 加载我的活动
|
|
|
|
|
- async loadMyActivities() {
|
|
|
|
|
|
|
+ // 加载我的活动和课程数据
|
|
|
|
|
+ async loadMyData() {
|
|
|
try {
|
|
try {
|
|
|
const userInfo = uni.getStorageSync('userInfo')
|
|
const userInfo = uni.getStorageSync('userInfo')
|
|
|
-
|
|
|
|
|
|
|
|
|
|
if (!userInfo || !userInfo.userId) {
|
|
if (!userInfo || !userInfo.userId) {
|
|
|
- console.warn('用户未登录')
|
|
|
|
|
uni.showToast({
|
|
uni.showToast({
|
|
|
title: '请先登录',
|
|
title: '请先登录',
|
|
|
icon: 'none'
|
|
icon: 'none'
|
|
@@ -103,74 +135,77 @@ export default {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const baseUrl = 'https://api.zhongruanke.cn' // 本地开发
|
|
|
|
|
- // const baseUrl = 'http://115.190.125.125:8083' // 生产环境
|
|
|
|
|
|
|
+ // 并行加载活动和课程数据
|
|
|
|
|
+ await Promise.all([
|
|
|
|
|
+ this.loadRegisteredActivities(userInfo.userId),
|
|
|
|
|
+ this.loadPurchasedCourses(userInfo.userId)
|
|
|
|
|
+ ])
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- // 获取已报名的活动(status=1)
|
|
|
|
|
- const [error1, registeredRes] = await uni.request({
|
|
|
|
|
- url: `${baseUrl}/api/activity-registration/my-activities?userId=${userInfo.userId}&status=1`,
|
|
|
|
|
- method: 'GET'
|
|
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('加载数据失败:', error)
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '加载数据失败',
|
|
|
|
|
+ icon: 'none'
|
|
|
})
|
|
})
|
|
|
-
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ // 加载已报名的活动
|
|
|
|
|
+ async loadRegisteredActivities(userId) {
|
|
|
|
|
+ const baseUrl = 'https://api.zhongruanke.cn'
|
|
|
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ const [error, res] = await uni.request({
|
|
|
|
|
+ url: `${baseUrl}/api/activity-registration/my-activities?userId=${userId}&status=1`,
|
|
|
|
|
+ method: 'GET'
|
|
|
|
|
+ })
|
|
|
|
|
|
|
|
- if (error1) {
|
|
|
|
|
- console.error('查询已报名活动失败:', error1)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (registeredRes && registeredRes.data && registeredRes.data.code === 200) {
|
|
|
|
|
-
|
|
|
|
|
- this.registeredActivities = (registeredRes.data.data || []).map(item => ({
|
|
|
|
|
|
|
+ if (res && res.data && res.data.code === 200) {
|
|
|
|
|
+ this.registeredActivities = (res.data.data || []).map(item => ({
|
|
|
id: item.id,
|
|
id: item.id,
|
|
|
activityId: item.activityId,
|
|
activityId: item.activityId,
|
|
|
name: item.activityName,
|
|
name: item.activityName,
|
|
|
- coverImage: item.coverImage,
|
|
|
|
|
|
|
+ coverImage: item.coverImage || '/static/default-activity.png',
|
|
|
startTime: item.startTime,
|
|
startTime: item.startTime,
|
|
|
endTime: item.endTime,
|
|
endTime: item.endTime,
|
|
|
location: item.location,
|
|
location: item.location,
|
|
|
price: item.price,
|
|
price: item.price,
|
|
|
- actualParticipants: item.actualParticipants,
|
|
|
|
|
- maxParticipants: item.maxParticipants,
|
|
|
|
|
|
|
+ actualParticipants: item.actualParticipants || 0,
|
|
|
|
|
+ maxParticipants: item.maxParticipants || 0,
|
|
|
status: this.getActivityStatusByTime(item.startTime, item.endTime)
|
|
status: this.getActivityStatusByTime(item.startTime, item.endTime)
|
|
|
}))
|
|
}))
|
|
|
this.registeredCount = this.registeredActivities.length
|
|
this.registeredCount = this.registeredActivities.length
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // 获取已签到的活动(status=3)
|
|
|
|
|
- const [error2, joinedRes] = await uni.request({
|
|
|
|
|
- url: `${baseUrl}/api/activity-registration/my-activities?userId=${userInfo.userId}&status=3`,
|
|
|
|
|
- method: 'GET'
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- if (error2) {
|
|
|
|
|
- console.error('查询已参加活动失败:', error2)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (joinedRes && joinedRes.data && joinedRes.data.code === 200) {
|
|
|
|
|
- this.joinedActivities = (joinedRes.data.data || []).map(item => ({
|
|
|
|
|
- id: item.id,
|
|
|
|
|
- activityId: item.activityId,
|
|
|
|
|
- name: item.activityName,
|
|
|
|
|
- coverImage: item.coverImage,
|
|
|
|
|
- startTime: item.startTime,
|
|
|
|
|
- endTime: item.endTime,
|
|
|
|
|
- location: item.location,
|
|
|
|
|
- price: item.price,
|
|
|
|
|
- actualParticipants: item.actualParticipants,
|
|
|
|
|
- maxParticipants: item.maxParticipants,
|
|
|
|
|
- status: 3
|
|
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('加载活动数据失败:', error)
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ // 加载已购买的课程
|
|
|
|
|
+ async loadPurchasedCourses(userId) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const coursesRes = await api.courseOrder.getPurchasedCourses(userId)
|
|
|
|
|
+ console.log(coursesRes)
|
|
|
|
|
+ this.purchasedCourses = coursesRes
|
|
|
|
|
+ if (coursesRes.code === 200) {
|
|
|
|
|
+ this.purchasedCourses = (coursesRes.data || []).map(course => ({
|
|
|
|
|
+ id: course.id,
|
|
|
|
|
+ courseId: course.id,
|
|
|
|
|
+ name: course.courseName,
|
|
|
|
|
+ coverImage: course.coverImage || '/static/default-course.png',
|
|
|
|
|
+ teacher: course.teacher,
|
|
|
|
|
+ price: course.price,
|
|
|
|
|
+ studentsCount: course.studentsCount || 0,
|
|
|
|
|
+ rating: course.rating || 4.5,
|
|
|
|
|
+ chaptersCount: course.chaptersCount || 0, // 课程章节数
|
|
|
|
|
+ lessonsCount: course.lessonsCount || 0, // 课程课时数
|
|
|
|
|
+ learnProgress: course.learnProgress || 0, // 学习进度
|
|
|
|
|
+ lastLearnTime: course.lastLearnTime // 最后学习时间
|
|
|
}))
|
|
}))
|
|
|
|
|
+ console.log(this.purchasedCourses)
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // 收藏功能暂时为空
|
|
|
|
|
- this.favoriteActivities = []
|
|
|
|
|
-
|
|
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
- console.error('加载我的活动失败:', error)
|
|
|
|
|
|
|
+ console.error('加载课程数据失败:', error)
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
|
|
@@ -187,9 +222,26 @@ export default {
|
|
|
return 3 // 已结束
|
|
return 3 // 已结束
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
|
|
+ // 获取活动状态类型(用于样式)
|
|
|
|
|
+ getStatusType(status) {
|
|
|
|
|
+ const types = { 1: 'pending', 2: 'ongoing', 3: 'ended' }
|
|
|
|
|
+ return types[status] || 'pending'
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ // 获取活动状态文本
|
|
|
|
|
+ getStatusText(status) {
|
|
|
|
|
+ const texts = { 1: '未开始', 2: '进行中', 3: '已结束' }
|
|
|
|
|
+ return texts[status] || '未知'
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
// 切换标签页
|
|
// 切换标签页
|
|
|
switchTab(tab) {
|
|
switchTab(tab) {
|
|
|
this.currentTab = tab
|
|
this.currentTab = tab
|
|
|
|
|
+ // 切换时滚动到顶部
|
|
|
|
|
+ uni.pageScrollTo({
|
|
|
|
|
+ scrollTop: 0,
|
|
|
|
|
+ duration: 300
|
|
|
|
|
+ })
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
// 格式化日期
|
|
// 格式化日期
|
|
@@ -207,63 +259,29 @@ export default {
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
- // 获取状态类型
|
|
|
|
|
- getStatusType(status) {
|
|
|
|
|
- const types = { 1: 'info', 2: 'success', 3: 'default' }
|
|
|
|
|
- return types[status] || 'info'
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
- // 获取状态文本
|
|
|
|
|
- getStatusText(status) {
|
|
|
|
|
- const texts = { 1: '未开始', 2: '进行中', 3: '已结束' }
|
|
|
|
|
- return texts[status] || '未知'
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
- // 获取空状态文本
|
|
|
|
|
- getEmptyText() {
|
|
|
|
|
- const texts = {
|
|
|
|
|
- registered: '暂无报名的活动',
|
|
|
|
|
- joined: '暂无参加过的活动',
|
|
|
|
|
- favorite: '暂无收藏的活动'
|
|
|
|
|
- }
|
|
|
|
|
- return texts[this.currentTab] || '暂无数据'
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
- // 取消报名
|
|
|
|
|
|
|
+ // 取消活动报名
|
|
|
async cancelActivity(activity) {
|
|
async cancelActivity(activity) {
|
|
|
uni.showModal({
|
|
uni.showModal({
|
|
|
- title: '提示',
|
|
|
|
|
- content: '确定要取消报名吗?',
|
|
|
|
|
|
|
+ title: '取消报名',
|
|
|
|
|
+ content: '确定要取消本次活动报名吗?',
|
|
|
success: async (res) => {
|
|
success: async (res) => {
|
|
|
if (res.confirm) {
|
|
if (res.confirm) {
|
|
|
try {
|
|
try {
|
|
|
const userInfo = uni.getStorageSync('userInfo')
|
|
const userInfo = uni.getStorageSync('userInfo')
|
|
|
const baseUrl = 'https://api.zhongruanke.cn'
|
|
const baseUrl = 'https://api.zhongruanke.cn'
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
const [error, result] = await uni.request({
|
|
const [error, result] = await uni.request({
|
|
|
url: `${baseUrl}/api/activity-registration/cancel?id=${activity.id}&userId=${userInfo.userId}`,
|
|
url: `${baseUrl}/api/activity-registration/cancel?id=${activity.id}&userId=${userInfo.userId}`,
|
|
|
method: 'PUT'
|
|
method: 'PUT'
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- if (error) {
|
|
|
|
|
- console.error('取消报名请求失败:', error)
|
|
|
|
|
- uni.showToast({
|
|
|
|
|
- title: '网络错误,请重试',
|
|
|
|
|
- icon: 'none'
|
|
|
|
|
- })
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
if (result && result.data && result.data.code === 200) {
|
|
if (result && result.data && result.data.code === 200) {
|
|
|
uni.showToast({
|
|
uni.showToast({
|
|
|
- title: '已取消报名',
|
|
|
|
|
|
|
+ title: '取消报名成功',
|
|
|
icon: 'success'
|
|
icon: 'success'
|
|
|
})
|
|
})
|
|
|
- this.loadMyActivities()
|
|
|
|
|
|
|
+ // 重新加载活动数据
|
|
|
|
|
+ this.loadRegisteredActivities(userInfo.userId)
|
|
|
} else {
|
|
} else {
|
|
|
uni.showToast({
|
|
uni.showToast({
|
|
|
title: (result && result.data && result.data.msg) || '取消失败',
|
|
title: (result && result.data && result.data.msg) || '取消失败',
|
|
@@ -271,9 +289,8 @@ export default {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
- console.error('取消报名失败:', error)
|
|
|
|
|
uni.showToast({
|
|
uni.showToast({
|
|
|
- title: '取消失败',
|
|
|
|
|
|
|
+ title: '取消失败,请重试',
|
|
|
icon: 'none'
|
|
icon: 'none'
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
@@ -283,9 +300,27 @@ export default {
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
// 跳转到活动详情
|
|
// 跳转到活动详情
|
|
|
- goToActivityDetail(activity) {
|
|
|
|
|
|
|
+ goToActivityDetail(itemId,item) {
|
|
|
|
|
+ uni.navigateTo({
|
|
|
|
|
+ url: `/pages/activities/detail?id=${item.activityId}`
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ // 跳转到详情
|
|
|
|
|
+ goToDetail(id,item) {
|
|
|
|
|
+
|
|
|
uni.navigateTo({
|
|
uni.navigateTo({
|
|
|
- url: `/pages/activities/detail?id=${activity.activityId}`
|
|
|
|
|
|
|
+ url: `/pages/courses/detail?id=${item.id}`,
|
|
|
|
|
+ success: () => {
|
|
|
|
|
+
|
|
|
|
|
+ },
|
|
|
|
|
+ fail: (err) => {
|
|
|
|
|
+
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '跳转失败',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
|
|
|
|
@@ -296,9 +331,11 @@ export default {
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
- // 返回上一页
|
|
|
|
|
- goBack() {
|
|
|
|
|
- uni.navigateBack()
|
|
|
|
|
|
|
+ // 跳转到课程列表
|
|
|
|
|
+ goToCourseList() {
|
|
|
|
|
+ uni.navigateTo({
|
|
|
|
|
+ url: '/pages/courses/list'
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -307,14 +344,15 @@ export default {
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
.my-activities-page {
|
|
.my-activities-page {
|
|
|
min-height: 100vh;
|
|
min-height: 100vh;
|
|
|
- background: #F5F5F5;
|
|
|
|
|
|
|
+ background: #FFF9F9;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 标签页 */
|
|
|
|
|
|
|
+/* 标签页样式 */
|
|
|
.tabs {
|
|
.tabs {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
background: white;
|
|
background: white;
|
|
|
padding: 0 30rpx;
|
|
padding: 0 30rpx;
|
|
|
|
|
+ border-bottom: 1rpx solid #f0f0f0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.tab-item {
|
|
.tab-item {
|
|
@@ -325,13 +363,13 @@ export default {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.tab-text {
|
|
.tab-text {
|
|
|
- font-size: 28rpx;
|
|
|
|
|
|
|
+ font-size: 30rpx;
|
|
|
color: #666;
|
|
color: #666;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.tab-item.active .tab-text {
|
|
.tab-item.active .tab-text {
|
|
|
color: #E91E63;
|
|
color: #E91E63;
|
|
|
- font-weight: bold;
|
|
|
|
|
|
|
+ font-weight: 600;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.tab-item.active::after {
|
|
.tab-item.active::after {
|
|
@@ -340,7 +378,7 @@ export default {
|
|
|
bottom: 0;
|
|
bottom: 0;
|
|
|
left: 50%;
|
|
left: 50%;
|
|
|
transform: translateX(-50%);
|
|
transform: translateX(-50%);
|
|
|
- width: 60rpx;
|
|
|
|
|
|
|
+ width: 80rpx;
|
|
|
height: 6rpx;
|
|
height: 6rpx;
|
|
|
background: #E91E63;
|
|
background: #E91E63;
|
|
|
border-radius: 3rpx;
|
|
border-radius: 3rpx;
|
|
@@ -359,48 +397,78 @@ export default {
|
|
|
text-align: center;
|
|
text-align: center;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 活动列表 */
|
|
|
|
|
|
|
+/* 列表容器 */
|
|
|
.activities-list {
|
|
.activities-list {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: 1fr 1fr;
|
|
|
|
|
+ gap: 20rpx;
|
|
|
padding: 20rpx;
|
|
padding: 20rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/* 活动卡片样式 */
|
|
|
.activity-card {
|
|
.activity-card {
|
|
|
|
|
+ position: relative;
|
|
|
background: white;
|
|
background: white;
|
|
|
- border-radius: 16rpx;
|
|
|
|
|
- margin-bottom: 20rpx;
|
|
|
|
|
|
|
+ border-radius: 20rpx;
|
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
|
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
|
|
|
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.activity-cover {
|
|
.activity-cover {
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
- height: 200rpx;
|
|
|
|
|
|
|
+ height: 240rpx;
|
|
|
background: #F5F5F5;
|
|
background: #F5F5F5;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.activity-info {
|
|
.activity-info {
|
|
|
- padding: 24rpx;
|
|
|
|
|
|
|
+ padding: 20rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.activity-header {
|
|
.activity-header {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
|
- align-items: center;
|
|
|
|
|
- margin-bottom: 16rpx;
|
|
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ margin-bottom: 15rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.activity-name {
|
|
.activity-name {
|
|
|
- font-size: 32rpx;
|
|
|
|
|
- font-weight: bold;
|
|
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ font-weight: 600;
|
|
|
color: #333;
|
|
color: #333;
|
|
|
flex: 1;
|
|
flex: 1;
|
|
|
- margin-right: 16rpx;
|
|
|
|
|
|
|
+ margin-right: 10rpx;
|
|
|
|
|
+ display: -webkit-box;
|
|
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
|
|
+ -webkit-line-clamp: 2;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ line-height: 1.4;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 活动状态标签 */
|
|
|
|
|
+.status-tag {
|
|
|
|
|
+ font-size: 20rpx;
|
|
|
|
|
+ padding: 4rpx 12rpx;
|
|
|
|
|
+ border-radius: 12rpx;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.status-pending {
|
|
|
|
|
+ background-color: #409EFF; /* 未开始-蓝色 */
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.status-ongoing {
|
|
|
|
|
+ background-color: #67C23A; /* 进行中-绿色 */
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.status-ended {
|
|
|
|
|
+ background-color: #909399; /* 已结束-灰色 */
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.activity-meta {
|
|
|
|
|
|
|
+/* 活动元信息 */
|
|
|
|
|
+.activity-meta--activity {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
- gap: 12rpx;
|
|
|
|
|
|
|
+ gap: 10rpx;
|
|
|
margin-bottom: 20rpx;
|
|
margin-bottom: 20rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -417,43 +485,126 @@ export default {
|
|
|
.meta-text {
|
|
.meta-text {
|
|
|
font-size: 24rpx;
|
|
font-size: 24rpx;
|
|
|
color: #666;
|
|
color: #666;
|
|
|
|
|
+ line-height: 1.4;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.activity-footer {
|
|
.activity-footer {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
- padding-top: 16rpx;
|
|
|
|
|
- border-top: 1rpx solid #F0F0F0;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.activity-price {
|
|
.activity-price {
|
|
|
- font-size: 32rpx;
|
|
|
|
|
- font-weight: bold;
|
|
|
|
|
color: #E91E63;
|
|
color: #E91E63;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ font-size: 32rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 课程卡片样式 */
|
|
|
|
|
+.course-card {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ background: white;
|
|
|
|
|
+ border-radius: 20rpx;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.course-cover {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 240rpx;
|
|
|
|
|
+ background: #F5F5F5;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.course-info {
|
|
|
|
|
+ padding: 20rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.course-header {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: flex-start;
|
|
|
|
|
+ margin-bottom: 15rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+.course-name {
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ margin-right: 10rpx;
|
|
|
|
|
+ display: -webkit-box;
|
|
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
|
|
+ -webkit-line-clamp: 2;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ line-height: 1.4;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.course-rating {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ gap: 4rpx;
|
|
|
|
|
+ background-color: #FFF8E1;
|
|
|
|
|
+ padding: 4rpx 10rpx;
|
|
|
|
|
+ border-radius: 10rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.rating-text {
|
|
|
|
|
+ font-size: 20rpx;
|
|
|
|
|
+ color: #FF9800;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 课程元信息 */
|
|
|
|
|
+.course-meta {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 10rpx;
|
|
|
|
|
+ margin-bottom: 20rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.course-footer {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.course-price {
|
|
|
|
|
+ color: #9C27B0;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ font-size: 32rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 按钮样式 */
|
|
|
.activity-actions {
|
|
.activity-actions {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
- gap: 16rpx;
|
|
|
|
|
|
|
+ gap: 10rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.action-btn {
|
|
.action-btn {
|
|
|
- padding: 8rpx 24rpx;
|
|
|
|
|
- background: #F5F5F5;
|
|
|
|
|
- color: #666;
|
|
|
|
|
|
|
+ padding: 8rpx 16rpx;
|
|
|
border-radius: 20rpx;
|
|
border-radius: 20rpx;
|
|
|
font-size: 24rpx;
|
|
font-size: 24rpx;
|
|
|
border: none;
|
|
border: none;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.action-btn.primary {
|
|
.action-btn.primary {
|
|
|
- background: #E91E63;
|
|
|
|
|
|
|
+ background-color: #E91E63;
|
|
|
color: white;
|
|
color: white;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/* 空状态 */
|
|
|
|
|
|
|
+.action-btn.cancel {
|
|
|
|
|
+ background-color: #F5F5F5;
|
|
|
|
|
+ color: #666;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.course-btn {
|
|
|
|
|
+ background-color: #9C27B0 !important;
|
|
|
|
|
+ width: 140rpx;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 空状态样式 */
|
|
|
.empty-state {
|
|
.empty-state {
|
|
|
|
|
+ grid-column: 1 / -1;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
@@ -480,5 +631,4 @@ export default {
|
|
|
font-size: 28rpx;
|
|
font-size: 28rpx;
|
|
|
border: none;
|
|
border: none;
|
|
|
}
|
|
}
|
|
|
-</style>
|
|
|
|
|
-
|
|
|
|
|
|
|
+</style>
|