调整路径

This commit is contained in:
ywyonui 2025-08-06 12:57:01 +08:00
parent dd41251a1f
commit 9ffab44ca4
25 changed files with 410 additions and 2782 deletions

View File

@ -144,14 +144,14 @@
} }
}, },
{ {
"path": "pages/base/interest-class/index", "path": "pages/base/xk/xqk",
"style": { "style": {
"navigationBarTitleText": "兴趣课", "navigationBarTitleText": "兴趣课",
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
}, },
{ {
"path": "pages/base/club/index", "path": "pages/base/xk/jlb",
"style": { "style": {
"navigationBarTitleText": "俱乐部", "navigationBarTitleText": "俱乐部",
"enablePullDownRefresh": false "enablePullDownRefresh": false
@ -193,28 +193,49 @@
} }
}, },
{ {
"path": "pages/base/course-selection/index", "path": "pages/base/xk/qk/xqk",
"style": { "style": {
"navigationBarTitleText": "课程选择", "navigationBarTitleText": "兴趣课选课",
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
}, },
{ {
"path": "pages/base/course-selection/detail", "path": "pages/base/xk/qk/jlb",
"style": {
"navigationBarTitleText": "俱乐部选课",
"enablePullDownRefresh": false
}
},
{
"path": "pages/base/xk/qk/wks",
"style": {
"navigationBarTitleText": "未开始选课",
"enablePullDownRefresh": false
}
},
{
"path": "pages/base/xk/qk/yjz",
"style": {
"navigationBarTitleText": "已截止选课",
"enablePullDownRefresh": false
}
},
{
"path": "pages/base/xk/detail",
"style": { "style": {
"navigationBarTitleText": "课程详情", "navigationBarTitleText": "课程详情",
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
}, },
{ {
"path": "pages/base/course-selection/payment", "path": "pages/base/xk/pay/index",
"style": { "style": {
"navigationBarTitleText": "支付", "navigationBarTitleText": "支付",
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
}, },
{ {
"path": "pages/base/course-selection/pay-wait", "path": "pages/base/xk/pay/wait",
"style": { "style": {
"navigationBarTitleText": "", "navigationBarTitleText": "",
"enablePullDownRefresh": false, "enablePullDownRefresh": false,
@ -224,60 +245,32 @@
} }
}, },
{ {
"path": "pages/base/course-selection/payment-success", "path": "pages/base/xk/pay/success",
"style": { "style": {
"navigationBarTitleText": "支付成功", "navigationBarTitleText": "支付成功",
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
}, },
{ {
"path": "pages/base/course-selection/payment-fail", "path": "pages/base/xk/pay/fail",
"style": { "style": {
"navigationBarTitleText": "支付失败", "navigationBarTitleText": "支付失败",
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
}, },
{ {
"path": "pages/base/course-selection/club-selection", "path": "pages/base/gzs/xkXqk",
"style": { "style": {
"navigationBarTitleText": "俱乐部选课", "navigationBarTitleText": "兴趣课告知书",
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
}, },
{ {
"path": "pages/base/course-selection/notice", "path": "pages/base/gzs/xkJlb",
"style": { "style": {
"navigationBarTitleText": "告知书", "navigationBarTitleText": "俱乐部告知书",
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
},
{
"path": "pages/base/course-selection/noticeclub",
"style": {
"navigationBarTitleText": "告知书",
"enablePullDownRefresh": false
}
},
{
"path": "pages/base/course-selection/enrolled",
"style": {
"navigationBarTitleText": "已报名",
"enablePullDownRefresh": false
}
} , {
"path": "pages/base/course-selection/notopen",
"style": {
"navigationBarTitleText": "未开放",
"enablePullDownRefresh": false
}
},
{
"path": "pages/base/course-selection/enrollment-ended",
"style": {
"navigationBarTitleText": "选课已结束",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
} }
], ],
"globalStyle": { "globalStyle": {

View File

@ -1,433 +0,0 @@
<template>
<BasicLayout>
<view class="p-15">
<!-- 顶部蓝色背景横幅 -->
<view class="banner-section">
<view class="banner-placeholder">
<view class="banner-content">
<text class="banner-title">兴趣课程</text>
<text class="banner-school">泸州市实验小学城西学校</text>
</view>
</view>
</view>
<!-- 课程类型选项卡 -->
<view class="my-course-section">
<view class="section-title">
<u-icon name="calendar" size="18" color="#1976d2"></u-icon>
<text class="title-text">我的课程</text>
</view>
<view class="tabs-container">
<view
class="tab-item"
:class="{ 'active': activeTab === 'basketball' }"
@click="switchTab('basketball')"
>
<text>篮球</text>
</view>
<view
class="tab-item"
:class="{ 'active': activeTab === 'football' }"
@click="switchTab('football')"
>
<text>足球</text>
</view>
</view>
<!-- 篮球课程信息卡片 -->
<view class="course-card" v-if="activeTab === 'basketball'">
<view class="course-image-placeholder"></view>
<view class="course-info">
<text class="course-name">篮球</text>
<view class="course-detail">
<text class="detail-label">开课老师</text>
<text class="detail-value">叶老师</text>
</view>
<view class="course-detail">
<text class="detail-label">上课地点</text>
<text class="detail-value">教学楼3楼</text>
</view>
</view>
</view>
<!-- 足球课程信息卡片 -->
<view class="course-card" v-if="activeTab === 'football'">
<view class="course-image-placeholder"></view>
<view class="course-info">
<text class="course-name">足球</text>
<view class="course-detail">
<text class="detail-label">开课老师</text>
<text class="detail-value">王老师</text>
</view>
<view class="course-detail">
<text class="detail-label">上课地点</text>
<text class="detail-value">操场</text>
</view>
</view>
</view>
</view>
<!-- 教学计划 -->
<view class="teaching-plan-section">
<view class="section-title-bar">
<text class="title-text">教学计划</text>
</view>
<!-- 篮球教学计划 -->
<view class="plan-content" v-if="activeTab === 'basketball'">
<view class="plan-item">
<text class="plan-phase">第一阶段</text>
<text class="plan-desc">了解机器人的组成知道每个零件的名称及用途认识机器人的结构</text>
</view>
<view class="plan-item">
<text class="plan-phase">第二阶段</text>
<text class="plan-desc">在老师的引导下分组搭建机器人注意引导幼儿理解机器人的数据线连接和遥控器方向的关系</text>
</view>
<view class="plan-item">
<text class="plan-phase">第三阶段</text>
<text class="plan-desc">学会操控机器人的移动方向并练习把魔方根据要求推到指定位置</text>
</view>
<view class="plan-item">
<text class="plan-phase">第四阶段</text>
<text class="plan-desc">组织幼儿参加创客机器人比赛</text>
</view>
</view>
<!-- 足球教学计划 -->
<view class="plan-content" v-if="activeTab === 'football'">
<view class="plan-item">
<text class="plan-phase">第一阶段</text>
<text class="plan-desc">基础训练包括传球控球和基本规则学习</text>
</view>
<view class="plan-item">
<text class="plan-phase">第二阶段</text>
<text class="plan-desc">进阶技巧学习包括带球跑动射门和防守基础</text>
</view>
<view class="plan-item">
<text class="plan-phase">第三阶段</text>
<text class="plan-desc">团队配合训练学习简单的战术配合和位置意识</text>
</view>
<view class="plan-item">
<text class="plan-phase">第四阶段</text>
<text class="plan-desc">小型比赛实践培养学生的团队协作能力和比赛经验</text>
</view>
</view>
</view>
<!-- 课堂随拍 -->
<view class="class-photos-section">
<view class="section-title-bar">
<text class="title-text">课堂随拍</text>
</view>
<!-- 篮球课堂照片 -->
<view class="photos-grid" v-if="activeTab === 'basketball'">
<view class="photo-placeholder"></view>
<view class="photo-placeholder"></view>
<view class="photo-placeholder"></view>
<view class="photo-placeholder"></view>
</view>
<!-- 足球课堂照片 -->
<view class="photos-grid" v-if="activeTab === 'football'">
<view class="photo-placeholder football-photo"></view>
<view class="photo-placeholder football-photo"></view>
<view class="photo-placeholder football-photo"></view>
<view class="photo-placeholder football-photo"></view>
</view>
</view>
</view>
<template #bottom>
<view class="white-bg-color py-5">
<view class="flex-row items-center pb-10 pt-5">
<u-button text="取消" class="ml-15 mr-7" :plain="true" @click="navigateBack"/>
<u-button text="退课申请" class="mr-15 mr-7" type="primary" @click="submit"/>
</view>
</view>
</template>
</BasicLayout>
</template>
<script lang="ts" setup>
import { navigateBack } from "@/utils/uniapp";
import { ref } from "vue";
import { xkFindDqXsApi } from "@/api/base/server";
import { useUserStore } from "@/store/modules/user";
const { getCurXs } = useUserStore();
//
const activeTab = ref('basketball');
//
function switchTab(tab: string) {
activeTab.value = tab;
}
function submit() {
const courseName = activeTab.value === 'basketball' ? '篮球' : '足球';
uni.showModal({
title: '确认退课',
content: `确定要退出${courseName}课程吗?`,
success: (res) => {
if (res.confirm) {
uni.showToast({
title: `${courseName}退课申请已提交`,
icon: 'none'
});
}
}
});
}
onMounted(async () => {
// Make onMounted async
xkFindDqXsApi({
xsId: getCurXs.id,
xklxId: '816059832'
}).then(res => {
// result
if (res && res.resultCode === 1) {
console.log(res)
} else {
//
console.warn("检查获取当前学期俱乐部接口返回错误:", res);
}
})
.catch((error) => {
//
console.error("调用获取当前学期俱乐部接口失败:", error);
});
});
</script>
<style lang="scss" scoped>
/* 顶部蓝色背景横幅 */
.banner-section {
margin-bottom: 15px;
.banner-placeholder {
height: 120px;
background-color: #3986FF;
border-radius: 10px;
display: flex;
justify-content: center;
align-items: center;
.banner-content {
text-align: center;
.banner-title {
font-size: 22px;
color: #ffffff;
font-weight: 500;
margin-bottom: 8px;
display: block;
}
.banner-school {
font-size: 14px;
color: rgba(255, 255, 255, 0.9);
}
}
}
}
/* 我的课程 */
.my-course-section {
margin-bottom: 15px;
.section-title {
display: flex;
align-items: center;
margin-bottom: 12px;
.title-text {
font-size: 16px;
font-weight: 500;
color: #303133;
margin-left: 6px;
}
}
.tabs-container {
display: flex;
border-bottom: 1px solid #ebeef5;
margin-bottom: 15px;
.tab-item {
padding: 12px 0;
margin-right: 20px;
position: relative;
text {
color: #606266;
font-size: 15px;
}
&.active {
text {
color: #1976d2;
font-weight: 500;
}
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 2px;
background-color: #1976d2;
}
}
}
}
.course-card {
background-color: #ffffff;
border-radius: 10px;
padding: 15px;
display: flex;
align-items: center;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.05);
.course-image-placeholder {
width: 120px;
height: 100px;
background-color: #f0f0f0;
border-radius: 6px;
margin-right: 15px;
flex-shrink: 0;
}
.course-info {
flex: 1;
.course-name {
font-size: 18px;
font-weight: 500;
color: #303133;
margin-bottom: 10px;
}
.course-detail {
display: flex;
margin-bottom: 6px;
&:last-child {
margin-bottom: 0;
}
.detail-label {
color: #606266;
font-size: 14px;
}
.detail-value {
color: #303133;
font-size: 14px;
}
}
}
}
}
/* 教学计划 */
.teaching-plan-section {
margin-bottom: 15px;
background-color: #ffffff;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.05);
.section-title-bar {
padding: 12px 15px;
border-bottom: 1px solid #f2f2f2;
.title-text {
font-size: 16px;
font-weight: 500;
color: #303133;
}
}
.plan-content {
padding: 15px;
.plan-item {
margin-bottom: 15px;
&:last-child {
margin-bottom: 0;
}
}
.plan-phase {
font-size: 15px;
font-weight: 500;
color: #303133;
}
.plan-desc {
font-size: 14px;
color: #606266;
line-height: 1.5;
}
}
}
/* 课堂随拍 */
.class-photos-section {
background-color: #ffffff;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.05);
margin-bottom: 60px;
.section-title-bar {
padding: 12px 15px;
border-bottom: 1px solid #f2f2f2;
.title-text {
font-size: 16px;
font-weight: 500;
color: #303133;
}
}
.photos-grid {
display: flex;
flex-wrap: wrap;
padding: 15px;
.photo-placeholder {
width: calc(50% - 8px);
height: 110px;
background-color: #f0f0f0;
border-radius: 6px;
margin-right: 8px;
margin-bottom: 8px;
&:nth-child(2n) {
margin-right: 0;
}
&:nth-child(3), &:nth-child(4) {
margin-bottom: 0;
}
&.football-photo {
background-color: #f5f5f5;
}
}
}
}
</style>

View File

@ -8,20 +8,38 @@
<view class="switch-btn" v-if="xkList.length > 1">切换</view> <view class="switch-btn" v-if="xkList.length > 1">切换</view>
</view> </view>
<!-- 俱乐部选择弹窗 --> <!-- 俱乐部选择弹窗 -->
<u-popup :show="showFlag" @close="showFlag = false" mode="bottom" round="10"> <u-popup
:show="showFlag"
@close="showFlag = false"
mode="bottom"
round="10"
>
<view class="xk-picker"> <view class="xk-picker">
<view class="xk-header"> <view class="xk-header">
<text class="xk-title">选择俱乐部</text> <text class="xk-title">选择俱乐部</text>
<u-icon name="close" size="20" @click="showFlag = false"></u-icon> <u-icon name="close" size="20" @click="showFlag = false"></u-icon>
</view> </view>
<view class="xk-list"> <view class="xk-list">
<view v-for="(xk, index) in xkList" :key="index" class="xk-item" :class="{ <view
'xk-item-active': curXk.id === xk.id v-for="(xk, index) in xkList"
}" @click="switchXk(xk)"> :key="index"
class="xk-item"
:class="{
'xk-item-active': curXk.id === xk.id,
'xk-item-selected': xk.selected,
}"
@click="switchXk(xk)"
>
<view class="xk-info"> <view class="xk-info">
<text class="xk-name">{{ xk.xkmc }}</text> <text class="xk-name">{{ xk.xkmc }}</text>
<text v-if="xk.selected" class="xk-selected-tip">已选择</text>
</view> </view>
<u-icon v-if="curXk.id === xk.id" name="checkmark" color="#409EFF" size="20"></u-icon> <u-icon
v-if="curXk.id === xk.id"
name="checkmark"
color="#409EFF"
size="20"
></u-icon>
</view> </view>
</view> </view>
</view> </view>
@ -40,14 +58,14 @@ const { setData } = useDataStore();
// //
const props = defineProps<{ const props = defineProps<{
isQk: boolean, // isQk: boolean; //
xsId: string, xsId: string;
xklxId: string, // Id962488654 / 816059832 xklxId: string; // Id962488654 / 816059832
title: string, title: string;
}>(); }>();
// emit // emit
const emit = defineEmits(['change']) const emit = defineEmits(["change"]);
// //
const xkList = ref<any>([]); const xkList = ref<any>([]);
@ -58,7 +76,14 @@ const showFlag = ref(false);
// //
const showPicker = () => { const showPicker = () => {
showFlag.value = true; showFlag.value = true;
} };
const goToWks = () => {
setData({ title: props.title });
uni.reLaunch({
url: "/pages/base/xk/qk/wks",
});
};
// //
const loadXkList = async () => { const loadXkList = async () => {
@ -68,7 +93,7 @@ const loadXkList = async () => {
const params = { const params = {
xsId: props.xsId, xsId: props.xsId,
njmcId: getCurXs.njmcId, njmcId: getCurXs.njmcId,
xklxId: props.xklxId xklxId: props.xklxId,
}; };
if (!props.isQk) { if (!props.isQk) {
const res = await xsYxListApi(params); const res = await xsYxListApi(params);
@ -85,46 +110,41 @@ const loadXkList = async () => {
uni.hideLoading(); uni.hideLoading();
if (res.resultCode === 1) { if (res.resultCode === 1) {
const result = res.result || {}; const result = res.result || {};
if (result.type && result.type === 1) { if (result.type === 1) {
//
setData(result);
uni.reLaunch({
url: "/pages/base/xk/pay/index",
});
return;
} else if (result.type === 2 || result.type === 3) {
//
if (result.xkList && result.xkList.length) { if (result.xkList && result.xkList.length) {
xkList.value = result.xkList; xkList.value = result.xkList;
switchXk(result.xkList[0]); switchXk(result.xkList[0]);
} else { return;
uni.reLaunch({
url: "/pages/base/course-selection/notopen",
});
} }
} else if (result.type && result.type === 2) {
//
setData(result);
uni.reLaunch({
url: "/pages/base/course-selection/payment",
});
} else {
uni.reLaunch({
url: "/pages/base/course-selection/notopen",
});
} }
} else {
uni.reLaunch({
url: "/pages/base/course-selection/notopen",
});
} }
goToWks();
} }
} };
// //
const switchXk = (xk: any) => { const switchXk = (xk: any) => {
curXk.value = xk; curXk.value = xk;
showFlag.value = false; showFlag.value = false;
emit("change", xk); emit("change", xk);
} };
// //
watch(() => props.xsId, (newVal) => { watch(
console.log("当前学生信息变更", newVal); () => props.xsId,
loadXkList(); (newVal) => {
}); console.log("当前学生信息变更", newVal);
loadXkList();
}
);
// //
if (props.xsId) { if (props.xsId) {
@ -203,6 +223,11 @@ if (props.xsId) {
background-color: rgba(64, 158, 255, 0.05); background-color: rgba(64, 158, 255, 0.05);
} }
&-selected {
background-color: rgba(64, 158, 255, 0.1);
border-left: 3px solid #409eff;
}
.xk-info { .xk-info {
flex: 1; flex: 1;
margin-left: 12px; margin-left: 12px;
@ -212,11 +237,18 @@ if (props.xsId) {
font-weight: 500; font-weight: 500;
color: #303133; color: #303133;
margin-bottom: 4px; margin-bottom: 4px;
display: block;
}
.xk-selected-tip {
font-size: 12px;
color: #409eff;
background-color: rgba(64, 158, 255, 0.1);
padding: 2px 6px;
border-radius: 4px;
} }
} }
} }
} }
} }
</style> </style>

View File

@ -111,7 +111,7 @@ const toggleSelection = (xkkc: any) => {
const goToDetail = (xkkc: any) => { const goToDetail = (xkkc: any) => {
setKcData(xkkc); setKcData(xkkc);
uni.navigateTo({ uni.navigateTo({
url: `/pages/base/course-selection/detail`, url: `/pages/base/xk/detail`,
}); });
}; };
@ -120,11 +120,15 @@ const switchXk = (xk: any) => {
if (!props.canSelected) { if (!props.canSelected) {
return; return;
} }
// ID // ID
let selectedXkkcIds = uni.getStorageSync("selectedXkkcIds") || []; let selectedXkkcIds = uni.getStorageSync("selectedXkkcIds") || [];
let newSelectedXkkcIds = []; let newSelectedXkkcIds: string[] = [];
for (let i = 0; i < xkkcList.value.length; i++) { for (let i = 0; i < xkkcList.value.length; i++) {
const xkkc = xkkcList.value[i]; const xkkc = xkkcList.value[i];
//
if (selectedXkkcIds.includes(xkkc.id)) { if (selectedXkkcIds.includes(xkkc.id)) {
xkkc.isSelected = true; xkkc.isSelected = true;
newSelectedXkkcIds.push(xkkc.id); newSelectedXkkcIds.push(xkkc.id);
@ -132,6 +136,7 @@ const switchXk = (xk: any) => {
xkkc.isSelected = false; xkkc.isSelected = false;
} }
} }
uni.setStorageSync("selectedXkkcIds", newSelectedXkkcIds); uni.setStorageSync("selectedXkkcIds", newSelectedXkkcIds);
emit("change", newSelectedXkkcIds); emit("change", newSelectedXkkcIds);
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,584 +0,0 @@
<template>
<BasicLayout>
<view class="enrolled-page">
<!-- 已报名状态提示 -->
<view class="status-card">
<view class="status-icon">
<u-icon name="checkmark" size="32" color="#3FBF72"></u-icon>
</view>
<view class="status-text">已报名</view>
<view class="status-desc">该学生已成功报名以下兴趣课程</view>
</view>
<!-- 学生信息卡片 -->
<view class="info-card student-card">
<view class="card-title">学生信息</view>
<view class="divider"></view>
<view class="student-info">
<view class="student-avatar">
<image
:src="studentInfo.xstxUrl || '/static/base/home/11222.png'"
mode="aspectFill"
></image>
</view>
<view class="student-details">
<view class="student-name">{{ studentInfo.xm }}</view>
<view class="student-class"
>{{ studentInfo.njmc }} {{ studentInfo.bjmc }}</view
>
</view>
</view>
</view>
<!-- 已报名课程列表 -->
<view class="info-card">
<view class="card-title"
>已报名课程 ({{ enrolledCourse.length }})</view
>
<view class="divider"></view>
<!-- 课程列表 -->
<view class="course-list">
<view
v-for="(item, index) in enrolledCourse"
:key="item.id"
class="course-item"
:class="{ 'last-item': index === enrolledCourse.length - 1 }"
>
<view class="course-header">
<view class="course-name">{{ item.title }}</view>
<view class="course-fee">¥{{ item.fee }}</view>
</view>
<view class="course-details">
<view class="detail-row">
<view class="detail-item">
<u-icon name="account" size="14" color="#666"></u-icon>
<text>{{ item.teacher }}</text>
</view>
<view class="detail-item">
<u-icon name="clock" size="14" color="#666"></u-icon>
<text>{{ item.time }}</text>
</view>
</view>
<view class="detail-row">
<view class="detail-item">
<u-icon name="map" size="14" color="#666"></u-icon>
<text>{{ item.location }}</text>
</view>
<view class="detail-item">
<u-icon name="calendar" size="14" color="#666"></u-icon>
<text>{{ formatDate(item.enrollDate) }}</text>
</view>
</view>
</view>
<view class="course-actions" v-if="!isAllPaid">
<u-button
text="取消报名"
size="mini"
:plain="true"
@click="cancelRegistration(item.id)"
></u-button>
</view>
</view>
</view>
</view>
<!-- 支付状态卡片 -->
<view
class="payment-status-card"
:class="{ paid: isAllPaid, unpaid: !isAllPaid }"
>
<view class="status-header">
<view class="status-icon">
<u-icon
:name="isAllPaid ? 'checkmark-circle' : 'clock'"
size="24"
:color="isAllPaid ? '#3FBF72' : '#FF9900'"
></u-icon>
</view>
<view class="status-text">
<text class="status-title">{{
isAllPaid ? "支付完成" : "待支付"
}}</text>
<text class="status-desc">{{
isAllPaid ? "所有课程费用已支付" : "请完成课程费用支付"
}}</text>
</view>
</view>
<view class="payment-details">
<view class="detail-item">
<text class="detail-label">课程总数</text>
<text class="detail-value">{{ enrolledCourse.length }}</text>
</view>
<view class="detail-item">
<text class="detail-label">总费用</text>
<text class="detail-value amount">¥{{ totalAmount }}</text>
</view>
<view class="detail-item" v-if="!isAllPaid">
<text class="detail-label">待支付</text>
<text class="detail-value unpaid-amount">¥{{ totalAmount }}</text>
</view>
</view>
</view>
</view>
<template #bottom>
<view class="bottom-actions" v-if="!isAllPaid">
<view class="payment-info">
<text class="payment-label">待支付</text>
<text class="payment-amount">¥{{ totalAmount }}</text>
</view>
<view class="payment-button">
<u-button text="立即支付" type="primary" @click="goPay"></u-button>
</view>
</view>
</template>
</BasicLayout>
</template>
<script setup lang="ts">
import { ref, onMounted, computed } from "vue";
import { useUserStore } from "@/store/modules/user";
import { useDataStore } from "@/store/modules/data";
import { xkqddeleteApi } from "@/api/base/server";
import { map } from "lodash";
import dayjs from "dayjs";
const { getUser } = useUserStore();
//
onMounted(() => {});
const useData = useDataStore();
const { getData } = storeToRefs(useData);
//
const studentInfo = ref({
id: getData.value.studentInfo.id,
xm: getData.value.studentInfo.xm,
njmc: getData.value.studentInfo.njmc,
bjmc: getData.value.studentInfo.bjmc,
xstxUrl: getData.value.studentInfo.xstxUrl,
});
//
const enrolledCourse = ref();
enrolledCourse.value = map(getData.value.enrolledCourse, (item) => {
return {
id: item.id,
title: item.xkmc,
image: item.image,
teacher: item.jsxm,
time: item.studyTime,
location: item.kcdd,
enrollDate: item.createdTime,
fee: item.jfje || 0,
};
});
//
const isAllPaid = ref(enrolledCourse.value[0].jfzt == "B"); //
//
const totalAmount = computed(() => {
return enrolledCourse.value.reduce(
(sum: number, course: any) => sum + course.fee,
0
);
});
//
const formatDate = (dateStr: string) => {
if (!dateStr) return "未知";
return dayjs(dateStr).format("YYYY-MM-DD HH:mm");
};
//
const goPay = () => {};
const cancelRegistration = async (id: string) => {
uni.showModal({
title: "确认取消",
content: "确定要取消该课程的报名吗?",
success: async (res) => {
if (res.confirm) {
uni.showLoading({ title: "处理中..." });
try {
await xkqddeleteApi({
ids: id,
});
uni.hideLoading();
uni.showToast({
title: "取消成功",
icon: "success",
});
setTimeout(() => {
uni.reLaunch({
url: `/pages/base/course-selection/index`,
});
}, 1500);
} catch (error) {
uni.hideLoading();
uni.showToast({
title: "取消失败",
icon: "error",
});
}
}
},
});
};
onMounted(() => {
});
</script>
<style lang="scss" scoped>
.enrolled-page {
background-color: #f5f7fa;
padding: 15px;
padding-bottom: 80px; /* 为底部固定按钮留出空间 */
}
.status-card {
background: linear-gradient(135deg, #3fbf72, #2ab559);
border-radius: 12px;
padding: 20px;
margin-bottom: 15px;
color: #fff;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
.status-icon {
width: 60px;
height: 60px;
background-color: #fff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 12px;
}
.status-text {
font-size: 22px;
font-weight: bold;
margin-bottom: 8px;
}
.status-desc {
font-size: 14px;
opacity: 0.8;
}
}
.info-card {
background-color: #fff;
border-radius: 12px;
padding: 15px;
margin-bottom: 15px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
&.student-card {
background-color: #eef4ff;
}
.card-title {
font-size: 16px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
}
.divider {
height: 1px;
background-color: #eee;
margin-bottom: 15px;
}
}
.student-info {
display: flex;
align-items: center;
.student-avatar {
width: 60px;
height: 60px;
border-radius: 50%;
overflow: hidden;
margin-right: 15px;
image {
width: 100%;
height: 100%;
}
}
.student-details {
.student-name {
font-size: 18px;
font-weight: 500;
color: #333;
margin-bottom: 5px;
}
.student-class {
font-size: 14px;
color: #666;
}
}
}
.course-list {
.course-item {
border-bottom: 1px solid #f0f0f0;
&.last-item {
border-bottom: none;
}
.course-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
.course-name {
font-size: 16px;
font-weight: 500;
color: #333;
}
.course-fee {
font-size: 16px;
font-weight: 500;
color: #ff6b01;
}
}
.course-details {
margin-bottom: 12px;
.detail-row {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}
.detail-item {
display: flex;
align-items: center;
flex: 1;
text {
margin-left: 5px;
font-size: 13px;
color: #666;
}
}
}
}
.course-actions {
display: flex;
justify-content: flex-end;
align-items: center;
:deep(.u-button) {
margin-left: 10px;
}
}
}
}
.payment-status-card {
background-color: #fff;
border-radius: 12px;
padding: 15px;
margin-bottom: 15px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
border-left: 4px solid #ddd;
&.paid {
border-left-color: #3fbf72;
background: linear-gradient(135deg, #f0f9ff, #e6f7ff);
}
&.unpaid {
border-left-color: #ff9900;
background: linear-gradient(135deg, #fff9f0, #fff2e6);
}
.status-header {
display: flex;
align-items: center;
margin-bottom: 15px;
.status-icon {
width: 24px;
height: 24px;
margin-right: 12px;
display: flex;
align-items: center;
justify-content: center;
}
.status-text {
flex: 1;
.status-title {
font-size: 16px;
font-weight: bold;
color: #333;
display: block;
margin-bottom: 4px;
}
.status-desc {
font-size: 13px;
color: #666;
display: block;
}
}
}
.payment-details {
.detail-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}
.detail-label {
font-size: 14px;
color: #666;
}
.detail-value {
font-size: 14px;
color: #333;
&.amount {
font-weight: bold;
color: #333;
}
&.unpaid-amount {
color: #ff5252;
font-weight: bold;
}
}
}
}
}
.notice-card {
background-color: #fff9e6;
border-radius: 12px;
padding: 15px;
.notice-title {
display: flex;
align-items: center;
margin-bottom: 10px;
text {
margin-left: 5px;
font-size: 16px;
font-weight: 500;
color: #333;
}
}
.notice-content {
font-size: 14px;
color: #666;
text {
display: block;
margin-bottom: 5px;
&:last-child {
margin-bottom: 0;
}
}
}
}
.bottom-actions {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 12px 20px;
background-color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
border-top: 1px solid #f0f0f0;
z-index: 100;
safe-area-inset-bottom: env(safe-area-inset-bottom);
.payment-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
.payment-label {
font-size: 12px;
color: #999;
margin-bottom: 2px;
line-height: 1;
}
.payment-amount {
font-size: 18px;
font-weight: bold;
color: #ff6b01;
line-height: 1.2;
}
}
.payment-button {
flex: 0 0 auto;
margin-left: 15px;
}
:deep(.u-button) {
width: 120px !important;
height: 40px !important;
border-radius: 20px !important;
font-size: 15px !important;
font-weight: 500 !important;
.u-button__text {
font-size: 15px !important;
font-weight: 500 !important;
}
&.u-button--primary {
background-color: #2879ff !important;
border-color: #2879ff !important;
}
}
}
</style>

View File

@ -1,284 +0,0 @@
<template>
<view class="interest-course">
<!-- 选课信息头部 - 固定部分 -->
<view class="selection-header">
<view class="header-content">
<!-- 选课类型选择部分 -->
<XkPicker title="俱乐部信息" :is-qk="true" xklx-id="962488654" :xs-id="curXs.id" @change="switchXk" v-if="!xsFlag" />
<!-- 学生选择和倒计时 -->
<view class="bottom-row">
<XsPicker :is-bar="true" @change="switchXs" />
<XkCountdown :xk="curXk" @over="xkTimeOver" v-if="curXk && curXk.id" />
</view>
</view>
</view>
<!-- 可滚动的内容区域 -->
<view class="scrollable-content">
<XkkcList :xk="curXk" :can-selected="true" @change="changeXkkc" v-if="!xsFlag" />
</view>
<!-- 底部报名按钮 - 固定部分 -->
<view class="register-btn-container">
<view class="selected-count-info" v-if="selectedXkkcIds && selectedXkkcIds.length > 0">
已选 {{ selectedXkkcIds.length }} 门课程
</view>
<view class="register-btn" @click="submit">点击报名</view>
</view>
</view>
</template>
<script setup lang="ts">
import XsPicker from "@/pages/base/components/XsPicker/index.vue"
import XkPicker from "@/pages/base/components/XkPicker/index.vue"
import XkCountdown from "@/pages/base/components/XkCountdown/index.vue"
import XkkcList from "@/pages/base/components/XkkcList/index.vue"
import { jzXkQkjApi } from "@/api/base/server";
import { useUserStore } from "@/store/modules/user";
import { useDataStore } from "@/store/modules/data";
import dayjs from "dayjs";
const { getCurXs, getUser } = useUserStore();
const { setData, getData } = useDataStore();
const { sign_file } = getData;
const user = computed(() => getUser);
const curXs = computed(() => getCurXs);
const curXk = ref<any>({});
const selectedXkkcIds = ref<any>([]);
const xsFlag = ref(true);
//
const checkEnrollmentStatus = (xk: any) => {
if (!xk || !xk.xkjstime) return;
const now = new Date().getTime();
const endTime = new Date(xk.xkjstime).getTime();
if (now > endTime) {
//
const courseInfo = encodeURIComponent(JSON.stringify(xk));
uni.navigateTo({
url: `/pages/base/course-selection/enrollment-ended?courseInfo=${courseInfo}`
});
return true;
}
return false;
};
//
const switchXk = (xk: any) => {
curXk.value = xk;
//
if (checkEnrollmentStatus(xk)) {
return;
}
}
//
const switchXs = (xs: any) => {
xsFlag.value = false;
}
//
const xkTimeOver = (val: any) => {
console.log('选课时间结束:', val);
//
const courseInfo = encodeURIComponent(JSON.stringify(curXk.value));
uni.navigateTo({
url: `/pages/base/course-selection/enrollment-ended?courseInfo=${courseInfo}`
});
}
//
const changeXkkc = (ids: any) => {
selectedXkkcIds.value = ids;
}
//
const submit = async () => {
//
if (selectedXkkcIds.value.length === 0) {
uni.showToast({
title: "请选择课程!",
icon: "none",
});
return;
}
//
if (curXk.value && curXk.value.xkkstime) {
const now = dayjs().valueOf();
const startTime = dayjs(curXk.value.xkkstime).valueOf();
if (now < startTime) {
uni.showToast({
title: "选课还未开始,请耐心等待!",
icon: "none",
});
return;
}
}
uni.showLoading({
title: "抢课中...",
});
const params = {
xsId: curXs.value.id,
xm: curXs.value.xm,
njmc: curXs.value.njmc,
njmcId: curXs.value.njmcId,
njId: curXs.value.njId,
bc: (curXs.value.njbc || '') + (curXs.value.bjmc || ''),
xkId: curXk.value.id,
xkkcIds: selectedXkkcIds.value,
jzId: getUser.jzId,
qmFile: sign_file ? sign_file.value : "",
};
const res = await jzXkQkjApi(params);
uni.hideLoading();
if (res.resultCode === 1) {
selectedXkkcIds.value = [];
uni.setStorageSync("selectedXkkcIds", []);
res.result.backUrl = "/pages/base/course-selection/index";
setData(res.result);
setTimeout(() => {
xsFlag.value = false;
}, 1000);
if (curXk.value.sfjf === 1) {
//
uni.navigateTo({
url: "/pages/base/course-selection/payment",
});
} else {
//
uni.navigateTo({
url: "/pages/base/course-selection/payment-success",
});
}
} else {
uni.showToast({
title: res.message,
icon: "none",
});
}
}
</script>
<style lang="scss" scoped>
.interest-course {
min-height: 100%;
background-color: #f5f7fa;
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
.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: linear-gradient(135deg, #4a90e2, #2879ff);
padding: 20px 15px;
color: #fff;
border-radius: 0 0 15px 15px;
box-shadow: 0 4px 12px rgba(40, 121, 255, 0.2);
position: sticky;
top: 0;
left: 0;
right: 0;
z-index: 10;
.header-content {
display: flex;
flex-direction: column;
gap: 15px;
.bottom-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 15px;
//
:deep(.xs-bar) {
flex: 1;
min-width: 0;
}
//
:deep(.countdown-section) {
flex-shrink: 0;
background: rgba(255, 255, 255, 0.1);
border-radius: 6px;
padding: 6px 10px;
backdrop-filter: blur(10px);
}
}
}
}
//
.scrollable-content {
flex: 1;
overflow-y: auto;
-webkit-overflow-scrolling: touch; // iOS
}
.register-btn-container {
position: sticky;
bottom: 0;
left: 0;
right: 0;
padding: 15px;
background-color: #fff;
z-index: 1;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
.selected-count-info {
font-size: 14px;
color: #666;
margin-bottom: 8px;
}
.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>

63
src/pages/base/gzs/jc.vue Normal file
View File

@ -0,0 +1,63 @@
<template>
<BasicLayout>
<view class="p-15">
<view class="white-bg-color p-15 r-md" v-if="notice">
<view> 各位家长</view>
<view class="notice-text">
{{ notice }}
</view>
</view>
<BasicSign ref="signCompRef" title="签名"></BasicSign>
</view>
<template #bottom>
<view class="white-bg-color py-5">
<view class="flex-row items-center pb-10 pt-5">
<u-button
text="下一步"
class="mx-15"
type="primary"
@click="submit"
/>
</view>
</view>
</template>
</BasicLayout>
</template>
<script lang="ts" setup>
import { xkgzsApi } from "@/api/base/server";
import { useDataStore } from "@/store/modules/data";
import { showLoading } from "@/utils/uniapp";
import { onLoad } from "@dcloudio/uni-app";
const signCompRef = ref<any>(null);
const sign_file = ref<any>(null);
const { setData, getGlobal } = useDataStore();
const notice = ref("");
onLoad(async () => {
showLoading({ title: "加载中..." });
const res = await xkgzsApi({ kcLx: "就餐" });
notice.value = res.rows?.[0]?.content || "";
uni.hideLoading();
});
async function submit() {
//
const data = await signCompRef.value.getSyncSignature();
sign_file.value = data.base64;
setData({
sign_file: sign_file.value,
});
uni.reLaunch({
url: "/pages/base/xk/qk/jlb",
});
}
</script>
<style lang="scss" scoped>
.notice-text {
margin-top: 10px;
text-indent: 2em; /* 添加两个中文字符的缩进 */
}
</style>

View File

@ -50,16 +50,16 @@ async function submit() {
sign_file: sign_file.value, sign_file: sign_file.value,
}); });
uni.reLaunch({ uni.reLaunch({
url: "/pages/base/course-selection/club-selection", url: "/pages/base/xk/qk/jlb",
}); });
/*if (getGlobal.type == 1) { /*if (getGlobal.type == 1) {
uni.reLaunch({ uni.reLaunch({
url: "/pages/base/course-selection/index", url: "/pages/base/xk/qk/xqk",
}); });
} }
if (getGlobal.type == 2) { if (getGlobal.type == 2) {
uni.reLaunch({ uni.reLaunch({
url: "/pages/base/course-selection/club-selection", url: "/pages/base/xk/qk/jlb",
}); });
}*/ }*/
} }

View File

@ -80,7 +80,7 @@ async function submit() {
// //
uni.reLaunch({ uni.reLaunch({
url: "/pages/base/course-selection/index", url: "/pages/base/xk/qk/xqk",
}); });
} catch (error) { } catch (error) {

View File

@ -200,25 +200,25 @@ const menuItems = ref([
{ {
title: "兴趣课", title: "兴趣课",
icon: "/static/base/home/file-text-line.png", icon: "/static/base/home/file-text-line.png",
path: "/pages/base/interest-class/index", path: "/pages/base/xk/xqk",
permissionKey: "school-xqk", // permissionKey: "school-xqk", //
}, },
{ {
title: "俱乐部", title: "俱乐部",
icon: "/static/base/home/contacts-book-3-line.png", icon: "/static/base/home/contacts-book-3-line.png",
path: "/pages/base/club/index", path: "/pages/base/xk/jlb",
permissionKey: "school-jlb", // permissionKey: "school-jlb", //
}, },
{ {
title: "兴趣课选课", title: "兴趣课选课",
icon: "/static/base/home/file-text-line.png", icon: "/static/base/home/file-text-line.png",
path: "/pages/base/course-selection/notice", path: "/pages/base/gzs/xkXqk",
permissionKey: "school-xqkxk", // permissionKey: "school-xqkxk", //
}, },
{ {
title: "俱乐部选课", title: "俱乐部选课",
icon: "/static/base/home/contacts-book-3-line.png", icon: "/static/base/home/contacts-book-3-line.png",
path: "/pages/base/course-selection/noticeclub", path: "/pages/base/gzs/xkJlb",
permissionKey: "school-jlbxk", // permissionKey: "school-jlbxk", //
}, },
]); ]);

View File

@ -1,305 +0,0 @@
<template>
<view class="interest-class-page">
<view class="content-container">
<!-- 顶部蓝色背景横幅 -->
<view class="banner-section">
<view class="banner-placeholder">
<image src="/static/base/home/43221.png" mode="widthFix" class="w-full h-full"></image>
</view>
</view>
<!-- 我的课程 -->
<view class="my-course-section">
<view class="section-title">
<u-icon name="calendar" size="18" color="#1976d2"></u-icon>
<text class="title-text">我的课程</text>
</view>
<view class="course-card">
<view class="course-image-placeholder"></view>
<view class="course-info">
<text class="course-name">篮球</text>
<view class="course-detail">
<text class="detail-label">开课老师</text>
<text class="detail-value">叶老师</text>
</view>
<view class="course-detail">
<text class="detail-label">上课地点</text>
<text class="detail-value">教学楼3楼</text>
</view>
</view>
</view>
</view>
<!-- 教学计划 -->
<view class="teaching-plan-section">
<view class="section-title-bar">
<text class="title-text">教学计划</text>
</view>
<view class="plan-content">
<view class="plan-item">
<text class="plan-phase">第一阶段</text>
<text class="plan-desc"
>了解机器人的组成知道每个零件的名称及用途认识机器人的结构</text
>
</view>
<view class="plan-item">
<text class="plan-phase">第二阶段</text>
<text class="plan-desc"
>在老师的引导下分组搭建机器人注意引导幼儿理解机器人的数据线连接和遥控器方向的关系</text
>
</view>
<view class="plan-item">
<text class="plan-phase">第三阶段</text>
<text class="plan-desc"
>学会操控机器人的移动方向并练习把魔方根据要求推到指定位置</text
>
</view>
<view class="plan-item">
<text class="plan-phase">第四阶段</text>
<text class="plan-desc">组织幼儿参加创客机器人比赛</text>
</view>
</view>
</view>
<!-- 课堂随拍 -->
<view class="class-photos-section">
<view class="section-title-bar">
<text class="title-text">课堂随拍</text>
</view>
<view class="photos-grid">
<view class="photo-placeholder"></view>
<view class="photo-placeholder"></view>
<view class="photo-placeholder"></view>
<view class="photo-placeholder"></view>
</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { xkFindDqXsApi } from "@/api/base/server";
import { useUserStore } from "@/store/modules/user";
const { getCurXs } = useUserStore();
onMounted(async () => {
// Make onMounted async
xkFindDqXsApi({
xsId: getCurXs.id,
xklxId: '962488654'
}).then(res => {
// result
if (res && res.resultCode === 1) {
console.log(res)
} else {
//
console.warn("检查获取当前学期兴趣课接口返回错误:", res);
}
})
.catch((error) => {
//
console.error("调用获取当前学期兴趣课接口失败:", error);
});
});
</script>
<style lang="scss" scoped>
.interest-class-page {
background-color: #f8f8f8;
min-height: 100vh;
}
.content-container {
padding: 15px;
}
/* 顶部蓝色背景横幅 */
.banner-section {
margin-bottom: 15px;
.banner-placeholder {
height: 120px;
background-color: #3986ff;
border-radius: 10px;
display: flex;
justify-content: center;
align-items: center;
.banner-content {
text-align: center;
.banner-title {
font-size: 22px;
color: #ffffff;
font-weight: 500;
margin-bottom: 8px;
display: block;
}
.banner-school {
font-size: 14px;
color: rgba(255, 255, 255, 0.9);
}
}
}
}
/* 我的课程 */
.my-course-section {
margin-bottom: 15px;
.section-title {
display: flex;
align-items: center;
margin-bottom: 12px;
.title-text {
font-size: 16px;
font-weight: 500;
color: #303133;
margin-left: 6px;
}
}
.course-card {
background-color: #ffffff;
border-radius: 10px;
padding: 15px;
display: flex;
align-items: center;
.course-image-placeholder {
width: 120px;
height: 100px;
background-color: #f0f0f0;
border-radius: 6px;
margin-right: 15px;
flex-shrink: 0;
}
.course-info {
flex: 1;
.course-name {
font-size: 18px;
font-weight: 500;
color: #303133;
margin-bottom: 10px;
}
.course-detail {
display: flex;
margin-bottom: 6px;
&:last-child {
margin-bottom: 0;
}
.detail-label {
color: #606266;
font-size: 14px;
}
.detail-value {
color: #303133;
font-size: 14px;
}
}
}
}
}
/* 教学计划 */
.teaching-plan-section {
margin-bottom: 15px;
background-color: #ffffff;
border-radius: 10px;
overflow: hidden;
.section-title-bar {
padding: 12px 15px;
border-bottom: 1px solid #f2f2f2;
.title-text {
font-size: 16px;
font-weight: 500;
color: #303133;
}
}
.plan-content {
padding: 15px;
.plan-item {
margin-bottom: 15px;
&:last-child {
margin-bottom: 0;
}
}
.plan-phase {
font-size: 15px;
font-weight: 500;
color: #303133;
}
.plan-desc {
font-size: 14px;
color: #606266;
line-height: 1.5;
}
}
}
/* 课堂随拍 */
.class-photos-section {
background-color: #ffffff;
border-radius: 10px;
overflow: hidden;
.section-title-bar {
padding: 12px 15px;
border-bottom: 1px solid #f2f2f2;
.title-text {
font-size: 16px;
font-weight: 500;
color: #303133;
}
}
.photos-grid {
display: flex;
flex-wrap: wrap;
padding: 15px;
.photo-placeholder {
width: calc(50% - 8px);
height: 110px;
background-color: #f0f0f0;
border-radius: 6px;
margin-right: 8px;
margin-bottom: 8px;
&:nth-child(2n) {
margin-right: 0;
}
&:nth-child(3),
&:nth-child(4) {
margin-bottom: 0;
}
}
}
}
</style>

View File

@ -36,7 +36,7 @@ import { ref, onMounted } from 'vue';
// //
const reselect = () => { const reselect = () => {
uni.redirectTo({ uni.redirectTo({
url: '/pages/base/course-selection/index' url: '/pages/base/xk/qk/xqk'
}); });
}; };

View File

@ -136,7 +136,7 @@ const payNow = async () => {
...res.result ...res.result
}); });
uni.redirectTo({ uni.redirectTo({
url: `/pages/base/course-selection/pay-wait?payUrl=${encodeURIComponent(res.result.cashierPayHtml)}` url: `/pages/base/xk/pay/wait?payUrl=${encodeURIComponent(res.result.cashierPayHtml)}`
}); });
} }
} catch (error) { } catch (error) {
@ -147,7 +147,7 @@ const payNow = async () => {
}); });
// const url = "https://www.baidu.com"; // const url = "https://www.baidu.com";
// uni.redirectTo({ // uni.redirectTo({
// url: `/pages/base/course-selection/pay-wait?payUrl=${encodeURIComponent(url)}` // url: `/pages/base/xk/pay/wait?payUrl=${encodeURIComponent(url)}`
// }); // });
} }
}; };

