zhxy-jzd/src/pages/base/course-selection/club-selection.vue

419 lines
8.2 KiB
Vue
Raw Normal View History

2025-05-07 09:44:23 +08:00
<template>
<view class="interest-course">
<!-- 选课信息头部 -->
<view class="selection-header">
<view class="header-content">
<view class="title">2023年秋季俱乐部选课</view>
<view class="countdown">
<text class="time-text">{{ remainTime }}</text>
<view class="time-icon">
<text class="time-value">90</text>
<text class="time-unit">mins</text>
</view>
</view>
</view>
<!-- 多选提示 -->
<view class="selection-tip">
<text>可选择多个俱乐部{{ selectedCount }}/{{ maxSelectCount }}</text>
</view>
</view>
<!-- 课程网格列表 -->
<view class="course-grid">
<view
v-for="(course, index) in courseList"
:key="index"
class="course-item"
:class="{ selected: course.isSelected }"
@click="toggleSelection(course)"
>
<view class="course-name">{{ course.title }}</view>
<view class="register-info">
<text>报名情况</text>
<text class="register-count">{{ course.registeredCount }}</text>
<text> | {{ course.maxCount }}</text>
</view>
<view class="detail-btn" @click.stop="viewCourseDetail(course)"
>详情</view
>
<view v-if="course.isSelected" class="selected-mark">
<uni-icons
type="checkbox-filled"
color="#3FBF72"
size="22"
></uni-icons>
</view>
</view>
</view>
<!-- 底部报名按钮 -->
<view class="register-btn-container">
<view class="selected-count">已选择{{ selectedCount }}/{{ maxSelectCount }}</view>
<view class="register-btn" @click="submitRegistration">点击报名</view>
</view>
</view>
</template>
<script setup lang="ts">
import { navigateTo } from "@/utils/uniapp";
import { ref, computed, onMounted } from "vue";
// 剩余时间
const remainTime = ref("89:57");
// 最大可选课程数
const maxSelectCount = ref(3);
// 计算已选课程数量
const selectedCount = computed(() => {
return courseList.value.filter(course => course.isSelected).length;
});
// 课程列表数据
const courseList = ref([
{
id: 1,
title: "少儿声乐",
registeredCount: 23,
maxCount: 30,
isSelected: true,
},
{
id: 2,
title: "机器人创客",
registeredCount: 23,
maxCount: 30,
isSelected: false,
},
{
id: 3,
title: "科学实践",
registeredCount: 23,
maxCount: 30,
isSelected: false,
},
{
id: 4,
title: "趣味手工",
registeredCount: 23,
maxCount: 30,
isSelected: false,
},
{
id: 5,
title: "动画制作",
registeredCount: 23,
maxCount: 30,
isSelected: false,
},
{
id: 6,
title: "趣味英语",
registeredCount: 23,
maxCount: 30,
isSelected: false,
},
{
id: 7,
title: "篮球",
registeredCount: 23,
maxCount: 30,
isSelected: false,
},
{
id: 8,
title: "足球",
registeredCount: 23,
maxCount: 30,
isSelected: false,
},
{
id: 9,
title: "羽毛球",
registeredCount: 23,
maxCount: 30,
isSelected: false,
},
{
id: 10,
title: "主持人",
registeredCount: 23,
maxCount: 30,
isSelected: false,
},
{
id: 11,
title: "心育课堂",
registeredCount: 23,
maxCount: 30,
isSelected: false,
},
{
id: 12,
title: "童戏皮影",
registeredCount: 23,
maxCount: 30,
isSelected: false,
},
]);
// 返回上一页
const goBack = () => {
uni.navigateBack();
};
// 查看课程详情
const viewCourseDetail = (course: any) => {
uni.navigateTo({
url: `/pages/base/course-selection/detail?id=${course.id}`,
});
};
// 选择或取消选择课程(改为多选)
const toggleSelection = (course: any) => {
// 如果当前课程未选中,且已达到最大选择数量,则提示
if (!course.isSelected && selectedCount.value >= maxSelectCount.value) {
uni.showToast({
title: `最多可选择${maxSelectCount.value}个俱乐部`,
icon: "none",
duration: 2000,
});
return;
}
// 直接切换当前课程的选中状态
course.isSelected = !course.isSelected;
uni.vibrateShort({
success: () => {
// 震动反馈成功
},
});
uni.showToast({
title: course.isSelected ? "已选择" : "已取消选择",
icon: "none",
duration: 500,
});
};
// 提交报名
const submitRegistration = () => {
const selectedCourses = courseList.value.filter(
(course) => course.isSelected
);
if (selectedCourses.length === 0) {
uni.showToast({
title: "请至少选择一个俱乐部",
icon: "none",
});
return;
}
uni.showModal({
title: "确认报名",
content: `您确定要报名已选择的${selectedCourses.length}个俱乐部吗?`,
success: (res) => {
if (res.confirm) {
uni.showLoading({
title: "报名中...",
});
// 模拟提交报名
setTimeout(() => {
uni.hideLoading();
navigateTo("/pages/base/course-selection/payment");
}, 1500);
}
},
});
};
// 页面加载
onMounted(() => {
// 实际应用中,可以从后端获取课程列表和倒计时信息
// fetchCourseList();
// startCountdown();
});
</script>
<style lang="scss" scoped>
.interest-course {
min-height: 100vh;
background-color: #f5f7fa;
padding-bottom: 80px;
}
.nav-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 15px;
height: 44px;
background-color: #fff;
.nav-left {
width: 40px;
height: 40px;
display: flex;
align-items: center;
}
.nav-title {
font-size: 18px;
font-weight: 500;
color: #333;
}
.nav-right {
width: 40px;
display: flex;
justify-content: flex-end;
}
}
.selection-header {
background-color: #eef4ff;
padding: 20px 15px;
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
.title {
font-size: 22px;
font-weight: bold;
color: #333;
}
.countdown {
display: flex;
align-items: center;
.time-text {
font-size: 22px;
font-weight: bold;
color: #ff4d4f;
margin-right: 10px;
}
.time-icon {
position: relative;
width: 52px;
height: 52px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #2879ff;
border-radius: 50%;
border: 2px solid #fff;
.time-value {
font-size: 16px;
font-weight: bold;
color: #fff;
}
.time-unit {
font-size: 10px;
color: #fff;
}
}
}
}
.selection-tip {
margin-top: 10px;
font-size: 14px;
color: #666;
}
}
.course-grid {
display: flex;
flex-wrap: wrap;
padding: 15px;
.course-item {
position: relative;
width: calc(50% - 10px);
margin-bottom: 15px;
background-color: #fff;
border-radius: 8px;
padding: 15px;
box-sizing: border-box;
&:nth-child(odd) {
margin-right: 10px;
}
&:nth-child(even) {
margin-left: 10px;
}
&.selected {
border: 1px solid #3fbf72;
}
.course-name {
font-size: 16px;
font-weight: 500;
color: #333;
margin-bottom: 10px;
}
.register-info {
font-size: 14px;
color: #666;
margin-bottom: 12px;
.register-count {
color: #2879ff;
}
}
.detail-btn {
display: inline-block;
color: #2879ff;
font-size: 14px;
}
.selected-mark {
position: absolute;
top: -6px;
right: -6px;
}
}
}
.register-btn-container {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 15px;
background-color: #fff;
.selected-count {
text-align: center;
font-size: 14px;
color: #666;
margin-bottom: 10px;
}
.register-btn {
height: 50px;
line-height: 50px;
text-align: center;
background-color: #2879ff;
color: #fff;
border-radius: 25px;
font-size: 16px;
font-weight: 500;
}
}
</style>