practice-calendar.tsx 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. import dayjs from 'dayjs'
  2. import Calendar from '@/business-components/calendar'
  3. import { Button, Cell, Dialog, Popup, Tag } from 'vant'
  4. import { defineComponent } from 'vue'
  5. import styles from './practice-calendar.module.less'
  6. import { getWeekCh } from '@/helpers/utils'
  7. import request from '@/helpers/request'
  8. import { state } from '@/state'
  9. export default defineComponent({
  10. name: 'practice-calendar',
  11. props: {
  12. courseNum: {
  13. type: Number,
  14. default: 4
  15. },
  16. teacherId: {
  17. type: [Number, String],
  18. default: ''
  19. }
  20. },
  21. data() {
  22. return {
  23. calendarList: [] as any,
  24. selectCourseList: [] as any,
  25. coursePlanStatus: false,
  26. selectStatus: false,
  27. coursePlanList: []
  28. }
  29. },
  30. computed: {
  31. showSelectList() {
  32. const arr: any = this.selectCourseList
  33. let list = [...arr]
  34. list.forEach((item: any) => {
  35. item.title =
  36. dayjs(item.startTime).format('YYYY-MM-DD') +
  37. ' ' +
  38. getWeekCh(dayjs(item.startTime).day()) +
  39. ' ' +
  40. item.start +
  41. '~' +
  42. item.end
  43. })
  44. return list
  45. },
  46. selectType() {
  47. // 循环次数是否足够
  48. return this.selectCourseList.length < this.courseNum
  49. ? 'noEnough'
  50. : 'enough'
  51. }
  52. },
  53. mounted() {
  54. this.getList()
  55. },
  56. methods: {
  57. async getList(date?: Date) {
  58. try {
  59. let params = {
  60. day: dayjs(date || new Date()).format('DD'),
  61. month: dayjs(date || new Date()).format('MM'),
  62. year: dayjs(date || new Date()).format('YYYY')
  63. }
  64. let res = await request.post(
  65. '/api-student/courseSchedule/createPracticeCourseCalendar',
  66. {
  67. data: {
  68. ...params,
  69. studentId: state.user.data?.userId,
  70. teacherId: this.teacherId
  71. }
  72. }
  73. )
  74. const result = res.data || []
  75. let tempObj = {}
  76. result.forEach((item: any) => {
  77. tempObj[item.date] = item
  78. })
  79. this.calendarList = tempObj
  80. } catch {}
  81. },
  82. onSelectDay(obj: any) {
  83. const result = obj || []
  84. let list = [...this.selectCourseList] as any
  85. console.log(obj, list)
  86. result.forEach((item: any) => {
  87. const isExist = list.some(
  88. (course: any) => course.startTime === item.startTime
  89. )
  90. !isExist && list.push({ ...item })
  91. })
  92. // 去掉不在
  93. list.forEach((item: any) => {
  94. const isExist = result.some(
  95. (course: any) => course.startTime === item.startTime
  96. )
  97. const index = result.findIndex(
  98. (course: any) => course.startTime === item.startTime
  99. )
  100. !isExist && list.splice(index, 1)
  101. })
  102. // 对数组进行排序
  103. list.sort((first: any, second: any) => {
  104. if (first.startTime > second.startTime) return 1
  105. if (first.startTime < second.startTime) return -1
  106. return 0
  107. })
  108. console.log(list, 'list')
  109. this.selectCourseList = [...list] as any
  110. },
  111. onCloseTag(item: any) {
  112. Dialog.confirm({
  113. title: '提示',
  114. message: '您是否要删除该选择的课程?',
  115. confirmButtonColor: 'var(--van-primary)'
  116. }).then(() => {
  117. const index = this.selectCourseList.findIndex(
  118. (course: any) => course.startTime === item.startTime
  119. )
  120. this.selectCourseList.splice(index, 1)
  121. })
  122. }
  123. },
  124. render() {
  125. return (
  126. <>
  127. <div class={styles.group}>
  128. <Calendar
  129. selectList={this.selectCourseList}
  130. list={this.calendarList}
  131. maxDays={this.courseNum}
  132. nextMonth={(date: Date) => this.getList(date)}
  133. prevMonth={(date: Date) => this.getList(date)}
  134. selectDay={this.onSelectDay}
  135. />
  136. </div>
  137. <Cell
  138. class={[styles.arrangeCell, 'mb12']}
  139. v-slots={{
  140. title: () => (
  141. <div class={styles.rTitle}>
  142. <span>已选择课程时间</span>
  143. </div>
  144. ),
  145. label: () => (
  146. <div class={styles.rTag}>
  147. {this.showSelectList.map((item: any) => (
  148. <>
  149. <Tag
  150. plain
  151. round
  152. closeable
  153. size="large"
  154. type="primary"
  155. class={styles.tag}
  156. onClose={() => this.onCloseTag(item)}
  157. >
  158. {item.title}
  159. </Tag>
  160. <br />
  161. </>
  162. ))}
  163. </div>
  164. )
  165. }}
  166. ></Cell>
  167. <Popup show={this.selectStatus} class={styles.selectPopup}>
  168. <div class={styles.selectContainer}>
  169. <div class={styles.rTitle}>
  170. <span>提示</span>
  171. </div>
  172. <div class={styles.selectPopupContent}>
  173. <p class={styles.desc}>
  174. {this.selectType === 'noEnough' && !this.coursePlanStatus
  175. ? '您所选择的上课时间未达到您输入的课时数,系统根据已选时间将自动按周顺延排课。'
  176. : '您已选择以下上课时间段,时间段会暂时锁定,锁定期间学员不可购买该时间段课程。'}
  177. </p>
  178. {this.coursePlanList &&
  179. this.coursePlanList.length > 0 &&
  180. this.coursePlanStatus && (
  181. <p class={styles.times}>
  182. {this.coursePlanList.map((item: any) => (
  183. <span>
  184. {dayjs(item.startTime || new Date()).format(
  185. 'YYYY-MM-DD'
  186. )}{' '}
  187. {dayjs(item.startTime || new Date()).format('HH:mm')}~
  188. {dayjs(item.endTime || new Date()).format('HH:mm')}
  189. </span>
  190. ))}
  191. </p>
  192. )}
  193. </div>
  194. <div class={styles.selectBtn}>
  195. <Button
  196. class={styles.btn}
  197. type="primary"
  198. round
  199. block
  200. plain
  201. onClick={this.onReset}
  202. >
  203. {this.selectType === 'noEnough' ? '继续选择' : '重新选择'}
  204. </Button>
  205. <Button
  206. class={styles.btn}
  207. type="primary"
  208. round
  209. block
  210. onClick={this.onSure}
  211. >
  212. 确认
  213. </Button>
  214. </div>
  215. </div>
  216. </Popup>
  217. </>
  218. )
  219. }
  220. })