View File

@ -135,7 +135,7 @@ setWsCallback((type: string, res: any) => {
// //
setTimeout(() => { setTimeout(() => {
uni.reLaunch({ uni.reLaunch({
url: "/pages/base/course-selection/payment-success", url: "/pages/base/xk/pay/success",
}); });
}, 1000) }, 1000)
} }
@ -226,11 +226,11 @@ onLoad(async (options: any) => {
// if ("0000000000" === respCode) { // if ("0000000000" === respCode) {
// if ("02" === orderStat) { // if ("02" === orderStat) {
// uni.reLaunch({ // uni.reLaunch({
// url: "/pages/base/course-selection/payment-success", // url: "/pages/base/xk/pay/success",
// }); // });
// } else if ("03" === orderStat) { // } else if ("03" === orderStat) {
// uni.reLaunch({ // uni.reLaunch({
// url: "/pages/base/course-selection/payment-fail", // url: "/pages/base/xk/pay/fail",
// }); // });
// } // }
// } else { // } else {

View File

@ -17,11 +17,19 @@
<!-- 可滚动的内容区域 --> <!-- 可滚动的内容区域 -->
<view class="scrollable-content"> <view class="scrollable-content">
<XkkcList :xk="curXk" :can-selected="true" :multiple="true" @change="changeXkkc" v-if="!xsFlag" /> <!-- 如果当前选课已被选择显示提示信息 -->
<view v-if="curXk && curXk.selected" class="selected-notice">
<view class="notice-content">
<u-icon name="info-circle" color="#409EFF" size="24"></u-icon>
<text class="notice-text">{{ curXk.message || '您已经选择了该选课下的课程,如果需要重新选课,请联系教师进行处理' }}</text>
</view>
</view>
<!-- 如果当前选课未被选择显示课程列表 -->
<XkkcList v-else :xk="curXk" :can-selected="true" :multiple="true" @change="changeXkkc" />
</view> </view>
<!-- 底部报名按钮 - 固定部分 --> <!-- 底部报名按钮 - 固定部分 -->
<view class="register-btn-container"> <view class="register-btn-container" v-if="curXk && !curXk.selected">
<view class="selected-count-info" v-if="selectedXkkcIds && selectedXkkcIds.length > 0"> <view class="selected-count-info" v-if="selectedXkkcIds && selectedXkkcIds.length > 0">
已选 {{ selectedXkkcIds.length }} 门课程 已选 {{ selectedXkkcIds.length }} 门课程
</view> </view>
@ -61,7 +69,7 @@ const checkEnrollmentStatus = (xk: any) => {
// //
const courseInfo = encodeURIComponent(JSON.stringify(xk)); const courseInfo = encodeURIComponent(JSON.stringify(xk));
uni.navigateTo({ uni.navigateTo({
url: `/pages/base/course-selection/enrollment-ended?courseInfo=${courseInfo}` url: `/pages/base/xk/qk/yjz?courseInfo=${courseInfo}`
}); });
return true; return true;
} }
@ -71,6 +79,10 @@ const checkEnrollmentStatus = (xk: any) => {
// //
const switchXk = (xk: any) => { const switchXk = (xk: any) => {
curXk.value = xk; curXk.value = xk;
//
selectedXkkcIds.value = [];
uni.setStorageSync("selectedXkkcIds", []);
// //
if (checkEnrollmentStatus(xk)) { if (checkEnrollmentStatus(xk)) {
return; return;
@ -104,6 +116,15 @@ const submit = async () => {
return; return;
} }
//
if (curXk.value && curXk.value.selected) {
uni.showToast({
title: "您已经选择了该选课下的课程,如需重新选课,请联系教师进行处理",
icon: "none",
});
return;
}
// //
if (curXk.value && curXk.value.xkkstime) { if (curXk.value && curXk.value.xkkstime) {
const now = dayjs().valueOf(); const now = dayjs().valueOf();
@ -138,7 +159,7 @@ const submit = async () => {
if (res.resultCode === 1) { if (res.resultCode === 1) {
selectedXkkcIds.value = []; selectedXkkcIds.value = [];
uni.setStorageSync("selectedXkkcIds", []); uni.setStorageSync("selectedXkkcIds", []);
res.result.backUrl = "/pages/base/course-selection/club-selection"; res.result.backUrl = "/pages/base/xk/qk/jlb";
setData(res.result); setData(res.result);
xsFlag.value = true; xsFlag.value = true;
setTimeout(() => { setTimeout(() => {
@ -147,12 +168,12 @@ const submit = async () => {
if (curXk.value.sfjf === 1) { if (curXk.value.sfjf === 1) {
// //
uni.navigateTo({ uni.navigateTo({
url: "/pages/base/course-selection/payment", url: "/pages/base/xk/pay/index",
}); });
} else { } else {
// //
uni.navigateTo({ uni.navigateTo({
url: "/pages/base/course-selection/payment-success", url: "/pages/base/xk/pay/success",
}); });
} }
} else { } else {
@ -260,6 +281,28 @@ const submit = async () => {
-webkit-overflow-scrolling: touch; // iOS -webkit-overflow-scrolling: touch; // iOS
} }
//
.selected-notice {
padding: 20px 15px;
.notice-content {
display: flex;
align-items: flex-start;
gap: 12px;
background: linear-gradient(135deg, #e3f2fd, #f3e5f5);
padding: 16px;
border-radius: 12px;
border-left: 4px solid #409EFF;
.notice-text {
flex: 1;
font-size: 14px;
line-height: 1.5;
color: #333;
}
}
}
.register-btn-container { .register-btn-container {
position: sticky; position: sticky;
bottom: 0; bottom: 0;

View File

@ -19,9 +19,9 @@
<text>温馨提示</text> <text>温馨提示</text>
</view> </view>
<view class="info-content"> <view class="info-content">
<text>1. 学校将按计划开放兴趣课程报名敬请关注学校通知</text> <text>1. 学校将按计划开放{{title}}课程报名敬请关注学校通知</text>
<text>2. 为保证公平课程报名将统一时间开放</text> <text>2. 为保证公平课程报名将统一时间开放</text>
<text>3. 开放报名后您可以为孩子选择合适的兴趣课程</text> <text>3. 开放报名后您可以为孩子选择合适的{{title}}课程</text>
<text>4. 如有疑问请联系班主任老师咨询详情</text> <text>4. 如有疑问请联系班主任老师咨询详情</text>
</view> </view>
</view> </view>
@ -48,6 +48,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from "vue"; import { ref, onMounted } from "vue";
import { useDataStore } from "@/store/modules/data";
const { getData } = useDataStore();
const title = computed(() => {
let t = getData.title || '';
return t.replace('信息', '');
});
// //
const goHome = () => { const goHome = () => {

View File

@ -112,7 +112,7 @@ const goBack = () => {
// //
const refreshPage = () => { const refreshPage = () => {
uni.reLaunch({ uni.reLaunch({
url: '/pages/base/course-selection/index' url: '/pages/base/xk/qk/xqk'
}); });
}; };
</script> </script>

107
src/pages/base/xk/xqk.vue Normal file
View File

@ -0,0 +1,107 @@
<template>
<view class="interest-course">
<!-- 选课信息头部 - 固定部分 -->
<view class="selection-header">
<view class="header-content">
<!-- 选课类型选择部分 -->
<XkPicker title="兴趣课信息" :is-qk="false" xklx-id="962488654" :xs-id="curXs.id" @change="switchXk" />
<!-- 学生选择部分 -->
<XsPicker :is-bar="true" />
</view>
</view>
<!-- 可滚动的内容区域 -->
<view class="scrollable-content">
<XkkcList :xk="curXk" />
</view>
</view>
</template>
<script setup lang="ts">
import XsPicker from "@/pages/base/components/XsPicker/index.vue"
import XkPicker from "@/pages/base/components/XkPicker/index.vue"
import XkkcList from "@/pages/base/components/XkkcList/index.vue"
import { useUserStore } from "@/store/modules/user";
const { getCurXs } = useUserStore();
const curXs = computed(() => getCurXs);
const curXk = ref<any>({});
//
const switchXk = (xk: any) => {
curXk.value = xk;
}
//
onBeforeUnmount(() => {
});
</script>
<style lang="scss" scoped>
.interest-course {
min-height: 100%;
background-color: #f5f7fa;
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
.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: linear-gradient(135deg, #4a90e2, #2879ff);
padding: 20px 15px;
color: #fff;
border-radius: 0 0 15px 15px;
box-shadow: 0 4px 12px rgba(40, 121, 255, 0.2);
position: sticky;
top: 0;
left: 0;
right: 0;
z-index: 10;
.header-content {
display: flex;
flex-direction: column;
gap: 15px;
}
}
//
.scrollable-content {
flex: 1;
overflow-y: auto;
-webkit-overflow-scrolling: touch; // iOS
}
</style>

View File

@ -12,20 +12,24 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import {onLoad} from "@dcloudio/uni-app"; import { onLoad } from "@dcloudio/uni-app";
import {useDataStore} from "@/store/modules/data"; import { useDataStore } from "@/store/modules/data";
import {useUserStore} from "@/store/modules/user"; import { useUserStore } from "@/store/modules/user";
import {checkOpenId} from "@/api/system/login"; import { checkOpenId } from "@/api/system/login";
import {refreshPermissionCache} from "@/utils/permission"; import { refreshPermissionCache } from "@/utils/permission";
const { setGlobal } = useDataStore(); const { setGlobal } = useDataStore();
const { afterLoginAction } = useUserStore(); const { afterLoginAction } = useUserStore();
const isShow = ref(true); const isShow = ref(true);
function toHome(data: any) { function toHome(data: any) {
if (data.type == 1 || data.type == 2) { if (data.type == 1) {
uni.reLaunch({ uni.reLaunch({
url: "/pages/base/course-selection/notice", url: "/pages/base/gzs/xkXqk",
});
} if (data.type == 2) {
uni.reLaunch({
url: "/pages/base/gzs/xkJlb",
}); });
} else { } else {
uni.reLaunch({ uni.reLaunch({

View File

@ -63,7 +63,7 @@
inputAlign="right" inputAlign="right"
></u--input> ></u--input>
</u-form-item> </u-form-item>
<!-- <u-form-item <!-- <u-form-item
label="与学生关系" label="与学生关系"
:prop="`students[${index}].jzxsgxId`" :prop="`students[${index}].jzxsgxId`"
required required
@ -98,8 +98,14 @@
<BasicForm @register="register"></BasicForm> <BasicForm @register="register"></BasicForm>
<BasicPicker ref="dicPickerRef" :range="dicOptions" title="请选择与学生关系" <BasicPicker
range-key="dictionaryCode" v-model="dicVal" @ok="dicChanged" /> ref="dicPickerRef"
:range="dicOptions"
title="请选择与学生关系"
range-key="dictionaryCode"
v-model="dicVal"
@ok="dicChanged"
/>
</view> </view>
<template #bottom> <template #bottom>
@ -123,8 +129,8 @@ import { dicApi } from "@/api/system/dic";
import { loginRegisterJzApi } from "@/api/base/server"; import { loginRegisterJzApi } from "@/api/base/server";
import { useUserStore } from "@/store/modules/user"; import { useUserStore } from "@/store/modules/user";
import { useDataStore } from "@/store/modules/data"; import { useDataStore } from "@/store/modules/data";
import {imagUrl} from "@/utils"; import { imagUrl } from "@/utils";
import {refreshPermissionCache} from "@/utils/permission"; import { refreshPermissionCache } from "@/utils/permission";
const dicOptions = ref<any>([[[]]]); const dicOptions = ref<any>([[[]]]);
const dicPickerRef = ref(); const dicPickerRef = ref();
@ -133,15 +139,15 @@ const dicVal = ref<number[]>([]);
let formSchema: FormsSchema[] = [ let formSchema: FormsSchema[] = [
{ title: "监护人信息" }, { title: "监护人信息" },
{ {
field: "jzxsgxId", field: "jzxsgxId",
label: "与学生关系", label: "与学生关系",
component: "BasicPicker", component: "BasicPicker",
componentProps: { componentProps: {
api: dicApi, api: dicApi,
param: { pid: 1622287061 }, param: { pid: 1622287061 },
rangeKey: "dictionaryValue", rangeKey: "dictionaryValue",
savaKey: "dictionaryCode", savaKey: "dictionaryCode",
}, },
}, },
{ {
field: "jzxm", field: "jzxm",
@ -187,8 +193,8 @@ const students = ref([
xsxm: "", xsxm: "",
xssfzh: "", xssfzh: "",
xstx: "", xstx: "",
jzxsgxId: "", jzxsgxId: "",
jzxsgxmc: "" jzxsgxmc: "",
}, },
]); ]);
@ -210,7 +216,7 @@ const dicChanged = (dicArr: any) => {
const dic = dicOptions.value[0][dicArr[0]]; const dic = dicOptions.value[0][dicArr[0]];
curXs.value.jzxsgxId = dic.dictionaryValue; curXs.value.jzxsgxId = dic.dictionaryValue;
curXs.value.jzxsgxmc = dic.dictionaryCode; curXs.value.jzxsgxmc = dic.dictionaryCode;
} };
async function afterRead(event: any, index: number) { async function afterRead(event: any, index: number) {
if (!event.tempFilePaths || event.tempFilePaths.length === 0) { if (!event.tempFilePaths || event.tempFilePaths.length === 0) {
@ -220,7 +226,9 @@ async function afterRead(event: any, index: number) {
const tempFilePath = event.tempFilePaths[0]; const tempFilePath = event.tempFilePaths[0];
showLoading({ title: "上传中" }); showLoading({ title: "上传中" });
try { try {
const res = await attachmentUpload(tempFilePath) as { result: Array<{ filePath: string }> }; const res = (await attachmentUpload(tempFilePath)) as {
result: Array<{ filePath: string }>;
};
const result = res.result; const result = res.result;
if (result && result.length > 0 && result[0].filePath) { if (result && result.length > 0 && result[0].filePath) {
students.value[index].xstx = result[0].filePath; students.value[index].xstx = result[0].filePath;
@ -245,8 +253,8 @@ function addMoreChildren() {
xsxm: "", xsxm: "",
xssfzh: "", xssfzh: "",
xstx: "", xstx: "",
jzxsgxId: "", jzxsgxId: "",
jzxsgxmc: "" jzxsgxmc: "",
}); });
} }
@ -261,11 +269,11 @@ function removeStudent(index: number) {
function toHome() { function toHome() {
if (getGlobal.type == 1) { if (getGlobal.type == 1) {
uni.reLaunch({ uni.reLaunch({
url: "/pages/base/course-selection/notice", url: "/pages/base/gzs/xkXqk",
}); });
} else if (getGlobal.type == 2) { } else if (getGlobal.type == 2) {
uni.reLaunch({ uni.reLaunch({
url: "/pages/base/course-selection/noticeclub", url: "/pages/base/gzs/xkJlb",
}); });
} else { } else {
uni.reLaunch({ uni.reLaunch({
@ -294,9 +302,9 @@ async function submit() {
const formData = await getValue(); const formData = await getValue();
showLoading({ title: "提交中" }); showLoading({ title: "提交中" });
try { try {
for (let i = 0; i < students.value.length; i++) { for (let i = 0; i < students.value.length; i++) {
students.value[i].jzxsgxId = formData.jzxsgxId; students.value[i].jzxsgxId = formData.jzxsgxId;
} }
const res = await loginRegisterJzApi({ const res = await loginRegisterJzApi({
xsList: students.value, xsList: students.value,
...formData, ...formData,
@ -332,8 +340,6 @@ onMounted(async () => {
// formSchema[1].componentProps.options = resDic.result; // formSchema[1].componentProps.options = resDic.result;
// setSchema(formSchema); // setSchema(formSchema);
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>