Browse Source

修改 bug

master
王泽彦 8 months ago
parent
commit
4cd74f7fc7
  1. 5
      uniapp/api/apiRoute.js
  2. 264
      uniapp/components/schedule/ScheduleDetail.vue
  3. 48
      uniapp/pages-coach/coach/schedule/adjust_course.vue

5
uniapp/api/apiRoute.js

@ -1277,6 +1277,11 @@ export default {
return await http.post('/student/attendance/cancel', data) return await http.post('/student/attendance/cancel', data)
}, },
// 将等待位学员转为正式课学员(保持接口兼容性)
async convertWaitingToFormal(data = {}) {
return await http.post('/course/convertWaitingToFormal', data)
},
//↓↓↓↓↓↓↓↓↓↓↓↓-----学员合同管理相关接口-----↓↓↓↓↓↓↓↓↓↓↓↓ //↓↓↓↓↓↓↓↓↓↓↓↓-----学员合同管理相关接口-----↓↓↓↓↓↓↓↓↓↓↓↓
// 获取学员合同列表 // 获取学员合同列表

264
uniapp/components/schedule/ScheduleDetail.vue

@ -110,10 +110,16 @@
<view class="section waiting-info" v-if="waitingStudents && waitingStudents.length > 0"> <view class="section waiting-info" v-if="waitingStudents && waitingStudents.length > 0">
<view class="section-header"> <view class="section-header">
<view class="section-title">等待位 ({{ waitingStudents.length }})</view> <view class="section-title">等待位 ({{ waitingStudents.length }})</view>
<view class="waiting-tip">
<text class="tip-text">点击卡片转为正式课学员</text>
</view>
</view> </view>
<view class="cards-grid"> <view class="cards-grid">
<view class="student-card filled waiting-filled" v-for="(student, index) in waitingStudents" :key="index" <view class="student-card filled waiting-filled" v-for="(student, index) in waitingStudents" :key="index"
@click="handleStudentClick(student, index)"> @click="handleStudentClick(student, index)">
<!-- 转换提示图标 -->
<view class="convert-icon"></view>
<!-- 续费提醒徽章 --> <!-- 续费提醒徽章 -->
<view v-if="student.needsRenewal && !student.isTrialStudent" class="renewal-badge">待续费</view> <view v-if="student.needsRenewal && !student.isTrialStudent" class="renewal-badge">待续费</view>
@ -200,6 +206,30 @@
</view> </view>
</view> </view>
</fui-modal> </fui-modal>
<!-- 升级确认弹窗 -->
<fui-modal :show="showUpgradeConfirm" title="升级确认" @cancel="cancelUpgrade" :buttons="[]" :zIndex="10000">
<view class="upgrade-confirm-modal" v-if="upgradeStudent">
<view class="confirm-content">
<view class="upgrade-icon"></view>
<view class="confirm-text">
是否将等待位学员 <text class="student-name-highlight">{{ upgradeStudent.name }}</text> 升级为正式学员
</view>
<view class="confirm-tip">
升级后将占用一个正式位
</view>
</view>
<view class="confirm-buttons">
<view class="confirm-btn cancel-btn" @click="cancelUpgrade">
<text>取消</text>
</view>
<view class="confirm-btn upgrade-btn" @click="confirmUpgrade">
<text>确定升级</text>
</view>
</view>
</view>
</fui-modal>
</fui-modal> </fui-modal>
</template> </template>
@ -222,11 +252,11 @@
// //
formalStudents() { formalStudents() {
if (!this.scheduleInfo || !this.scheduleInfo.students) return []; if (!this.scheduleInfo || !this.scheduleInfo.students) return [];
return this.scheduleInfo.students.filter(student => student.course_type !== 3); return this.scheduleInfo.students.filter(student => student.schedule_type === 1 || student.schedule_type === null);
}, },
waitingStudents() { waitingStudents() {
if (!this.scheduleInfo || !this.scheduleInfo.students) return []; if (!this.scheduleInfo || !this.scheduleInfo.students) return [];
return this.scheduleInfo.students.filter(student => student.course_type === 3); return this.scheduleInfo.students.filter(student => student.schedule_type === 2);
}, },
statusClass() { statusClass() {
const statusMap = { const statusMap = {
@ -271,7 +301,10 @@
scheduleInfo: null, scheduleInfo: null,
showAttendanceModal: false, showAttendanceModal: false,
selectedStudent: null, selectedStudent: null,
selectedStudentIndex: -1 selectedStudentIndex: -1,
showUpgradeConfirm: false,
upgradeStudent: null,
upgradeStudentIndex: -1
} }
}, },
watch: { watch: {
@ -400,9 +433,90 @@
// //
handleStudentClick(student, index) { handleStudentClick(student, index) {
console.log('点击了学员:', student)
//
if (student.schedule_type === 2) {
// -
this.handleWaitingStudentClick(student, index);
} else {
// - /
this.selectedStudent = student; this.selectedStudent = student;
this.selectedStudentIndex = index; this.selectedStudentIndex = index;
this.showAttendanceModal = true; this.showAttendanceModal = true;
}
},
//
handleWaitingStudentClick(student, index) {
this.upgradeStudent = student;
this.upgradeStudentIndex = index;
this.showUpgradeConfirm = true;
},
//
confirmUpgrade() {
this.showUpgradeConfirm = false;
if (this.upgradeStudent && this.upgradeStudentIndex >= 0) {
this.convertWaitingToFormal(this.upgradeStudent, this.upgradeStudentIndex);
}
},
//
cancelUpgrade() {
this.showUpgradeConfirm = false;
this.upgradeStudent = null;
this.upgradeStudentIndex = -1;
},
//
async convertWaitingToFormal(student, index) {
try {
uni.showLoading({
title: '升级中...'
});
// class_arrangement_detail
const upgradeData = {
resources_id: student.resources_id || student.resource_id,
schedule_id: this.scheduleId,
student_id: student.student_id || student.id,
from_schedule_type: 2, //
to_schedule_type: 1, //
position: this.formalStudents.length + 1, //
course_type: student.course_type === 3 ? 1 : student.course_type //
};
//
const response = await api.upgradeStudentSchedule(upgradeData);
if (response.code === 1) {
//
student.course_type = 1; //
student.courseStatus = '正式课';
student.courseType = 'temporary'; //
//
await this.fetchScheduleDetail();
uni.showToast({
title: '升级成功',
icon: 'success'
});
} else {
uni.showToast({
title: response.msg || '升级失败',
icon: 'none'
});
}
} catch (error) {
console.error('升级等待位学员失败:', error);
uni.showToast({
title: '升级失败,请重试',
icon: 'none'
});
} finally {
uni.hideLoading();
}
}, },
// //
@ -648,6 +762,21 @@
font-weight: 500; font-weight: 500;
} }
.waiting-tip {
display: flex;
align-items: center;
padding: 8rpx 16rpx;
background: rgba(139, 92, 246, 0.2);
border-radius: 6rpx;
border: 1px solid rgba(139, 92, 246, 0.3);
}
.tip-text {
font-size: 22rpx;
color: #8b5cf6;
font-weight: 500;
}
.info-item { .info-item {
display: flex; display: flex;
margin-bottom: 16rpx; margin-bottom: 16rpx;
@ -889,6 +1018,39 @@
.student-card.waiting-filled { .student-card.waiting-filled {
border-color: #8b5cf6; border-color: #8b5cf6;
background: #2a2a3a; background: #2a2a3a;
position: relative;
}
/* 转换提示图标 */
.convert-icon {
position: absolute;
top: 8rpx;
left: 8rpx;
width: 32rpx;
height: 32rpx;
background: linear-gradient(45deg, #8b5cf6, #a855f7);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 16rpx;
z-index: 5;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.1);
opacity: 0.8;
}
100% {
transform: scale(1);
opacity: 1;
}
} }
.student-card:active { .student-card:active {
@ -1023,4 +1185,100 @@
border-radius: 4rpx; border-radius: 4rpx;
transition: width 0.3s ease; transition: width 0.3s ease;
} }
/* 升级确认弹窗样式 */
.upgrade-confirm-modal {
padding: 40rpx 30rpx;
text-align: center;
}
.confirm-content {
margin-bottom: 40rpx;
}
.upgrade-icon {
font-size: 60rpx;
margin-bottom: 20rpx;
background: linear-gradient(45deg, #8b5cf6, #a855f7);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
animation: glow 2s ease-in-out infinite alternate;
}
@keyframes glow {
from {
filter: drop-shadow(0 0 5rpx #8b5cf6);
}
to {
filter: drop-shadow(0 0 15rpx #a855f7);
}
}
.confirm-text {
font-size: 32rpx;
color: #fff;
line-height: 1.5;
margin-bottom: 16rpx;
}
.student-name-highlight {
color: #8b5cf6;
font-weight: bold;
}
.confirm-tip {
font-size: 26rpx;
color: #999;
line-height: 1.4;
}
.confirm-buttons {
display: flex;
gap: 20rpx;
justify-content: center;
}
.confirm-btn {
flex: 1;
padding: 24rpx 32rpx;
border-radius: 12rpx;
cursor: pointer;
transition: all 0.3s ease;
text-align: center;
max-width: 200rpx;
}
.confirm-btn text {
font-size: 28rpx;
font-weight: 600;
}
.cancel-btn {
background: #4a4a4a;
border: 1px solid #666;
}
.cancel-btn text {
color: #ccc;
}
.cancel-btn:active {
background: #5a5a5a;
transform: scale(0.98);
}
.upgrade-btn {
background: linear-gradient(45deg, #8b5cf6, #a855f7);
border: 1px solid #8b5cf6;
}
.upgrade-btn text {
color: #fff;
}
.upgrade-btn:active {
background: linear-gradient(45deg, #7c3aed, #9333ea);
transform: scale(0.98);
}
</style> </style>

48
uniapp/pages-coach/coach/schedule/adjust_course.vue

@ -31,10 +31,29 @@
<text class="info-label">上课场地</text> <text class="info-label">上课场地</text>
<text class="info-value">{{ scheduleInfo.venue_name }}</text> <text class="info-value">{{ scheduleInfo.venue_name }}</text>
</view> </view>
<view class="info-row">
<text class="info-label">所属班级</text>
<text class="info-value">{{ scheduleInfo.class_info ? scheduleInfo.class_info.class_name : '未指定班级' }}</text>
</view>
</view> </view>
<view class="section-title">调整后信息</view> <view class="section-title">调整后信息</view>
<!-- 班级选择 -->
<fui-form-item label="所属班级">
<picker
:value="classPickerIndex"
:range="classOptions"
:range-key="'class_name'"
@change="onClassSelect"
>
<view class="selector-input">
<text>{{ selectedClass ? selectedClass.class_name : (scheduleInfo.class_info ? scheduleInfo.class_info.class_name : '请选择班级') }}</text>
<fui-icon name="arrowdown" :size="32" color="#CCCCCC"></fui-icon>
</view>
</picker>
</fui-form-item>
<!-- 教练选择 --> <!-- 教练选择 -->
<fui-form-item label="授课教练"> <fui-form-item label="授课教练">
<picker <picker
@ -135,6 +154,7 @@ export default {
// //
formData: { formData: {
schedule_id: '', schedule_id: '',
class_id: '',
coach_id: '', coach_id: '',
venue_id: '', venue_id: '',
course_date: '', course_date: '',
@ -145,15 +165,18 @@ export default {
// showDatePicker // showDatePicker
// //
classOptions: [],
coachOptions: [], coachOptions: [],
venueOptions: [], venueOptions: [],
timeSlotOptions: [], timeSlotOptions: [],
// //
selectedClass: null,
selectedCoach: null, selectedCoach: null,
selectedVenue: null, selectedVenue: null,
// picker // picker
classPickerIndex: 0,
coachPickerIndex: 0, coachPickerIndex: 0,
venuePickerIndex: 0, venuePickerIndex: 0,
timePickerIndex: 0 timePickerIndex: 0
@ -192,6 +215,7 @@ export default {
this.scheduleInfo = res.data; this.scheduleInfo = res.data;
// //
this.formData.class_id = this.scheduleInfo.class_id;
this.formData.coach_id = this.scheduleInfo.coach_id; this.formData.coach_id = this.scheduleInfo.coach_id;
this.formData.venue_id = this.scheduleInfo.venue_id; this.formData.venue_id = this.scheduleInfo.venue_id;
this.formData.course_date = this.scheduleInfo.course_date; this.formData.course_date = this.scheduleInfo.course_date;
@ -218,6 +242,9 @@ export default {
const res = await api.getCourseScheduleFilterOptions(); const res = await api.getCourseScheduleFilterOptions();
if (res.code === 1) { if (res.code === 1) {
//
this.classOptions = res.data.classes || [];
// //
this.coachOptions = res.data.coaches || []; this.coachOptions = res.data.coaches || [];
@ -227,7 +254,7 @@ export default {
// //
this.generateTimeSlotOptions(); this.generateTimeSlotOptions();
// //
this.findSelectedOptions(); this.findSelectedOptions();
} else { } else {
uni.showToast({ uni.showToast({
@ -248,6 +275,13 @@ export default {
// //
findSelectedOptions() { findSelectedOptions() {
//
if (this.scheduleInfo.class_id) {
this.selectedClass = this.classOptions.find(classItem => classItem.id === this.scheduleInfo.class_id);
this.classPickerIndex = this.classOptions.findIndex(classItem => classItem.id === this.scheduleInfo.class_id);
if (this.classPickerIndex === -1) this.classPickerIndex = 0;
}
// //
if (this.scheduleInfo.coach_id) { if (this.scheduleInfo.coach_id) {
this.selectedCoach = this.coachOptions.find(coach => coach.id === this.scheduleInfo.coach_id); this.selectedCoach = this.coachOptions.find(coach => coach.id === this.scheduleInfo.coach_id);
@ -276,6 +310,15 @@ export default {
}, },
// //
onClassSelect(e) {
const index = e.detail.value;
this.classPickerIndex = index;
if (index >= 0 && index < this.classOptions.length) {
this.selectedClass = this.classOptions[index];
this.formData.class_id = this.selectedClass.id;
}
},
onCoachSelect(e) { onCoachSelect(e) {
const index = e.detail.value; const index = e.detail.value;
this.coachPickerIndex = index; this.coachPickerIndex = index;
@ -317,7 +360,8 @@ export default {
// //
validateForm() { validateForm() {
// //
const hasChanges = this.formData.coach_id !== this.scheduleInfo.coach_id || const hasChanges = this.formData.class_id !== this.scheduleInfo.class_id ||
this.formData.coach_id !== this.scheduleInfo.coach_id ||
this.formData.venue_id !== this.scheduleInfo.venue_id || this.formData.venue_id !== this.scheduleInfo.venue_id ||
this.formData.course_date !== this.scheduleInfo.course_date || this.formData.course_date !== this.scheduleInfo.course_date ||
this.formData.time_slot !== this.scheduleInfo.time_slot || this.formData.time_slot !== this.scheduleInfo.time_slot ||

Loading…
Cancel
Save