arrange.tsx 12 KB

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