|
@@ -1,4 +1,5 @@
|
|
|
import ColProtocol from '@/components/col-protocol'
|
|
|
+import Calendar from '@/business-components/calendar'
|
|
|
import request from '@/helpers/request'
|
|
|
import { state } from '@/state'
|
|
|
import dayjs from 'dayjs'
|
|
@@ -11,10 +12,11 @@ import {
|
|
|
Stepper,
|
|
|
Sticky,
|
|
|
Tag,
|
|
|
- Popup
|
|
|
+ Popup,
|
|
|
+ Toast
|
|
|
} from 'vant'
|
|
|
import { defineComponent } from 'vue'
|
|
|
-import PracticeCalendar from '../model/practice-calendar'
|
|
|
+import { getWeekCh } from '@/helpers/utils'
|
|
|
import styles from './practice.module.less'
|
|
|
|
|
|
export default defineComponent({
|
|
@@ -29,8 +31,6 @@ export default defineComponent({
|
|
|
const query = this.$route.query
|
|
|
return {
|
|
|
teacherId: query.teacherId,
|
|
|
- calendarList: {},
|
|
|
- selectCourseList: [],
|
|
|
agreeStatus: false,
|
|
|
teacherSubjectList: [],
|
|
|
subjectStatus: false,
|
|
@@ -40,7 +40,13 @@ export default defineComponent({
|
|
|
subjectName: '',
|
|
|
subjectId: 0
|
|
|
},
|
|
|
- courseNum: 4
|
|
|
+ courseNum: 4,
|
|
|
+ calendarList: [] as any,
|
|
|
+ selectCourseList: [] as any,
|
|
|
+ coursePlanStatus: false,
|
|
|
+ selectStatus: false,
|
|
|
+ coursePlanList: [] as any,
|
|
|
+ calendarDate: new Date() as Date // 日历当前时间
|
|
|
}
|
|
|
},
|
|
|
async mounted() {
|
|
@@ -71,10 +77,216 @@ export default defineComponent({
|
|
|
item.name = item.subjectName
|
|
|
})
|
|
|
this.teacherSubjectList = result
|
|
|
+
|
|
|
+ this.getList()
|
|
|
} catch {}
|
|
|
},
|
|
|
+ computed: {
|
|
|
+ showSelectList() {
|
|
|
+ const arr: any = this.selectCourseList
|
|
|
+ let list = [...arr]
|
|
|
+ list.forEach((item: any) => {
|
|
|
+ item.title =
|
|
|
+ dayjs(item.startTime).format('YYYY-MM-DD') +
|
|
|
+ ' ' +
|
|
|
+ getWeekCh(dayjs(item.startTime).day()) +
|
|
|
+ ' ' +
|
|
|
+ item.start +
|
|
|
+ '~' +
|
|
|
+ item.end
|
|
|
+ })
|
|
|
+ return list
|
|
|
+ },
|
|
|
+ selectType() {
|
|
|
+ // 循环次数是否足够
|
|
|
+ return this.selectCourseList.length < this.courseNum
|
|
|
+ ? 'noEnough'
|
|
|
+ : 'enough'
|
|
|
+ }
|
|
|
+ },
|
|
|
methods: {
|
|
|
- onSubmit() {}
|
|
|
+ async onSubmit() {
|
|
|
+ if (this.selectCourseList.length <= 0) {
|
|
|
+ Toast('请选择课程时间')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.agreeStatus) {
|
|
|
+ Toast('请先阅读并同意《酷乐秀平台服务协议》')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.selectCourseList.length < this.courseNum) {
|
|
|
+ this.selectStatus = true
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ await this._lookCourse()
|
|
|
+ },
|
|
|
+ async getList(date?: Date) {
|
|
|
+ try {
|
|
|
+ let params = {
|
|
|
+ day: dayjs(date || new Date()).format('DD'),
|
|
|
+ month: dayjs(date || new Date()).format('MM'),
|
|
|
+ year: dayjs(date || new Date()).format('YYYY')
|
|
|
+ }
|
|
|
+ let res = await request.post(
|
|
|
+ '/api-student/courseSchedule/createPracticeCourseCalendar',
|
|
|
+ {
|
|
|
+ data: {
|
|
|
+ ...params,
|
|
|
+ studentId: state.user.data?.userId,
|
|
|
+ teacherId: this.teacherId
|
|
|
+ }
|
|
|
+ }
|
|
|
+ )
|
|
|
+ const result = res.data || []
|
|
|
+ let tempObj = {}
|
|
|
+ result.forEach((item: any) => {
|
|
|
+ tempObj[item.date] = item
|
|
|
+ })
|
|
|
+ this.calendarList = tempObj
|
|
|
+ } catch {}
|
|
|
+ },
|
|
|
+ onSelectDay(obj: any) {
|
|
|
+ const result = obj || []
|
|
|
+ let list = [...this.selectCourseList] as any
|
|
|
+ console.log(obj, list)
|
|
|
+ result.forEach((item: any) => {
|
|
|
+ const isExist = list.some(
|
|
|
+ (course: any) => course.startTime === item.startTime
|
|
|
+ )
|
|
|
+ !isExist && list.push({ ...item })
|
|
|
+ })
|
|
|
+ // 去掉不在
|
|
|
+ list.forEach((item: any) => {
|
|
|
+ const isExist = result.some(
|
|
|
+ (course: any) => course.startTime === item.startTime
|
|
|
+ )
|
|
|
+ const index = result.findIndex(
|
|
|
+ (course: any) => course.startTime === item.startTime
|
|
|
+ )
|
|
|
+ !isExist && list.splice(index, 1)
|
|
|
+ })
|
|
|
+ // 对数组进行排序
|
|
|
+ list.sort((first: any, second: any) => {
|
|
|
+ if (first.startTime > second.startTime) return 1
|
|
|
+ if (first.startTime < second.startTime) return -1
|
|
|
+ return 0
|
|
|
+ })
|
|
|
+ console.log(list, 'list')
|
|
|
+ this.selectCourseList = [...list] as any
|
|
|
+ },
|
|
|
+ onCloseTag(item: any) {
|
|
|
+ Dialog.confirm({
|
|
|
+ title: '提示',
|
|
|
+ message: '您是否要删除该选择的课程?',
|
|
|
+ confirmButtonColor: 'var(--van-primary)'
|
|
|
+ }).then(() => {
|
|
|
+ const index = this.selectCourseList.findIndex(
|
|
|
+ (course: any) => course.startTime === item.startTime
|
|
|
+ )
|
|
|
+ this.selectCourseList.splice(index, 1)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ async _lookCourse(callBack?: Function) {
|
|
|
+ try {
|
|
|
+ let times = [] as any
|
|
|
+ this.selectCourseList.forEach((item: any) => {
|
|
|
+ times.push({
|
|
|
+ startTime: item.startTime,
|
|
|
+ endTime: item.endTime
|
|
|
+ })
|
|
|
+ })
|
|
|
+ const res = await request.post(
|
|
|
+ '/api-teacher/courseGroup/lockCourseToCache',
|
|
|
+ {
|
|
|
+ data: {
|
|
|
+ courseNum: this.courseNum,
|
|
|
+ courseType: 'PRACTICE',
|
|
|
+ loop: this.selectType === 'noEnough' ? 1 : 0,
|
|
|
+ teacherId: this.teacherId,
|
|
|
+ timeList: [...times]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ )
|
|
|
+ const result = res.data || []
|
|
|
+ result.forEach((item: any, index: number) => {
|
|
|
+ this.coursePlanList[index] = {
|
|
|
+ ...this.coursePlanList[index],
|
|
|
+ startTime: item.startTime,
|
|
|
+ endTime: item.endTime,
|
|
|
+ classNum: index + 1
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.coursePlanStatus = true
|
|
|
+ this.selectStatus = true
|
|
|
+ callBack && callBack()
|
|
|
+ } catch (e: any) {
|
|
|
+ // 报错时需要重置日历表的数据
|
|
|
+ const message = e.message
|
|
|
+ Dialog.alert({
|
|
|
+ title: '提示',
|
|
|
+ confirmButtonColor: 'var(--van-primary)',
|
|
|
+ message
|
|
|
+ }).then(() => {
|
|
|
+ this.getList(this.calendarDate || new Date())
|
|
|
+ this.selectCourseList = []
|
|
|
+ this.selectStatus = false
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async _unLookCourse() {
|
|
|
+ try {
|
|
|
+ await request.get('/api-teacher/courseGroup/unlockCourseToCache', {
|
|
|
+ params: {
|
|
|
+ teacherId: state.user.data?.userId
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.selectStatus = false
|
|
|
+ this.coursePlanList.forEach((item: any) => {
|
|
|
+ item.startTime = ''
|
|
|
+ item.endTime = ''
|
|
|
+ })
|
|
|
+ } catch {}
|
|
|
+ },
|
|
|
+ async onReset() {
|
|
|
+ // 是否有锁课状态 或 是锁课类型的
|
|
|
+ if (this.coursePlanStatus || this.selectType === 'enough') {
|
|
|
+ await this._unLookCourse()
|
|
|
+ } else if (this.selectType === 'noEnough') {
|
|
|
+ this.selectStatus = false
|
|
|
+ }
|
|
|
+ this.coursePlanStatus = false
|
|
|
+ },
|
|
|
+ async onSure() {
|
|
|
+ const status = this.coursePlanStatus
|
|
|
+ await this._lookCourse(() => {
|
|
|
+ if (status) {
|
|
|
+ this.selectStatus = false
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ routerTo() {
|
|
|
+ const live = this.live
|
|
|
+ this.$router.push({
|
|
|
+ path: '/orderDetail',
|
|
|
+ query: {
|
|
|
+ orderType: 'LIVE',
|
|
|
+ courseGroupId: live.courseGroupId
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ async cancelPayment(orderNo: string) {
|
|
|
+ try {
|
|
|
+ await request.post('/api-student/userOrder/orderCancel', {
|
|
|
+ data: {
|
|
|
+ orderNo
|
|
|
+ }
|
|
|
+ })
|
|
|
+ // this.routerTo()
|
|
|
+ } catch {}
|
|
|
+ }
|
|
|
},
|
|
|
render() {
|
|
|
return (
|
|
@@ -122,10 +334,108 @@ export default defineComponent({
|
|
|
/>
|
|
|
</CellGroup>
|
|
|
|
|
|
- <PracticeCalendar
|
|
|
- teacherId={this.teacherId as string}
|
|
|
- courseNum={this.courseNum}
|
|
|
- />
|
|
|
+ <div class={styles.group}>
|
|
|
+ <Calendar
|
|
|
+ selectList={this.selectCourseList}
|
|
|
+ list={this.calendarList}
|
|
|
+ maxDays={this.courseNum}
|
|
|
+ nextMonth={(date: Date) => this.getList(date)}
|
|
|
+ prevMonth={(date: Date) => this.getList(date)}
|
|
|
+ selectDay={this.onSelectDay}
|
|
|
+ v-model:calendarDate={this.calendarDate}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <Cell
|
|
|
+ class={[styles.arrangeCell, 'mb12']}
|
|
|
+ v-slots={{
|
|
|
+ title: () => (
|
|
|
+ <div class={styles.rTitle}>
|
|
|
+ <span>已选择课程时间</span>
|
|
|
+ </div>
|
|
|
+ ),
|
|
|
+ label: () => (
|
|
|
+ <div class={styles.rTag}>
|
|
|
+ {this.showSelectList.map((item: any) => (
|
|
|
+ <>
|
|
|
+ <Tag
|
|
|
+ plain
|
|
|
+ round
|
|
|
+ closeable
|
|
|
+ size="large"
|
|
|
+ type="primary"
|
|
|
+ class={styles.tag}
|
|
|
+ onClose={() => this.onCloseTag(item)}
|
|
|
+ >
|
|
|
+ {item.title}
|
|
|
+ </Tag>
|
|
|
+ <br />
|
|
|
+ </>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ ></Cell>
|
|
|
+
|
|
|
+ <div class={styles.protocol}>
|
|
|
+ <ColProtocol
|
|
|
+ v-model={this.agreeStatus}
|
|
|
+ showHeader
|
|
|
+ style={{ paddingLeft: 0, paddingRight: 0 }}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <Popup show={this.selectStatus} class={styles.selectPopup}>
|
|
|
+ <div class={styles.selectContainer}>
|
|
|
+ <div class={styles.rTitle}>
|
|
|
+ <span>提示</span>
|
|
|
+ </div>
|
|
|
+ <div class={styles.selectPopupContent}>
|
|
|
+ <p class={styles.desc}>
|
|
|
+ {this.selectType === 'noEnough' && !this.coursePlanStatus
|
|
|
+ ? '您所选择的上课时间未达到您输入的课时数,系统根据已选时间将自动按周顺延排课。'
|
|
|
+ : '您已选择以下上课时间段,时间段会暂时锁定,锁定期间学员不可购买该时间段课程。'}
|
|
|
+ </p>
|
|
|
+ {this.coursePlanList &&
|
|
|
+ this.coursePlanList.length > 0 &&
|
|
|
+ this.coursePlanStatus && (
|
|
|
+ <p class={styles.times}>
|
|
|
+ {this.coursePlanList.map((item: any) => (
|
|
|
+ <span>
|
|
|
+ {dayjs(item.startTime || new Date()).format(
|
|
|
+ 'YYYY-MM-DD'
|
|
|
+ )}{' '}
|
|
|
+ {dayjs(item.startTime || new Date()).format('HH:mm')}~
|
|
|
+ {dayjs(item.endTime || new Date()).format('HH:mm')}
|
|
|
+ </span>
|
|
|
+ ))}
|
|
|
+ </p>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class={styles.selectBtn}>
|
|
|
+ <Button
|
|
|
+ class={styles.btn}
|
|
|
+ type="primary"
|
|
|
+ round
|
|
|
+ block
|
|
|
+ plain
|
|
|
+ onClick={this.onReset}
|
|
|
+ >
|
|
|
+ {this.selectType === 'noEnough' ? '继续选择' : '重新选择'}
|
|
|
+ </Button>
|
|
|
+ <Button
|
|
|
+ class={styles.btn}
|
|
|
+ type="primary"
|
|
|
+ round
|
|
|
+ block
|
|
|
+ onClick={this.onSure}
|
|
|
+ >
|
|
|
+ 确认
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </Popup>
|
|
|
|
|
|
<ActionSheet
|
|
|
show={this.subjectStatus}
|
|
@@ -147,14 +457,6 @@ export default defineComponent({
|
|
|
/>
|
|
|
</div>
|
|
|
<Sticky offsetBottom={0} position="bottom">
|
|
|
- <div class={styles.protocol}>
|
|
|
- <ColProtocol
|
|
|
- v-model={this.agreeStatus}
|
|
|
- showHeader
|
|
|
- style={{ paddingLeft: 0, paddingRight: 0 }}
|
|
|
- />
|
|
|
- </div>
|
|
|
-
|
|
|
<div
|
|
|
class={'btnGroup'}
|
|
|
style={{ background: '#fff', paddingTop: '10px' }}
|