index.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. import request from '@/helpers/request'
  2. import { Button, Popup, Tag, Toast } from 'vant'
  3. import { defineComponent } from 'vue'
  4. import styles from './index.module.less'
  5. import dayjs from 'dayjs'
  6. import { createState } from '../createState'
  7. import { state } from '@/state'
  8. import { getWeekCh } from '@/helpers/utils'
  9. import ColCalendar from '@/components/col-calendar'
  10. import { ElButton, ElDialog, ElMessageBox, ElTag } from 'element-plus'
  11. export default defineComponent({
  12. name: 'arrange',
  13. data() {
  14. return {
  15. selectStatus: false,
  16. calendarList: {},
  17. calendarDate: new Date() as Date // 日历当前时间
  18. }
  19. },
  20. computed: {
  21. showSelectList() {
  22. let list = [...createState.selectCourseList]
  23. list.forEach((item: any) => {
  24. item.title =
  25. dayjs(item.startTime).format('YYYY-MM-DD') +
  26. ' ' +
  27. getWeekCh(dayjs(item.startTime).day()) +
  28. ' ' +
  29. item.start +
  30. '~' +
  31. item.end
  32. })
  33. return list
  34. },
  35. selectType() {
  36. // 循环次数是否足够
  37. return createState.selectCourseList.length < createState.live.courseNum
  38. ? 'noEnough'
  39. : 'enough'
  40. }
  41. },
  42. async mounted() {
  43. const initDate = dayjs().add(1, 'day').toDate()
  44. await this.getList(initDate)
  45. if (createState.coursePlanStatus) {
  46. this.selectStatus = true
  47. }
  48. },
  49. methods: {
  50. async getList(date?: Date) {
  51. let params = {
  52. day: dayjs(date || new Date()).format('DD'),
  53. month: dayjs(date || new Date()).format('MM'),
  54. year: dayjs(date || new Date()).format('YYYY')
  55. }
  56. try {
  57. let res = await request.post(
  58. '/api-website/courseSchedule/createLiveCourseCalendar',
  59. {
  60. data: {
  61. ...params,
  62. singleCourseMinutes: createState.live.singleMins,
  63. freeCourseMinutes: createState.live.freeMinutes,
  64. teacherId: state.user.data?.userId
  65. }
  66. }
  67. )
  68. const result = res.data || []
  69. let tempObj = {}
  70. result.forEach((item: any) => {
  71. tempObj[item.date] = item
  72. })
  73. this.calendarList = tempObj
  74. } catch {}
  75. },
  76. onSelectDay(obj: any) {
  77. const result = obj || []
  78. let list = [...createState.selectCourseList]
  79. console.log(obj, list)
  80. result.forEach((item: any) => {
  81. const isExist = list.some(
  82. (course: any) => course.startTime === item.startTime
  83. )
  84. !isExist && list.push({ ...item })
  85. })
  86. // 去掉不在
  87. let tempList: any[] = []
  88. list.forEach((item: any) => {
  89. const isExist = result.some(
  90. (course: any) => course.startTime === item.startTime
  91. )
  92. // const index = result.findIndex(
  93. // (course: any) => course.startTime === item.startTime
  94. // )
  95. // !isExist && list.splice(index, 1)
  96. isExist && tempList.push(item)
  97. })
  98. // 对数组进行排序
  99. tempList.sort((first: any, second: any) => {
  100. if (first.startTime > second.startTime) return 1
  101. if (first.startTime < second.startTime) return -1
  102. return 0
  103. })
  104. createState.selectCourseList = [...tempList]
  105. },
  106. onCloseTag(item: any) {
  107. Dialog.confirm({
  108. title: '提示',
  109. message: '您是否要删除该选择的课程?',
  110. confirmButtonColor: 'var(--van-primary)'
  111. }).then(() => {
  112. const index = createState.selectCourseList.findIndex(
  113. (course: any) => course.startTime === item.startTime
  114. )
  115. createState.selectCourseList.splice(index, 1)
  116. })
  117. },
  118. async onSubmit() {
  119. if (createState.selectCourseList.length <= 0) {
  120. Toast('请选择课程时间')
  121. return
  122. }
  123. if (createState.selectCourseList.length < createState.live.courseNum) {
  124. this.selectStatus = true
  125. return
  126. }
  127. await this._lookCourse()
  128. },
  129. async _lookCourse(callBack?: Function) {
  130. try {
  131. let times = [] as any
  132. createState.selectCourseList.forEach((item: any) => {
  133. times.push({
  134. startTime: item.startTime,
  135. endTime: item.endTime
  136. })
  137. })
  138. const res = await request.post(
  139. '/api-website/courseGroup/lockCourseToCache',
  140. {
  141. data: {
  142. courseNum: createState.live.courseNum,
  143. courseType: 'LIVE',
  144. loop: this.selectType === 'noEnough' ? 1 : 0,
  145. teacherId: state.user.data?.userId,
  146. timeList: [...times]
  147. }
  148. }
  149. )
  150. const result = res.data || []
  151. result.forEach((item: any, index: number) => {
  152. createState.live.coursePlanList[index] = {
  153. ...createState.live.coursePlanList[index],
  154. startTime: item.startTime,
  155. endTime: item.endTime,
  156. classNum: index + 1
  157. }
  158. })
  159. createState.coursePlanStatus = true
  160. this.selectStatus = true
  161. callBack && callBack()
  162. } catch (e: any) {
  163. // 报错时需要重置日历表的数据
  164. const message = e.message
  165. Dialog.alert({
  166. title: '提示',
  167. confirmButtonColor: 'var(--van-primary)',
  168. message
  169. }).then(() => {
  170. this.getList(this.calendarDate || new Date())
  171. createState.selectCourseList = []
  172. this.selectStatus = false
  173. })
  174. }
  175. },
  176. async _unLookCourse() {
  177. try {
  178. await request.get('/api-website/courseGroup/unlockCourseToCache', {
  179. params: {
  180. teacherId: state.user.data?.userId
  181. }
  182. })
  183. this.selectStatus = false
  184. setTimeout(() => {
  185. createState.live.coursePlanList.forEach((item: any) => {
  186. item.startTime = ''
  187. item.endTime = ''
  188. })
  189. }, 500)
  190. } catch {}
  191. },
  192. async onReset() {
  193. // 是否有锁课状态 或 是锁课类型的
  194. if (createState.coursePlanStatus || this.selectType === 'enough') {
  195. await this._unLookCourse()
  196. } else if (this.selectType === 'noEnough') {
  197. this.selectStatus = false
  198. }
  199. // 只能重置课程时间
  200. createState.live.coursePlanList.forEach((item: any) => {
  201. item.startTime = ''
  202. item.endTime = ''
  203. })
  204. setTimeout(() => {
  205. createState.coursePlanStatus = false
  206. }, 500)
  207. },
  208. async onSure() {
  209. // 判断是否有锁课状态 或 是锁课类型的 并且已经有课的
  210. console.log(
  211. this.selectType,
  212. createState.coursePlanStatus,
  213. createState.live.coursePlanList
  214. )
  215. let courseLength = 0
  216. createState.live.coursePlanList.forEach((item: any) => {
  217. item.startTime && courseLength++
  218. })
  219. if (this.selectType === 'enough' || courseLength > 0) {
  220. this.selectStatus = false
  221. createState.active = 4
  222. return
  223. }
  224. const status = createState.coursePlanStatus
  225. await this._lookCourse(() => {
  226. if (status) {
  227. this.selectStatus = false
  228. createState.active = 4
  229. }
  230. })
  231. }
  232. },
  233. render() {
  234. return (
  235. <div class={[styles.arrange]}>
  236. <div class="px-[235px] pt-7">
  237. <div class="border-dashed border-[#EDEDED] border-2 rounded-lg px-8 pt-4 pb-6">
  238. <ColCalendar
  239. selectList={createState.selectCourseList}
  240. list={this.calendarList}
  241. maxDays={createState.live.courseNum || 0}
  242. nextMonth={(date: Date) => this.getList(date)}
  243. prevMonth={(date: Date) => this.getList(date)}
  244. selectDay={this.onSelectDay}
  245. v-model:calendarDate={this.calendarDate}
  246. />
  247. </div>
  248. <div class={[styles.arrangeCell, '!my-4']}>
  249. <div class={styles.rTitle}>
  250. <span>已选择课程时间</span>
  251. </div>
  252. <div class={styles.rTag}>
  253. {this.showSelectList.map((item: any) => (
  254. <>
  255. <ElTag
  256. round
  257. size="large"
  258. effect="light"
  259. class={['mb-2 !border-[#2DC7AA] !color-[#2DC7AA]']}
  260. closable
  261. onClose={() => this.onCloseTag(item)}
  262. >
  263. {item.title}
  264. </ElTag>
  265. <br />
  266. </>
  267. ))}
  268. </div>
  269. </div>
  270. </div>
  271. <div class="border-t border-t-[#E5E5E5] text-center pt-6 pb-7">
  272. <ElButton
  273. class="!w-40 !h-[38px]"
  274. onClick={() => {
  275. createState.active = 2
  276. // 重置选择的课次
  277. createState.selectCourseList = []
  278. }}
  279. >
  280. 上一步
  281. </ElButton>
  282. <ElButton
  283. type="primary"
  284. class="!w-40 !h-[38px]"
  285. onClick={this.onSubmit}
  286. >
  287. 下一步
  288. </ElButton>
  289. </div>
  290. <ElDialog
  291. modelValue={this.selectStatus}
  292. onUpdate:modelValue={e => (this.selectStatus = e)}
  293. width={'400px'}
  294. title="提示"
  295. >
  296. <div class={styles.selectContainer}>
  297. <div class={styles.selectPopupContent}>
  298. <p class={styles.desc}>
  299. {this.selectType === 'noEnough' && !createState.coursePlanStatus
  300. ? '您所选择的上课时间未达到您输入的课时数,系统根据已选时间将自动按周顺延排课。'
  301. : '您已选择以下上课时间段,时间段会暂时锁定,锁定期间学员不可购买该时间段课程。'}
  302. </p>
  303. {createState.live.coursePlanList &&
  304. createState.live.coursePlanList.length > 0 &&
  305. createState.coursePlanStatus && (
  306. <p class={styles.times}>
  307. {createState.live.coursePlanList.map((item: any) => (
  308. <span>
  309. {dayjs(item.startTime || new Date()).format(
  310. 'YYYY-MM-DD'
  311. )}{' '}
  312. {dayjs(item.startTime || new Date()).format('HH:mm')}~
  313. {dayjs(item.endTime || new Date()).format('HH:mm')}
  314. </span>
  315. ))}
  316. </p>
  317. )}
  318. </div>
  319. <div class={styles.selectBtn}>
  320. <ElButton
  321. type="primary"
  322. round
  323. plain
  324. class="!w-40 !h-[38px]"
  325. onClick={this.onReset}
  326. >
  327. {this.selectType === 'noEnough' ? '继续选择' : '重新选择'}
  328. </ElButton>
  329. <ElButton
  330. type="primary"
  331. round
  332. class="!w-40 !h-[38px]"
  333. onClick={this.onSure}
  334. >
  335. 确认
  336. </ElButton>
  337. </div>
  338. </div>
  339. </ElDialog>
  340. {/* <Popup show={this.selectStatus} class={styles.selectPopup}>
  341. <div class={styles.selectContainer}>
  342. <div class={styles.rTitle}>
  343. <span>提示</span>
  344. </div>
  345. <div class={styles.selectPopupContent}>
  346. <p class={styles.desc}>
  347. {this.selectType === 'noEnough' && !createState.coursePlanStatus
  348. ? '您所选择的上课时间未达到您输入的课时数,系统根据已选时间将自动按周顺延排课。'
  349. : '您已选择以下上课时间段,时间段会暂时锁定,锁定期间学员不可购买该时间段课程。'}
  350. </p>
  351. {createState.live.coursePlanList &&
  352. createState.live.coursePlanList.length > 0 &&
  353. createState.coursePlanStatus && (
  354. <p class={styles.times}>
  355. {createState.live.coursePlanList.map((item: any) => (
  356. <span>
  357. {dayjs(item.startTime || new Date()).format(
  358. 'YYYY-MM-DD'
  359. )}{' '}
  360. {dayjs(item.startTime || new Date()).format('HH:mm')}~
  361. {dayjs(item.endTime || new Date()).format('HH:mm')}
  362. </span>
  363. ))}
  364. </p>
  365. )}
  366. </div>
  367. <div class={styles.selectBtn}>
  368. <Button
  369. class={styles.btn}
  370. type="primary"
  371. round
  372. block
  373. plain
  374. onClick={this.onReset}
  375. >
  376. {this.selectType === 'noEnough' ? '继续选择' : '重新选择'}
  377. </Button>
  378. <Button
  379. class={styles.btn}
  380. type="primary"
  381. round
  382. block
  383. onClick={this.onSure}
  384. >
  385. 确认
  386. </Button>
  387. </div>
  388. </div>
  389. </Popup> */}
  390. </div>
  391. )
  392. }
  393. })