list.tsx 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. import request from '@/helpers/request'
  2. import {
  3. Button,
  4. Cell,
  5. CellGroup,
  6. DatePicker,
  7. DatePickerColumnType,
  8. List,
  9. Picker,
  10. Popup
  11. } from 'vant'
  12. import { defineComponent, onMounted, reactive, ref } from 'vue'
  13. import styles from '../index.module.less'
  14. import { state as baseState } from '@/state'
  15. import iconOrchestra from '@/views/mine-orchestra/images/icon-or.png'
  16. import OEmpty from '@/components/o-empty'
  17. import { useRouter } from 'vue-router'
  18. import dayjs from 'dayjs'
  19. import { formatterDatePicker } from '@/helpers/utils'
  20. import OFullRefresh from '@/components/o-full-refresh'
  21. export default defineComponent({
  22. name: 'train-list',
  23. props: {
  24. type: {
  25. type: String,
  26. default: 'WEEKLY'
  27. },
  28. orchestraList: {
  29. type: Array,
  30. default: () => []
  31. }
  32. },
  33. setup(props) {
  34. const columnsType = ref<DatePickerColumnType[]>(['year', 'month'])
  35. const router = useRouter()
  36. const state = reactive({
  37. showPopoverTime: false,
  38. timeName: dayjs().format('YYYY') + '年' + dayjs().format('MM') + '月',
  39. currentDate: [dayjs().format('YYYY'), dayjs().format('MM')],
  40. orchestraStatus: false,
  41. selectOrchestra: {} as any,
  42. isClick: false,
  43. list: [] as any,
  44. listState: {
  45. dataShow: true, // 判断是否有数据
  46. loading: false,
  47. finished: false,
  48. refreshing: false,
  49. height: 0 // 页面头部高度,为了处理下拉刷新用的
  50. },
  51. params: {
  52. page: 1,
  53. rows: 20
  54. }
  55. })
  56. const getList = async () => {
  57. try {
  58. if (state.isClick) return
  59. state.isClick = true
  60. const dateRange = dayjs(state.currentDate[0] + '-' + state.currentDate[1] + '01')
  61. const startTime = dateRange.startOf('month').format('YYYY-MM-DD')
  62. const endTime = dateRange.endOf('month').format('YYYY-MM-DD')
  63. const { data } = await request.post('/api-school/orchestraReport/page', {
  64. data: {
  65. reportType: props.type,
  66. page: state.params.page,
  67. rows: state.params.rows,
  68. orchestraId: state.selectOrchestra.value,
  69. startTime,
  70. endTime
  71. }
  72. })
  73. state.listState.loading = false
  74. state.listState.refreshing = false
  75. // 处理重复请求数据
  76. if (state.list.length > 0 && data.current === 1) {
  77. return
  78. }
  79. state.list = state.list.concat(data.rows || [])
  80. state.listState.finished = data.current >= data.pages
  81. state.params.page = data.current + 1
  82. state.listState.dataShow = state.list.length > 0
  83. state.isClick = false
  84. } catch {
  85. state.listState.dataShow = false
  86. state.listState.finished = true
  87. state.listState.refreshing = false
  88. state.isClick = false
  89. }
  90. }
  91. const onRefresh = () => {
  92. state.params.page = 1
  93. state.list = []
  94. state.listState.dataShow = true // 判断是否有数据
  95. state.listState.loading = false
  96. state.listState.finished = false
  97. getList()
  98. }
  99. const onDetail = (item: any) => {
  100. const path = props.type === 'WEEKLY' ? '/train-week-report' : '/train-month-report'
  101. router.push({
  102. path,
  103. query: {
  104. id: item.id
  105. }
  106. })
  107. }
  108. const checkTimer = (val: any) => {
  109. state.timeName = val.selectedValues[0] + '年' + val.selectedValues[1] + '月'
  110. state.showPopoverTime = false
  111. onRefresh()
  112. }
  113. onMounted(async () => {
  114. try {
  115. // 判断是否有乐团
  116. if (props.orchestraList.length > 0) {
  117. // const orchestraId = sessionStorage.getItem('orchestraStoryId')
  118. // if (orchestraId) {
  119. // const item = props.orchestraList.find((child: any) => child.value === orchestraId)
  120. // state.selectOrchestra = item || props.orchestraList[0]
  121. // } else {
  122. state.selectOrchestra = props.orchestraList[0]
  123. // }
  124. }
  125. await getList()
  126. } catch {
  127. //
  128. }
  129. })
  130. return () => (
  131. <div
  132. style={{
  133. minHeight: 'calc(100vh - var(--van-tabs-line-height))',
  134. overflow: 'hidden'
  135. }}
  136. >
  137. <div class={'searchGroup'}>
  138. <div
  139. class={['searchItem', state.showPopoverTime && 'searchItem-active']}
  140. onClick={() => {
  141. state.showPopoverTime = true
  142. }}
  143. >
  144. {state.timeName}
  145. <i class={'arrow'}></i>
  146. </div>
  147. <div
  148. class={['searchItem', state.orchestraStatus && 'searchItem-active']}
  149. onClick={() => {
  150. state.orchestraStatus = true
  151. }}
  152. >
  153. <span>{state.selectOrchestra.text || ' '}</span>
  154. <i class={'arrow'}></i>
  155. </div>
  156. </div>
  157. <div
  158. style={{
  159. overflowY: 'auto',
  160. height: 'calc(100vh - var(--van-tabs-line-height) - 1.17333rem)'
  161. }}
  162. >
  163. {state.listState.dataShow ? (
  164. <OFullRefresh
  165. v-model:modelValue={state.listState.refreshing}
  166. onRefresh={onRefresh}
  167. style={{
  168. minHeight: 'calc(100vh - var(--van-tabs-line-height) - 1.17333rem)'
  169. }}
  170. >
  171. <List
  172. // v-model:loading={state.listState.loading}
  173. finished={state.listState.finished}
  174. finishedText=" "
  175. style={{
  176. overflow: 'hidden'
  177. }}
  178. onLoad={getList}
  179. immediateCheck={false}
  180. >
  181. {state.list.map((item: any) => (
  182. <Cell center class={styles.reportList}>
  183. {{
  184. title: () => <div>{item.orchestraName}</div>,
  185. value: () => (
  186. <Button type="primary" round size="small" onClick={() => onDetail(item)}>
  187. 查看报告
  188. </Button>
  189. ),
  190. label: () =>
  191. props.type === 'WEEKLY' ? (
  192. <div class={styles.time}>
  193. {item.startTime}~{item.endTime}
  194. </div>
  195. ) : (
  196. <div class={styles.time}>{item.monthlyTime}</div>
  197. )
  198. }}
  199. </Cell>
  200. ))}
  201. </List>
  202. </OFullRefresh>
  203. ) : (
  204. <OEmpty btnStatus={false} tips="暂无训练报告" />
  205. )}
  206. </div>
  207. <Popup
  208. v-model:show={state.showPopoverTime}
  209. position="bottom"
  210. round
  211. teleport={'body'}
  212. class={'popupBottomSearch'}
  213. >
  214. <DatePicker
  215. onCancel={() => {
  216. state.showPopoverTime = false
  217. }}
  218. onConfirm={checkTimer}
  219. v-model={state.currentDate}
  220. formatter={formatterDatePicker}
  221. columnsType={columnsType.value}
  222. />
  223. </Popup>
  224. <Popup
  225. v-model:show={state.orchestraStatus}
  226. position="bottom"
  227. round
  228. class={'popupBottomSearch'}
  229. teleport="body"
  230. >
  231. <Picker
  232. columns={props.orchestraList as any}
  233. onCancel={() => (state.orchestraStatus = false)}
  234. onConfirm={(val: any) => {
  235. state.selectOrchestra = val.selectedOptions[0]
  236. state.orchestraStatus = false
  237. onRefresh()
  238. }}
  239. />
  240. </Popup>
  241. </div>
  242. )
  243. }
  244. })