index.tsx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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, watch, nextTick } from 'vue'
  16. import { useRoute, useRouter } from 'vue-router'
  17. import styles from './index.module.less'
  18. import iconStep from './images/icon-step.png'
  19. import iconStepCalendar from './images/icon-step-calendar.png'
  20. import request from '@/helpers/request'
  21. import OEmpty from '@/components/o-empty'
  22. import dayjs from 'dayjs'
  23. import OVideo from '@/components/o-video'
  24. import { state as globalState } from '@/state'
  25. import OFullRefresh from '@/components/o-full-refresh'
  26. export default defineComponent({
  27. name: 'orchestra-story',
  28. props: {
  29. orchestraId: {
  30. type: String,
  31. default: ''
  32. }
  33. },
  34. setup(props) {
  35. const state = reactive({
  36. isClick: false,
  37. list: [] as any,
  38. videoWidth: '100%',
  39. listState: {
  40. reshLoading: false,
  41. dataShow: true, // 判断是否有数据
  42. loading: false,
  43. finished: false,
  44. refreshing: false,
  45. height: 0 // 页面头部高度,为了处理下拉刷新用的
  46. },
  47. params: {
  48. type: null,
  49. page: 1,
  50. rows: 20
  51. }
  52. })
  53. const getList = async () => {
  54. try {
  55. if (state.isClick) return
  56. state.isClick = true
  57. const res = await request.post(`${globalState.platformApi}/orchestraStory/page`, {
  58. data: {
  59. orchestraId: props.orchestraId
  60. },
  61. hideLoading: true
  62. })
  63. state.listState.loading = false
  64. state.listState.refreshing = false
  65. const result = res.data || {}
  66. // 处理重复请求数据
  67. if (state.list.length > 0 && result.current === 1) {
  68. return
  69. }
  70. state.list = state.list.concat(result.rows || [])
  71. state.listState.finished = result.current >= result.pages
  72. state.params.page = result.current + 1
  73. state.listState.dataShow = state.list.length > 0
  74. state.isClick = false
  75. } catch {
  76. state.listState.dataShow = false
  77. state.listState.finished = true
  78. state.listState.refreshing = false
  79. state.isClick = false
  80. }
  81. }
  82. watch(
  83. () => props.orchestraId,
  84. () => {
  85. state.params.page = 1
  86. state.list = []
  87. state.listState.finished = false
  88. getList()
  89. }
  90. )
  91. const videoRef: any = ref([])
  92. const onPlay = (index: any) => {
  93. videoRef.value.forEach((item: any, child: any) => {
  94. if (child !== index) {
  95. item.onStop()
  96. }
  97. })
  98. }
  99. const swipeRef = ref([] as any)
  100. onMounted(async () => {
  101. await getList()
  102. nextTick(() => {
  103. // 为了处理在安卓手机上面关闭全屏之后样式会有问题
  104. const width = document.querySelector('.van-step__title')?.clientWidth
  105. state.videoWidth = width ? width + 'px' : '100%'
  106. })
  107. })
  108. return () => (
  109. // <OFullRefresh
  110. // v-model:modelValue={state.listState.refreshing}
  111. // onRefresh={() => {
  112. // state.params.page = 1
  113. // state.listState.refreshing = true
  114. // state.list = []
  115. // getList()
  116. // }}
  117. // style={`min-height: calc(100vh - var(--van-nav-bar-height) - var(--header-height) - ${
  118. // props.orchestraId ? '1.2rem' : ''
  119. // })`}
  120. // >
  121. <div
  122. class={[styles.orchestraStory]}
  123. style={{ overflowY: 'auto', height: !state.listState.dataShow ? '100%' : 'auto' }}
  124. >
  125. {state.listState.dataShow ? (
  126. <List
  127. // v-model:loading={state.listState.loading}
  128. finished={state.listState.finished}
  129. finishedText=" "
  130. class={[styles.liveList]}
  131. onLoad={getList}
  132. immediateCheck={false}
  133. >
  134. <Steps direction="vertical" class={[styles.storySteps, 'storyStepContainer']}>
  135. {state.list.map((item: any, index: number) => (
  136. <Step
  137. v-slots={{
  138. 'inactive-icon': () => <Image src={iconStep} class={styles.iconInactive} />,
  139. 'active-icon': () => <Image src={iconStepCalendar} class={styles.iconActive} />
  140. }}
  141. >
  142. <div class={styles.stepTimes}>
  143. <div class={styles.stepTime}>
  144. {dayjs(item.createTime).format('YYYY年MM月DD日')}
  145. </div>
  146. </div>
  147. <p class={[styles.content, 'van-multi-ellipsis--l2']}>{item.content}</p>
  148. <Swipe
  149. ref={(el: any) => (swipeRef.value[index] = el)}
  150. class={styles.storySwipe}
  151. touchable={item.type === 'VIDEO' ? false : true}
  152. >
  153. {item.attachments &&
  154. item.attachments.map((child: any, index: number) => (
  155. <SwipeItem>
  156. {item.type === 'IMAGE' && (
  157. <div
  158. class={styles.swipeImg}
  159. style={
  160. child.url
  161. ? {
  162. backgroundImage: `url(${child.url})`,
  163. backgroundSize: 'cover'
  164. }
  165. : ''
  166. }
  167. ></div>
  168. )}
  169. {item.type === 'VIDEO' && (
  170. <OVideo
  171. src={child.url}
  172. height={'100%'}
  173. style={{ width: state.videoWidth }}
  174. poster={child.coverImage}
  175. class={styles.swipeImg}
  176. ref={(el: any) => (videoRef.value[index] = el)}
  177. onPlay={() => onPlay(index)}
  178. onExitfullscreen={() => {
  179. // console.group('重新resize', swipeRef.value)
  180. // console.time('开始')
  181. nextTick(() => {
  182. setTimeout(() => {
  183. // console.time('结束')
  184. // console.groupEnd()
  185. // swipeRef.value?.resize()
  186. swipeRef.value.forEach((item: any) => {
  187. item.resize()
  188. })
  189. }, 600)
  190. })
  191. }}
  192. />
  193. )}
  194. </SwipeItem>
  195. ))}
  196. </Swipe>
  197. </Step>
  198. ))}
  199. </Steps>
  200. </List>
  201. ) : (
  202. <OEmpty btnStatus={false} tips="暂无事迹" style={{ paddingBottom: '30px' }} />
  203. )}
  204. </div>
  205. // </OFullRefresh>
  206. )
  207. }
  208. })