index.tsx 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. import OHeader from '@/components/o-header'
  2. import {
  3. Cell,
  4. CellGroup,
  5. Icon,
  6. Image,
  7. List,
  8. Picker,
  9. Popup,
  10. Step,
  11. Steps,
  12. Swipe,
  13. SwipeItem
  14. } from 'vant'
  15. import { defineComponent, onMounted, reactive, ref } from 'vue'
  16. import { useRoute, useRouter } from 'vue-router'
  17. import styles from './index.module.less'
  18. import iconEdit from './images/icon-edit.png'
  19. import iconStep from './images/icon-step.png'
  20. import iconStepCalendar from './images/icon-step-calendar.png'
  21. import request from '@/helpers/request'
  22. import { state as baseState } from '@/state'
  23. import OFullRefresh from '@/components/o-full-refresh'
  24. import OEmpty from '@/components/o-empty'
  25. import dayjs from 'dayjs'
  26. import OVideo from '@/components/o-video'
  27. import baseEvent from '@/base-event'
  28. export default defineComponent({
  29. name: 'orchestra-story',
  30. setup() {
  31. const route = useRoute()
  32. const router = useRouter()
  33. const state = reactive({
  34. orchestraStatus: false,
  35. orchestraList: [] as any,
  36. selectOrchestra: {} as any,
  37. isClick: false,
  38. list: [] as any,
  39. listState: {
  40. dataShow: true, // 判断是否有数据
  41. loading: false,
  42. finished: false,
  43. refreshing: false,
  44. height: 0 // 页面头部高度,为了处理下拉刷新用的
  45. },
  46. params: {
  47. type: null,
  48. page: 1,
  49. rows: 20
  50. }
  51. })
  52. // 获取乐团列表
  53. const getOrchestras = async () => {
  54. try {
  55. const { data } = await request.post('/api-school/orchestra/page', {
  56. data: {
  57. page: 1,
  58. rows: 100,
  59. schoolId: baseState.user.data.school.id,
  60. status: 'DONE'
  61. }
  62. })
  63. const temps = data.rows || []
  64. const s = [] as any
  65. temps.forEach((item: any) => {
  66. s.push({
  67. text: item.name,
  68. value: item.id
  69. })
  70. })
  71. state.orchestraList = [...s]
  72. // 判断是否有乐团
  73. if (s.length > 0) {
  74. const orchestraId = sessionStorage.getItem('orchestraStoryId')
  75. if (orchestraId) {
  76. const item = s.find((child: any) => child.value === orchestraId)
  77. state.selectOrchestra = item || s[0]
  78. } else {
  79. state.selectOrchestra = s[0]
  80. }
  81. getList()
  82. }
  83. } catch {
  84. //
  85. }
  86. }
  87. const getList = async () => {
  88. try {
  89. if (state.isClick) return
  90. state.isClick = true
  91. const res = await request.post('/api-school/orchestraStory/page', {
  92. data: {
  93. orchestraId: state.selectOrchestra.value
  94. }
  95. })
  96. state.listState.loading = false
  97. state.listState.refreshing = false
  98. const result = res.data || {}
  99. // 处理重复请求数据
  100. if (state.list.length > 0 && result.current === 1) {
  101. return
  102. }
  103. state.list = state.list.concat(result.rows || [])
  104. state.listState.finished = result.current >= result.pages
  105. state.params.page = result.current + 1
  106. state.listState.dataShow = state.list.length > 0
  107. state.isClick = false
  108. } catch {
  109. state.listState.dataShow = false
  110. state.listState.finished = true
  111. state.listState.refreshing = false
  112. state.isClick = false
  113. }
  114. }
  115. const onRefresh = () => {
  116. state.params.page = 1
  117. state.list = []
  118. state.listState.dataShow = true // 判断是否有数据
  119. state.listState.loading = false
  120. state.listState.finished = false
  121. getList()
  122. }
  123. const onEdit = async (item: any) => {
  124. router.push({
  125. path: '/story-operation',
  126. query: {
  127. id: item.id,
  128. orchestraId: state.selectOrchestra.value
  129. }
  130. })
  131. }
  132. const videoRef: any = ref([])
  133. const onPlay = (index: any) => {
  134. videoRef.value.forEach((item: any, child: any) => {
  135. if (child !== index) {
  136. item.onStop()
  137. }
  138. })
  139. }
  140. onMounted(async () => {
  141. getOrchestras()
  142. })
  143. return () => (
  144. <div class={[styles.orchestraStory, !state.listState.dataShow && 'emptyRootContainer']}>
  145. <OHeader>
  146. {{
  147. right: () => (
  148. <span
  149. style={{ color: 'var(--van-primary)' }}
  150. onClick={() => {
  151. router.push('/story-operation')
  152. }}
  153. >
  154. 添加
  155. </span>
  156. )
  157. }}
  158. </OHeader>
  159. {state.orchestraList.length > 0 && (
  160. <div style={{ width: '100%' }}>
  161. <CellGroup inset class={styles.cellGroup}>
  162. <Cell
  163. title={state.selectOrchestra.text || ' '}
  164. isLink
  165. center
  166. onClick={() => (state.orchestraStatus = true)}
  167. ></Cell>
  168. </CellGroup>
  169. </div>
  170. )}
  171. {state.listState.dataShow ? (
  172. // <OFullRefresh
  173. // v-model:modelValue={state.listState.refreshing}
  174. // onRefresh={onRefresh}
  175. // style={{
  176. // minHeight: `calc(100vh - ${state.listState.height}px)`
  177. // }}
  178. // >
  179. <List
  180. // v-model:loading={state.listState.loading}
  181. finished={state.listState.finished}
  182. finishedText=" "
  183. class={[styles.liveList]}
  184. onLoad={getList}
  185. immediateCheck={false}
  186. >
  187. <Steps direction="vertical" class={styles.storySteps}>
  188. {state.list.map((item: any, index: number) => (
  189. <Step
  190. v-slots={{
  191. 'inactive-icon': () => <Image src={iconStep} class={styles.iconInactive} />,
  192. 'active-icon': () => <Image src={iconStepCalendar} class={styles.iconActive} />
  193. }}
  194. >
  195. <div class={styles.stepTimes}>
  196. <div class={styles.stepTime}>
  197. {dayjs(item.createTime).format('YYYY年MM月DD日')}
  198. </div>
  199. <span class={styles.stepEdit} onClick={() => onEdit(item)}>
  200. <Icon name={iconEdit} />
  201. 编辑
  202. </span>
  203. </div>
  204. <p class={[styles.content, 'van-multi-ellipsis--l2']}>{item.content}</p>
  205. <Swipe class={styles.storySwipe}>
  206. {item.attachments &&
  207. item.attachments.map((child: any) => (
  208. <SwipeItem>
  209. {item.type === 'IMAGE' && (
  210. <div
  211. class={styles.swipeImg}
  212. style={
  213. child.url
  214. ? {
  215. backgroundImage: `url(${child.url})`,
  216. backgroundSize: 'cover'
  217. }
  218. : ''
  219. }
  220. ></div>
  221. )}
  222. {item.type === 'VIDEO' && (
  223. <OVideo
  224. // ref={videoRef}
  225. ref={(el: any) => (videoRef.value[index] = el)}
  226. src={child.url}
  227. height={'100%'}
  228. poster={child.coverImage}
  229. class={styles.swipeImg}
  230. onPlay={() => onPlay(index)}
  231. />
  232. )}
  233. </SwipeItem>
  234. ))}
  235. </Swipe>
  236. </Step>
  237. ))}
  238. </Steps>
  239. </List>
  240. ) : (
  241. <OEmpty btnStatus={false} tips="暂无事迹" />
  242. )}
  243. <Popup v-model:show={state.orchestraStatus} position="bottom" round>
  244. <Picker
  245. columns={state.orchestraList}
  246. onCancel={() => (state.orchestraStatus = false)}
  247. onConfirm={(val: any) => {
  248. state.selectOrchestra = val.selectedOptions[0]
  249. state.orchestraStatus = false
  250. sessionStorage.setItem('orchestraStoryId', state.selectOrchestra.value)
  251. onRefresh()
  252. }}
  253. />
  254. </Popup>
  255. </div>
  256. )
  257. }
  258. })