index.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. import OHeader from '@/components/o-header'
  2. import OSticky from '@/components/o-sticky'
  3. import {
  4. Button,
  5. Cell,
  6. CellGroup,
  7. Dialog,
  8. Icon,
  9. Image,
  10. showConfirmDialog,
  11. showToast,
  12. Tab,
  13. Tabs,
  14. Tag
  15. } from 'vant'
  16. import { defineComponent, onMounted, reactive, ref } from 'vue'
  17. import styles from './index.module.less'
  18. import iconTimer from '../../images/icon-timer.png'
  19. import iconTeacher from '@common/images/icon_teacher.png'
  20. import { useRoute, useRouter } from 'vue-router'
  21. import request from '@/helpers/request'
  22. import dayjs from 'dayjs'
  23. import { forms } from '../../create'
  24. import { postMessage } from '@/helpers/native-message'
  25. export default defineComponent({
  26. name: 'course-preview',
  27. setup() {
  28. // SAME_SCHOOL_TEACHER("同学校老师课程冲突"),
  29. // DIFF_SCHOOL_TEACHER("不同学校老师课程冲突"),
  30. // STUDENT("学生课程冲突"),
  31. const route = useRoute()
  32. const router = useRouter()
  33. const state = reactive({
  34. type: route.query.type,
  35. conflictStatus: false,
  36. conflictMessage: '该时间段伴学指导在其他学校有课',
  37. tabValue: '',
  38. courseValue: '',
  39. selectClasses: [] as any, // 选中的班级列表
  40. selectCourse: [] as any, // 选中的课程
  41. choiceCourse: {}, // 选中需要调整的课程
  42. isClick: false
  43. })
  44. const courseTabsRef: any = ref()
  45. // 获取所有
  46. const getClasses = async () => {
  47. try {
  48. const { data } = await request.post('/api-school/orchestra/trainingPlanListCache', {
  49. requestType: 'form',
  50. data: {
  51. cacheId: route.query.cacheId,
  52. classGroupId: forms.selectClassGroupId || null
  53. }
  54. })
  55. // 初始化数据
  56. formatClasses(data)
  57. if (forms.planList.orchestra.length > 0) {
  58. const selectOrchestra = forms.selectOrchestraId
  59. ? { orchestraId: forms.selectOrchestraId }
  60. : forms.planList.orchestra[0]
  61. state.tabValue = selectOrchestra.orchestraId
  62. const selectClasses = forms.selectClassGroupId
  63. ? { classGroupId: forms.selectClassGroupId }
  64. : forms.planList.classes[selectOrchestra.orchestraId]
  65. ? forms.planList.classes[selectOrchestra.orchestraId][0]
  66. : {}
  67. state.courseValue = selectClasses.classGroupId
  68. state.selectClasses = forms.planList.classes[selectOrchestra.orchestraId] || []
  69. state.selectCourse = forms.planList.course[selectClasses.classGroupId]
  70. // 判断是否有数据
  71. forms.selectOrchestraId = null
  72. forms.selectClassGroupId = null
  73. }
  74. } catch {
  75. //
  76. }
  77. }
  78. // 格式化班级数据
  79. const formatClasses = async (data: any) => {
  80. // 判断是否有班级编号,如果有就说明接口只会返回该班的数据
  81. if (forms.selectClassGroupId) {
  82. forms.planList.course[forms.selectClassGroupId] = data || []
  83. return
  84. }
  85. // 初始化乐团
  86. const orchestra: any = []
  87. data.forEach((item: any) => {
  88. const index = orchestra.findIndex((o: any) => o.orchestraId === item.orchestraId)
  89. // 判断是否已经添加过
  90. if (index === -1) {
  91. orchestra.push({
  92. orchestraId: item.orchestraId,
  93. orchestraName: item.orchestraName
  94. })
  95. }
  96. })
  97. // 初始化班级
  98. const classes: any = {}
  99. orchestra.forEach((item: any) => {
  100. data.forEach((child: any) => {
  101. // 判断是否是同一个乐团
  102. if (item.orchestraId === child.orchestraId) {
  103. const classInOrchestra = classes[item.orchestraId]
  104. // // 判断是否已经存在乐团数据
  105. if (classInOrchestra) {
  106. const index = classInOrchestra.findIndex(
  107. (c: any) => c.classGroupId === child.classGroupId
  108. )
  109. if (index === -1) {
  110. classes[item.orchestraId].push({
  111. classGroupId: child.classGroupId,
  112. className: child.className
  113. })
  114. }
  115. } else {
  116. classes[item.orchestraId] = [
  117. {
  118. classGroupId: child.classGroupId,
  119. className: child.className
  120. }
  121. ]
  122. }
  123. }
  124. })
  125. })
  126. // 初始化课程数据
  127. const course: any = {}
  128. for (const item in classes) {
  129. const oList = classes[item] || []
  130. oList.forEach((child: any) => {
  131. const courseList = data.filter((d: any) => d.classGroupId === child.classGroupId)
  132. course[child.classGroupId] = courseList
  133. })
  134. }
  135. forms.planList = {
  136. orchestra,
  137. classes,
  138. course
  139. }
  140. }
  141. const onChoiceCourse = (course: any) => {
  142. forms.selectOrchestraId = state.tabValue || null
  143. forms.selectClassGroupId = state.courseValue || null
  144. router.push({
  145. path: '/course-adjust',
  146. query: {
  147. id: course.id,
  148. cacheId: route.query.cacheId
  149. }
  150. })
  151. }
  152. const onSubmit = async () => {
  153. try {
  154. state.isClick = true
  155. await request.post('/api-school/orchestra/trainingPlan/' + route.query.cacheId)
  156. setTimeout(() => {
  157. showToast(state.type === 'change' ? '调整成功' : '排课成功')
  158. }, 100)
  159. setTimeout(() => {
  160. state.isClick = false
  161. postMessage({ api: 'back', content: {} })
  162. }, 1100)
  163. } catch {
  164. //
  165. state.isClick = false
  166. }
  167. }
  168. onMounted(() => {
  169. getClasses()
  170. })
  171. return () => (
  172. <div class={styles.coursePreview}>
  173. <OSticky position="top">
  174. <OHeader border={false} />
  175. <Tabs
  176. lineWidth={20}
  177. lineHeight={4}
  178. v-model:active={state.tabValue}
  179. swipeThreshold={3}
  180. class={styles.orchestraTabs}
  181. onChange={(val: any) => {
  182. console.log(val, 'val', state.tabValue)
  183. // 乐团变化时
  184. if (!forms.selectClassGroupId) {
  185. state.selectClasses = forms.planList.classes[val] || []
  186. const selectClasses = forms.planList.classes[val]
  187. ? forms.planList.classes[val][0]
  188. : {}
  189. state.selectCourse = forms.planList.course[selectClasses.classGroupId]
  190. state.courseValue = selectClasses.classGroupId
  191. }
  192. }}
  193. >
  194. {forms.planList.orchestra.map((item: any) => (
  195. <Tab title={item.orchestraName} name={item.orchestraId}></Tab>
  196. ))}
  197. </Tabs>
  198. {/* {state.courseValue && ( */}
  199. <Tabs
  200. swipeThreshold={3}
  201. class={styles.courseTabs}
  202. v-model:active={state.courseValue}
  203. lineHeight={0}
  204. shrink
  205. ref={courseTabsRef}
  206. onChange={(val: any) => {
  207. state.selectCourse = forms.planList.course[val]
  208. }}
  209. >
  210. {state.selectClasses.map((item: any) => (
  211. <Tab title={item.className} name={item.classGroupId}></Tab>
  212. ))}
  213. </Tabs>
  214. {/* )} */}
  215. </OSticky>
  216. {state.selectCourse.map((item: any) => (
  217. <CellGroup inset class={styles.cellGroup}>
  218. <Cell center class={styles.cellDatetime}>
  219. {{
  220. title: () => (
  221. <div class={styles.cellDate}>
  222. <Icon name={iconTimer} class={styles.iconTimer} />
  223. {dayjs(item.classDate).format('YYYY-MM-DD')}
  224. </div>
  225. ),
  226. value: () => <span class={styles.cellTime}>{item.singleCourseTime}分钟</span>
  227. }}
  228. </Cell>
  229. <div
  230. class={[
  231. styles.cellTimeRange,
  232. item.conflictType && item.conflictType.length > 0 && styles.conflictType
  233. ]}
  234. >
  235. {dayjs(item.startTime).format('HH:mm')}-{dayjs(item.endTime).format('HH:mm')}
  236. </div>
  237. <Cell center class={styles.cellTeacher} border={false}>
  238. {{
  239. icon: () => <Image src={item.teacherAvatar || iconTeacher} class={styles.img} />,
  240. title: () => (
  241. <div class={styles.teacherInfo}>
  242. <p class={[styles.teacherName, 'van-ellipsis']}>{item.teacherName}</p>
  243. <Tag type="primary">{item.className}</Tag>
  244. </div>
  245. ),
  246. value: () => (
  247. <Button
  248. round
  249. plain
  250. type="primary"
  251. class={styles.btn}
  252. onClick={() => onChoiceCourse(item)}
  253. >
  254. 调整
  255. </Button>
  256. )
  257. }}
  258. </Cell>
  259. <Cell center border={false} class={[styles.cellTeacher, styles.conflictGrouop]}>
  260. {{
  261. title: () => (
  262. <>
  263. {item.conflictType && item.conflictType.includes('STUDENT') && (
  264. <Tag
  265. class={styles.conflict}
  266. color="#F44541"
  267. size="large"
  268. onClick={() => {
  269. state.conflictMessage = '学生时间冲突'
  270. state.conflictStatus = true
  271. state.choiceCourse = item
  272. }}
  273. >
  274. 学生冲突
  275. </Tag>
  276. )}
  277. {item.conflictType && item.conflictType.includes('DIFF_SCHOOL_TEACHER') && (
  278. <Tag
  279. class={styles.conflict}
  280. color="#F44541"
  281. size="large"
  282. onClick={() => {
  283. state.conflictMessage = '该时间段伴学指导在其他学校有课'
  284. state.conflictStatus = true
  285. state.choiceCourse = item
  286. }}
  287. >
  288. 学校冲突
  289. </Tag>
  290. )}
  291. {item.conflictType && item.conflictType.includes('SAME_SCHOOL_TEACHER') && (
  292. <Tag
  293. class={styles.conflict}
  294. color="#F44541"
  295. size="large"
  296. onClick={() => {
  297. state.conflictMessage = '伴学指导在本学校时间有冲突'
  298. state.conflictStatus = true
  299. state.choiceCourse = item
  300. }}
  301. >
  302. 老师冲突
  303. </Tag>
  304. )}
  305. {item.conflictType && item.conflictType.includes('LEAVE') && (
  306. <Tag
  307. class={styles.conflict}
  308. color="#F44541"
  309. size="large"
  310. onClick={() => {
  311. state.conflictMessage = '伴学指导请假冲突'
  312. state.conflictStatus = true
  313. state.choiceCourse = item
  314. }}
  315. >
  316. 请假冲突
  317. </Tag>
  318. )}
  319. </>
  320. )
  321. }}
  322. </Cell>
  323. </CellGroup>
  324. ))}
  325. <OSticky position="bottom">
  326. <div class={'btnGroup'}>
  327. <Button
  328. round
  329. block
  330. type="primary"
  331. size="large"
  332. onClick={onSubmit}
  333. disabled={state.isClick}
  334. >
  335. {state.type === 'change' ? '确认调整' : '确认排课'}
  336. </Button>
  337. </div>
  338. </OSticky>
  339. <Dialog
  340. v-model:show={state.conflictStatus}
  341. message={state.conflictMessage}
  342. messageAlign="center"
  343. confirmButtonText="去调整"
  344. cancelButtonText="知道了"
  345. showCancelButton
  346. onConfirm={() => {
  347. state.conflictStatus = false
  348. onChoiceCourse(state.choiceCourse)
  349. }}
  350. >
  351. {{
  352. title: () => (
  353. <div class={styles.dialogTitle}>
  354. <i></i>
  355. 课程冲突
  356. </div>
  357. )
  358. }}
  359. </Dialog>
  360. </div>
  361. )
  362. }
  363. })