You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
628 lines
18 KiB
628 lines
18 KiB
<template>
|
|
<view class="adjust-course-container">
|
|
<view class="form-container">
|
|
<view v-if="loading" class="loading-container">
|
|
<fui-loading></fui-loading>
|
|
<text class="loading-text">加载中...</text>
|
|
</view>
|
|
|
|
<fui-form v-else>
|
|
<!-- 课程信息 -->
|
|
<view class="section-title">当前课程信息</view>
|
|
<view class="course-info-card">
|
|
<view class="info-row">
|
|
<text class="info-label">课程名称:</text>
|
|
<text class="info-value">{{ scheduleInfo.course_name }}</text>
|
|
</view>
|
|
<view class="info-row">
|
|
<text class="info-label">上课日期:</text>
|
|
<text class="info-value">{{ scheduleInfo.course_date }}</text>
|
|
</view>
|
|
<view class="info-row">
|
|
<text class="info-label">上课时间:</text>
|
|
<text class="info-value">{{ scheduleInfo.time_slot }}</text>
|
|
</view>
|
|
<view class="info-row">
|
|
<text class="info-label">授课教练:</text>
|
|
<text class="info-value">主教练:{{ scheduleInfo.coach_name }}</text>
|
|
<text class="info-value">助教:{{ scheduleInfo.coach_name }}</text>
|
|
</view>
|
|
<view class="info-row">
|
|
<text class="info-label">上课场地:</text>
|
|
<text class="info-value">{{ scheduleInfo.venue_name }}</text>
|
|
</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 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="授课教练">
|
|
<picker
|
|
:value="coachPickerIndex"
|
|
:range="coachOptions"
|
|
:range-key="'name'"
|
|
@change="onCoachSelect"
|
|
>
|
|
<view class="selector-input">
|
|
<text>{{ selectedCoach ? selectedCoach.name : scheduleInfo.coach_name }}</text>
|
|
<fui-icon name="arrowdown" :size="32" color="#CCCCCC"></fui-icon>
|
|
</view>
|
|
</picker>
|
|
</fui-form-item>
|
|
|
|
<!-- 场地选择 -->
|
|
<fui-form-item label="上课场地">
|
|
<picker
|
|
:value="venuePickerIndex"
|
|
:range="venueOptions"
|
|
:range-key="'venue_name'"
|
|
@change="onVenueSelect"
|
|
>
|
|
<view class="selector-input">
|
|
<text>{{ selectedVenue ? selectedVenue.venue_name : scheduleInfo.venue_name }}</text>
|
|
<fui-icon name="arrowdown" :size="32" color="#CCCCCC"></fui-icon>
|
|
</view>
|
|
</picker>
|
|
</fui-form-item>
|
|
|
|
<!-- 日期选择 -->
|
|
<fui-form-item label="上课日期">
|
|
<picker
|
|
mode="date"
|
|
:value="formData.course_date || scheduleInfo.course_date || getCurrentDate()"
|
|
:start="getMinDate()"
|
|
:end="getMaxDate()"
|
|
@change="onDateSelect"
|
|
>
|
|
<view class="selector-input">
|
|
<text>{{ formData.course_date || scheduleInfo.course_date }}</text>
|
|
<fui-icon name="calendar" :size="32" color="#CCCCCC"></fui-icon>
|
|
</view>
|
|
</picker>
|
|
</fui-form-item>
|
|
|
|
<!-- 时间选择 -->
|
|
<fui-form-item label="上课时间">
|
|
<picker
|
|
:value="timePickerIndex"
|
|
:range="timeSlotOptions"
|
|
:range-key="'text'"
|
|
@change="onTimeSelect"
|
|
>
|
|
<view class="selector-input">
|
|
<text>{{ formData.time_slot || scheduleInfo.time_slot }}</text>
|
|
<fui-icon name="time" :size="32" color="#CCCCCC"></fui-icon>
|
|
</view>
|
|
</picker>
|
|
</fui-form-item>
|
|
|
|
<!-- 容量设置 -->
|
|
<fui-form-item label="课程容量">
|
|
<fui-input
|
|
type="number"
|
|
:value="formData.available_capacity || scheduleInfo.available_capacity"
|
|
placeholder="请输入课程容量"
|
|
@input="formData.available_capacity = $event"
|
|
></fui-input>
|
|
</fui-form-item>
|
|
|
|
|
|
<!-- 提交按钮 -->
|
|
<view class="btn-container">
|
|
<fui-button type="primary" @click="submitForm" :loading="submitting">确认调整</fui-button>
|
|
</view>
|
|
</fui-form>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import api from '@/api/apiRoute.js';
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
// 状态标记
|
|
loading: true,
|
|
submitting: false,
|
|
|
|
// 课程ID
|
|
scheduleId: null,
|
|
|
|
// 课程信息
|
|
scheduleInfo: {},
|
|
|
|
// 表单数据
|
|
formData: {
|
|
schedule_id: '',
|
|
class_id: '',
|
|
coach_id: '',
|
|
venue_id: '',
|
|
course_date: '',
|
|
time_slot: '',
|
|
available_capacity: ''
|
|
},
|
|
|
|
// 移除不再需要的showDatePicker
|
|
|
|
// 选项数据
|
|
classOptions: [],
|
|
coachOptions: [],
|
|
venueOptions: [],
|
|
timeSlotOptions: [],
|
|
|
|
// 选中的数据对象
|
|
selectedClass: null,
|
|
selectedCoach: null,
|
|
selectedVenue: null,
|
|
|
|
// picker索引
|
|
classPickerIndex: 0,
|
|
coachPickerIndex: 0,
|
|
venuePickerIndex: 0,
|
|
timePickerIndex: 0
|
|
};
|
|
},
|
|
|
|
onLoad(options) {
|
|
if (options.id) {
|
|
this.scheduleId = options.id;
|
|
this.formData.schedule_id = options.id;
|
|
this.loadScheduleInfo();
|
|
this.loadFilterOptions();
|
|
} else {
|
|
uni.showToast({
|
|
title: '参数错误',
|
|
icon: 'none'
|
|
});
|
|
setTimeout(() => {
|
|
uni.navigateBack();
|
|
}, 1500);
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
// 返回上一页
|
|
goBack() {
|
|
uni.navigateBack();
|
|
},
|
|
|
|
// 加载课程安排信息
|
|
async loadScheduleInfo() {
|
|
try {
|
|
const res = await api.getCourseScheduleInfo({ schedule_id: this.scheduleId });
|
|
|
|
if (res.code === 1) {
|
|
this.scheduleInfo = res.data;
|
|
|
|
// 初始化表单数据
|
|
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.course_date = this.scheduleInfo.course_date;
|
|
this.formData.time_slot = this.scheduleInfo.time_slot;
|
|
this.formData.available_capacity = this.scheduleInfo.available_capacity;
|
|
} else {
|
|
uni.showToast({
|
|
title: res.msg || '获取课程安排信息失败',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('获取课程安排信息失败:', error);
|
|
uni.showToast({
|
|
title: '获取课程安排信息失败',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
},
|
|
|
|
// 加载选项数据
|
|
async loadFilterOptions() {
|
|
try {
|
|
const res = await api.getCourseScheduleFilterOptions();
|
|
|
|
if (res.code === 1) {
|
|
// 设置班级选项
|
|
this.classOptions = res.data.classes || [];
|
|
|
|
// 设置教练选项
|
|
this.coachOptions = res.data.coaches || [];
|
|
|
|
// 设置场地选项
|
|
this.venueOptions = res.data.venues || [];
|
|
|
|
// 生成时间段选项
|
|
this.generateTimeSlotOptions();
|
|
|
|
// 找到当前选中的选项
|
|
this.findSelectedOptions();
|
|
} else {
|
|
uni.showToast({
|
|
title: res.msg || '加载筛选选项失败',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('加载筛选选项失败:', error);
|
|
uni.showToast({
|
|
title: '加载筛选选项失败',
|
|
icon: 'none'
|
|
});
|
|
} finally {
|
|
this.loading = false;
|
|
}
|
|
},
|
|
|
|
// 查找当前选中的选项
|
|
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) {
|
|
this.selectedCoach = this.coachOptions.find(coach => coach.id === this.scheduleInfo.coach_id);
|
|
this.coachPickerIndex = this.coachOptions.findIndex(coach => coach.id === this.scheduleInfo.coach_id);
|
|
if (this.coachPickerIndex === -1) this.coachPickerIndex = 0;
|
|
}
|
|
|
|
// 查找当前场地
|
|
if (this.scheduleInfo.venue_id) {
|
|
this.selectedVenue = this.venueOptions.find(venue => venue.id === this.scheduleInfo.venue_id);
|
|
this.venuePickerIndex = this.venueOptions.findIndex(venue => venue.id === this.scheduleInfo.venue_id);
|
|
if (this.venuePickerIndex === -1) this.venuePickerIndex = 0;
|
|
}
|
|
|
|
// 查找当前时间段
|
|
if (this.scheduleInfo.time_slot && this.timeSlotOptions.length > 0) {
|
|
this.timePickerIndex = this.timeSlotOptions.findIndex(time => time.value === this.scheduleInfo.time_slot);
|
|
if (this.timePickerIndex === -1) this.timePickerIndex = 0;
|
|
}
|
|
},
|
|
|
|
// 生成时间段选项(保留原有方法作为备用)
|
|
generateTimeSlotOptions() {
|
|
// 使用新的默认时间选项生成方法
|
|
this.generateDefaultTimeOptions();
|
|
},
|
|
|
|
// 选择器事件处理
|
|
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) {
|
|
const index = e.detail.value;
|
|
this.coachPickerIndex = index;
|
|
if (index >= 0 && index < this.coachOptions.length) {
|
|
this.selectedCoach = this.coachOptions[index];
|
|
this.formData.coach_id = this.selectedCoach.id;
|
|
}
|
|
},
|
|
|
|
onVenueSelect(e) {
|
|
const index = e.detail.value;
|
|
this.venuePickerIndex = index;
|
|
if (index >= 0 && index < this.venueOptions.length) {
|
|
this.selectedVenue = this.venueOptions[index];
|
|
this.formData.venue_id = this.selectedVenue.id;
|
|
|
|
// 自动填充场地容量
|
|
if (this.selectedVenue.capacity) {
|
|
this.formData.available_capacity = this.selectedVenue.capacity;
|
|
}
|
|
|
|
// 获取该场地的时间选项
|
|
this.loadVenueTimeOptions(this.selectedVenue.id);
|
|
}
|
|
},
|
|
|
|
onDateSelect(e) {
|
|
this.formData.course_date = e.detail.value;
|
|
},
|
|
|
|
onTimeSelect(e) {
|
|
const index = e.detail.value;
|
|
this.timePickerIndex = index;
|
|
if (index >= 0 && index < this.timeSlotOptions.length) {
|
|
this.formData.time_slot = this.timeSlotOptions[index].value;
|
|
}
|
|
},
|
|
|
|
// 表单验证
|
|
validateForm() {
|
|
// 检查是否有任何修改
|
|
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.course_date !== this.scheduleInfo.course_date ||
|
|
this.formData.time_slot !== this.scheduleInfo.time_slot ||
|
|
this.formData.available_capacity !== this.scheduleInfo.available_capacity;
|
|
|
|
if (!hasChanges) {
|
|
uni.showToast({
|
|
title: '未进行任何修改',
|
|
icon: 'none'
|
|
});
|
|
return false;
|
|
}
|
|
|
|
|
|
return true;
|
|
},
|
|
|
|
// 获取场地时间选项
|
|
async loadVenueTimeOptions(venueId) {
|
|
if (!venueId) {
|
|
// 如果没有选择场地,使用默认时间选项
|
|
this.generateDefaultTimeOptions();
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const res = await api.getVenueTimeOptions({ venue_id: venueId });
|
|
|
|
if (res.code === 1) {
|
|
this.timeSlotOptions = res.data.time_options || [];
|
|
// 更新时间picker索引
|
|
this.updateTimePickerIndex();
|
|
} else {
|
|
console.error('获取场地时间选项失败:', res.msg);
|
|
// 如果获取失败,使用默认时间选项
|
|
this.generateDefaultTimeOptions();
|
|
this.updateTimePickerIndex();
|
|
}
|
|
} catch (error) {
|
|
console.error('获取场地时间选项失败:', error);
|
|
// 如果获取失败,使用默认时间选项
|
|
this.generateDefaultTimeOptions();
|
|
this.updateTimePickerIndex();
|
|
}
|
|
},
|
|
|
|
// 生成默认时间选项(8:30开始,每小时一档)
|
|
generateDefaultTimeOptions() {
|
|
const timeSlots = [];
|
|
|
|
for (let hour = 8; hour < 22; hour++) {
|
|
const minute = (hour === 8) ? '30' : '00'; // 8:30开始
|
|
const startHour = hour.toString().padStart(2, '0');
|
|
const endHour = (hour + 1).toString().padStart(2, '0');
|
|
const startTime = `${startHour}:${minute}`;
|
|
const endTime = `${endHour}:${minute}`;
|
|
|
|
timeSlots.push({
|
|
value: `${startTime}-${endTime}`,
|
|
text: `${startTime}-${endTime}`
|
|
});
|
|
}
|
|
|
|
this.timeSlotOptions = timeSlots;
|
|
},
|
|
|
|
// 更新时间picker索引
|
|
updateTimePickerIndex() {
|
|
if (this.formData.time_slot && this.timeSlotOptions.length > 0) {
|
|
this.timePickerIndex = this.timeSlotOptions.findIndex(time => time.value === this.formData.time_slot);
|
|
if (this.timePickerIndex === -1) this.timePickerIndex = 0;
|
|
}
|
|
},
|
|
|
|
// 获取最小日期(当前日期)
|
|
getMinDate() {
|
|
const today = new Date();
|
|
const year = today.getFullYear();
|
|
const month = (today.getMonth() + 1).toString().padStart(2, '0');
|
|
const day = today.getDate().toString().padStart(2, '0');
|
|
return `${year}-${month}-${day}`;
|
|
},
|
|
|
|
// 获取最大日期(一年后)
|
|
getMaxDate() {
|
|
const nextYear = new Date();
|
|
nextYear.setFullYear(nextYear.getFullYear() + 1);
|
|
const year = nextYear.getFullYear();
|
|
const month = (nextYear.getMonth() + 1).toString().padStart(2, '0');
|
|
const day = nextYear.getDate().toString().padStart(2, '0');
|
|
return `${year}-${month}-${day}`;
|
|
},
|
|
|
|
// 获取当前日期作为默认值
|
|
getCurrentDate() {
|
|
const today = new Date();
|
|
const year = today.getFullYear();
|
|
const month = (today.getMonth() + 1).toString().padStart(2, '0');
|
|
const day = today.getDate().toString().padStart(2, '0');
|
|
return `${year}-${month}-${day}`;
|
|
},
|
|
|
|
// 提交表单
|
|
async submitForm() {
|
|
if (!this.validateForm()) {
|
|
return;
|
|
}
|
|
|
|
this.submitting = true;
|
|
|
|
try {
|
|
const res = await api.updateCourseSchedule(this.formData);
|
|
|
|
if (res.code === 1) {
|
|
uni.showToast({
|
|
title: '调整成功',
|
|
icon: 'success'
|
|
});
|
|
|
|
// 延迟返回,让用户看到成功提示
|
|
setTimeout(() => {
|
|
uni.navigateBack();
|
|
}, 1500);
|
|
} else {
|
|
uni.showToast({
|
|
title: res.msg || '调整失败',
|
|
icon: 'none'
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('调整课程安排失败:', error);
|
|
uni.showToast({
|
|
title: '调整失败,请重试',
|
|
icon: 'none'
|
|
});
|
|
} finally {
|
|
this.submitting = false;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.adjust-course-container {
|
|
min-height: 100vh;
|
|
background-color: #18181c;
|
|
}
|
|
|
|
.form-container {
|
|
padding: 30rpx;
|
|
}
|
|
|
|
.loading-container {
|
|
height: 200rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.loading-text {
|
|
margin-top: 20rpx;
|
|
font-size: 28rpx;
|
|
color: #999;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
color: #29d3b4;
|
|
margin: 30rpx 0 20rpx;
|
|
padding-bottom: 10rpx;
|
|
border-bottom: 1px solid #333;
|
|
}
|
|
|
|
.course-info-card {
|
|
background-color: #23232a;
|
|
border-radius: 12rpx;
|
|
padding: 20rpx;
|
|
margin-bottom: 30rpx;
|
|
}
|
|
|
|
.info-row {
|
|
display: flex;
|
|
margin-bottom: 16rpx;
|
|
font-size: 28rpx;
|
|
}
|
|
|
|
.info-label {
|
|
color: #999;
|
|
width: 160rpx;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.info-value {
|
|
color: #fff;
|
|
flex: 1;
|
|
}
|
|
|
|
.selector-input {
|
|
height: 80rpx;
|
|
background-color: #23232a;
|
|
border-radius: 8rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0 24rpx;
|
|
font-size: 28rpx;
|
|
color: #fff;
|
|
}
|
|
|
|
.btn-container {
|
|
margin-top: 60rpx;
|
|
padding: 0 30rpx;
|
|
}
|
|
|
|
/* Picker样式 */
|
|
.picker-mask {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
z-index: 9999;
|
|
display: flex;
|
|
align-items: flex-end;
|
|
}
|
|
|
|
.picker-content {
|
|
width: 100%;
|
|
background-color: #23232a;
|
|
border-radius: 20rpx 20rpx 0 0;
|
|
max-height: 80vh;
|
|
}
|
|
|
|
.picker-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 30rpx;
|
|
border-bottom: 1px solid #333;
|
|
}
|
|
|
|
.picker-cancel, .picker-confirm {
|
|
font-size: 28rpx;
|
|
color: #29d3b4;
|
|
}
|
|
|
|
.picker-title {
|
|
font-size: 32rpx;
|
|
color: #fff;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.picker-item {
|
|
height: 80rpx;
|
|
line-height: 80rpx;
|
|
text-align: center;
|
|
font-size: 28rpx;
|
|
color: #fff;
|
|
}
|
|
</style>
|