attend-student.tsx 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. import OSearch from '@/components/o-search'
  2. import OEmpty from '@/components/o-empty'
  3. import dayjs from 'dayjs'
  4. import OFullRefresh from '@/components/o-full-refresh'
  5. import {
  6. Icon,
  7. Popover,
  8. DatePicker,
  9. DatePickerColumnType,
  10. Popup,
  11. List,
  12. PullRefresh,
  13. ActionSheet,
  14. showToast,
  15. Sticky,
  16. Picker
  17. } from 'vant'
  18. import { defineComponent, reactive, ref, onMounted, watch } from 'vue'
  19. import { useRouter } from 'vue-router'
  20. import styles from './attent-student.module.less'
  21. import request from '@/helpers/request'
  22. import { state as globalState } from '@/state'
  23. import StudentAttItem from '../modals/studentAtt-item'
  24. export default defineComponent({
  25. name: 'attend-student',
  26. props: {
  27. toHeight: {
  28. type: Number,
  29. default: 0
  30. }
  31. },
  32. setup(props, { emit }) {
  33. const router = useRouter()
  34. const state = reactive({
  35. showPopoverTime: false,
  36. showPopoverOrchestra: false,
  37. showPopoverSubject: false,
  38. actions: [] as any,
  39. subjects: [] as any,
  40. currentDate: [dayjs().format('YYYY'), dayjs().format('MM')]
  41. })
  42. const forms = reactive({
  43. time: state.currentDate[0] + '' + state.currentDate[1],
  44. timeName: state.currentDate[0] + '年' + state.currentDate[1] + '月',
  45. orchestraId: '',
  46. orchestraName: '全部乐团',
  47. subjectId: '',
  48. subjectName: '全部声部',
  49. page: 1,
  50. rows: 20
  51. })
  52. const toTop = ref(props.toHeight)
  53. const minDate = ref(new Date(dayjs().subtract(10, 'year').format('YYYY-MM-DD')))
  54. const maxDate = ref(new Date(dayjs().add(10, 'year').format('YYYY-MM-DD')))
  55. const columnsType = ref<DatePickerColumnType[]>(['year', 'month'])
  56. const refreshing = ref(false)
  57. const loading = ref(false)
  58. const finished = ref(false)
  59. const showContact = ref(false)
  60. const list = ref([])
  61. const getList = async () => {
  62. loading.value = true
  63. try {
  64. if (refreshing.value) {
  65. // forms.page = 1
  66. list.value = []
  67. refreshing.value = false
  68. }
  69. const res = await request.post(
  70. '/api-school/courseScheduleStudentAttendance/studentAttendance',
  71. {
  72. data: { ...forms }
  73. }
  74. )
  75. if (list.value.length > 0 && res.data.pages === 1) {
  76. return
  77. }
  78. // forms.page = res.data.current + 1
  79. list.value = res.data
  80. showContact.value = list.value.length > 0
  81. // console.log(showContact.value, ' showContact.value ')
  82. loading.value = false
  83. finished.value = true
  84. } catch (e: any) {
  85. // console.log(e, 'e')
  86. const message = e.message
  87. showToast(message)
  88. showContact.value = false
  89. finished.value = true
  90. }
  91. }
  92. const checkTimer = (val: any) => {
  93. forms.time = val.selectedValues[0] + val.selectedValues[1]
  94. forms.timeName = val.selectedValues[0] + '年' + val.selectedValues[1] + '月'
  95. state.showPopoverTime = false
  96. getList()
  97. }
  98. const checkOrchestra = (val: any) => {
  99. const selectedOptions = val.selectedOptions[0] || {}
  100. forms.orchestraId = selectedOptions.value
  101. forms.orchestraName = selectedOptions.name
  102. state.showPopoverOrchestra = false
  103. refreshing.value = true
  104. getList()
  105. }
  106. const checkSubject = (val: any) => {
  107. const selectedOptions = val.selectedOptions[0] || {}
  108. forms.subjectId = selectedOptions.value
  109. forms.subjectName = selectedOptions.name
  110. state.showPopoverSubject = false
  111. refreshing.value = true
  112. getList()
  113. }
  114. const getOrchestraList = async () => {
  115. try {
  116. const res = await request.post('/api-teacher/orchestra/page', {
  117. data: { page: 1, rows: 9999, status: 'DONE' }
  118. })
  119. state.actions = res.data.rows.map((item) => {
  120. return {
  121. name: item.name,
  122. value: item.id as string
  123. }
  124. })
  125. } catch (e: any) {
  126. const message = e.message
  127. showToast(message)
  128. }
  129. }
  130. const getSubjects = async () => {
  131. try {
  132. const res = await request.post('/api-school/subjectBasicConfig/page', {
  133. data: { page: 1, rows: 9999 }
  134. })
  135. state.subjects = res.data.rows.map((item) => {
  136. return {
  137. name: item.subjectName,
  138. value: item.subjectId as string
  139. }
  140. })
  141. state.subjects.unshift({ name: '全部声部', value: '' })
  142. } catch (e: any) {
  143. const message = e.message
  144. showToast(message)
  145. }
  146. }
  147. onMounted(() => {
  148. getSubjects()
  149. getOrchestraList()
  150. getList()
  151. })
  152. watch(
  153. () => props.toHeight,
  154. (val: number) => {
  155. toTop.value = val
  156. }
  157. )
  158. const onRefresh = () => {
  159. finished.value = false
  160. // 重新加载数据
  161. // 将 loading 设置为 true,表示处于加载状态
  162. loading.value = true
  163. getList()
  164. }
  165. return () => (
  166. <div
  167. class={!showContact.value && 'emptyRootContainer'}
  168. style={{ minHeight: `calc(100vh - ${toTop.value}px)` }}
  169. >
  170. {/* <OSticky position="top" background="#F8F8F8"> */}
  171. <Sticky offsetTop={toTop.value} style={{ width: '100%' }}>
  172. <div class={styles.chioseWrap}>
  173. <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
  174. <div
  175. class={[styles.searchBand, styles.orchestraBand]}
  176. onClick={() => {
  177. state.showPopoverTime = true
  178. }}
  179. >
  180. <p> {forms.timeName} </p>
  181. <Icon name={state.showPopoverTime ? 'arrow-up' : 'arrow-down'} />
  182. </div>
  183. </div>
  184. <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
  185. <div
  186. class={[styles.searchBand, styles.orchestraBand]}
  187. onClick={() => {
  188. state.showPopoverOrchestra = true
  189. }}
  190. >
  191. <p> {forms.orchestraName}</p>
  192. <Icon name={state.showPopoverOrchestra ? 'arrow-up' : 'arrow-down'} />
  193. </div>
  194. </div>
  195. <div style={{ padding: '12px 13px', background: '#F8F8F8' }}>
  196. <div
  197. class={[styles.searchBand, styles.orchestraBand]}
  198. onClick={() => {
  199. state.showPopoverSubject = true
  200. }}
  201. >
  202. <p> {forms.subjectName}</p>
  203. <Icon name={state.showPopoverSubject ? 'arrow-up' : 'arrow-down'} />
  204. </div>
  205. </div>
  206. </div>
  207. </Sticky>
  208. {/* </OSticky> */}
  209. {showContact.value ? (
  210. <OFullRefresh
  211. v-model:modelValue={refreshing.value}
  212. onRefresh={onRefresh}
  213. style="min-height: 100vh;"
  214. >
  215. <List
  216. loading-text=" "
  217. // v-model:loading={loading.value}
  218. finished={finished.value}
  219. finished-text=" "
  220. onLoad={getList}
  221. >
  222. {list.value.map((item: any) => (
  223. <StudentAttItem item={item}></StudentAttItem>
  224. ))}
  225. </List>
  226. </OFullRefresh>
  227. ) : (
  228. <OEmpty tips="暂无考勤"></OEmpty>
  229. )}
  230. <Popup v-model:show={state.showPopoverTime} position="bottom" style="{ height: '30%' }">
  231. <DatePicker
  232. onCancel={() => {
  233. state.showPopoverTime = false
  234. }}
  235. onConfirm={checkTimer}
  236. v-model={state.currentDate}
  237. title="选择年月"
  238. minDate={minDate.value}
  239. maxDate={maxDate.value}
  240. columnsType={columnsType.value}
  241. />
  242. </Popup>
  243. {/* <ActionSheet
  244. v-model:show={state.showPopoverOrchestra}
  245. title="选择乐团"
  246. actions={state.actions}
  247. onSelect={checkOrchestra}
  248. ></ActionSheet>
  249. <ActionSheet
  250. style={{ height: '40%' }}
  251. close-on-click-action
  252. v-model:show={state.showPopoverSubject}
  253. title="选择声部"
  254. actions={state.subjects}
  255. onSelect={checkSubject}
  256. ></ActionSheet> */}
  257. <Popup v-model:show={state.showPopoverOrchestra} position="bottom" round>
  258. <Picker
  259. columns={state.actions}
  260. onCancel={() => (state.showPopoverOrchestra = false)}
  261. onConfirm={(val: any) => checkOrchestra(val)}
  262. columnsFieldNames={{ text: 'name', value: 'value' }}
  263. />
  264. </Popup>
  265. <Popup v-model:show={state.showPopoverSubject} position="bottom" round>
  266. <Picker
  267. columns={state.subjects}
  268. onCancel={() => (state.showPopoverSubject = false)}
  269. onConfirm={(val: any) => checkSubject(val)}
  270. columnsFieldNames={{ text: 'name', value: 'value' }}
  271. />
  272. </Popup>
  273. </div>
  274. )
  275. }
  276. })