index.tsx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  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, ElMessageBox } 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. ElMessageBox.confirm('确定删除该课程吗?', '提示', {
  108. type: 'warning'
  109. }).then(() => {
  110. const index = createState.selectCourseList.findIndex(
  111. (course: any) => course.startTime === item.startTime
  112. )
  113. createState.selectCourseList.splice(index, 1)
  114. })
  115. },
  116. async onSubmit() {
  117. if (createState.selectCourseList.length <= 0) {
  118. Toast('请选择课程时间')
  119. return
  120. }
  121. if (createState.selectCourseList.length < createState.live.courseNum) {
  122. this.selectStatus = true
  123. return
  124. }
  125. await this._lookCourse()
  126. },
  127. async _lookCourse(callBack?: Function) {
  128. try {
  129. let times = [] as any
  130. createState.selectCourseList.forEach((item: any) => {
  131. times.push({
  132. startTime: item.startTime,
  133. endTime: item.endTime
  134. })
  135. })
  136. const res = await request.post(
  137. '/api-website/courseGroup/lockCourseToCache',
  138. {
  139. data: {
  140. courseNum: createState.live.courseNum,
  141. courseType: 'LIVE',
  142. loop: this.selectType === 'noEnough' ? 1 : 0,
  143. teacherId: state.user.data?.userId,
  144. timeList: [...times]
  145. }
  146. }
  147. )
  148. const result = res.data || []
  149. result.forEach((item: any, index: number) => {
  150. createState.live.coursePlanList[index] = {
  151. ...createState.live.coursePlanList[index],
  152. startTime: item.startTime,
  153. endTime: item.endTime,
  154. classNum: index + 1
  155. }
  156. })
  157. createState.coursePlanStatus = true
  158. this.selectStatus = true
  159. callBack && callBack()
  160. } catch (e: any) {
  161. // 报错时需要重置日历表的数据
  162. const message = e.message
  163. ElMessageBox.confirm(message, '提示', {
  164. type: 'warning'
  165. }).then(() => {
  166. this.getList(this.calendarDate || new Date())
  167. createState.selectCourseList = []
  168. this.selectStatus = false
  169. })
  170. }
  171. },
  172. async _unLookCourse() {
  173. try {
  174. await request.get('/api-website/courseGroup/unlockCourseToCache', {
  175. params: {
  176. teacherId: state.user.data?.userId
  177. }
  178. })
  179. this.selectStatus = false
  180. setTimeout(() => {
  181. createState.live.coursePlanList.forEach((item: any) => {
  182. item.startTime = ''
  183. item.endTime = ''
  184. })
  185. }, 500)
  186. } catch {}
  187. },
  188. async onReset() {
  189. // 是否有锁课状态 或 是锁课类型的
  190. if (createState.coursePlanStatus || this.selectType === 'enough') {
  191. await this._unLookCourse()
  192. } else if (this.selectType === 'noEnough') {
  193. this.selectStatus = false
  194. }
  195. createState.live.coursePlanList = []
  196. setTimeout(() => {
  197. createState.coursePlanStatus = false
  198. }, 500)
  199. },
  200. async onSure() {
  201. // 判断是否有锁课状态 或 是锁课类型的 并且已经有课的
  202. if (
  203. this.selectType === 'enough' ||
  204. createState.live.coursePlanList.length > 0
  205. ) {
  206. this.selectStatus = false
  207. createState.active = 4
  208. return
  209. }
  210. const status = createState.coursePlanStatus
  211. await this._lookCourse(() => {
  212. if (status) {
  213. this.selectStatus = false
  214. createState.active = 4
  215. }
  216. })
  217. }
  218. },
  219. render() {
  220. return (
  221. <div class={[styles.arrange]}>
  222. <div class="px-[235px] pt-7">
  223. <div class="border-dashed border-[#EDEDED] border-2 rounded-lg px-8 pt-4 pb-6">
  224. <ColCalendar
  225. selectList={createState.selectCourseList}
  226. list={this.calendarList}
  227. maxDays={createState.live.courseNum || 0}
  228. nextMonth={(date: Date) => this.getList(date)}
  229. prevMonth={(date: Date) => this.getList(date)}
  230. selectDay={this.onSelectDay}
  231. v-model:calendarDate={this.calendarDate}
  232. />
  233. </div>
  234. <div class={[styles.arrangeCell, '!my-3']}>
  235. <div class={styles.rTitle}>
  236. <span>已选择课程时间</span>
  237. </div>
  238. <div class={styles.rTag}>
  239. {this.showSelectList.map((item: any) => (
  240. <>
  241. <Tag
  242. plain
  243. round
  244. closeable
  245. size="large"
  246. type="primary"
  247. class={styles.tag}
  248. onClose={() => this.onCloseTag(item)}
  249. >
  250. {item.title}
  251. </Tag>
  252. <br />
  253. </>
  254. ))}
  255. </div>
  256. </div>
  257. </div>
  258. <div class="border-t border-t-[#E5E5E5] text-center pt-6 pb-7">
  259. <ElButton
  260. class="!w-40 !h-[38px]"
  261. onClick={() => {
  262. createState.active = 2
  263. // 重置选择的课次
  264. createState.selectCourseList = []
  265. }}
  266. >
  267. 上一步
  268. </ElButton>
  269. <ElButton
  270. type="primary"
  271. class="!w-40 !h-[38px]"
  272. onClick={this.onSubmit}
  273. >
  274. 下一步
  275. </ElButton>
  276. </div>
  277. <Popup show={this.selectStatus} class={styles.selectPopup}>
  278. <div class={styles.selectContainer}>
  279. <div class={styles.rTitle}>
  280. <span>提示</span>
  281. </div>
  282. <div class={styles.selectPopupContent}>
  283. <p class={styles.desc}>
  284. {this.selectType === 'noEnough' && !createState.coursePlanStatus
  285. ? '您所选择的上课时间未达到您输入的课时数,系统根据已选时间将自动按周顺延排课。'
  286. : '您已选择以下上课时间段,时间段会暂时锁定,锁定期间学员不可购买该时间段课程。'}
  287. </p>
  288. {createState.live.coursePlanList &&
  289. createState.live.coursePlanList.length > 0 &&
  290. createState.coursePlanStatus && (
  291. <p class={styles.times}>
  292. {createState.live.coursePlanList.map((item: any) => (
  293. <span>
  294. {dayjs(item.startTime || new Date()).format(
  295. 'YYYY-MM-DD'
  296. )}{' '}
  297. {dayjs(item.startTime || new Date()).format('HH:mm')}~
  298. {dayjs(item.endTime || new Date()).format('HH:mm')}
  299. </span>
  300. ))}
  301. </p>
  302. )}
  303. </div>
  304. <div class={styles.selectBtn}>
  305. <Button
  306. class={styles.btn}
  307. type="primary"
  308. round
  309. block
  310. plain
  311. onClick={this.onReset}
  312. >
  313. {this.selectType === 'noEnough' ? '继续选择' : '重新选择'}
  314. </Button>
  315. <Button
  316. class={styles.btn}
  317. type="primary"
  318. round
  319. block
  320. onClick={this.onSure}
  321. >
  322. 确认
  323. </Button>
  324. </div>
  325. </div>
  326. </Popup>
  327. </div>
  328. )
  329. }
  330. })