index.tsx 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import { defineComponent, reactive, ref } from 'vue'
  2. import { Sticky, List, Popup, Icon } from 'vant'
  3. import Search from '@/components/col-search'
  4. import request from '@/helpers/request'
  5. import Item from './item'
  6. import SelectTag from '../search/select-tag'
  7. import { useRoute, useRouter } from 'vue-router'
  8. import ColResult from '@/components/col-result'
  9. import styles from './index.module.less'
  10. import { getRandomKey, musicBuy } from '../music'
  11. import { state } from '@/state'
  12. import SelectSubject from '../search/select-subject'
  13. const noop = () => {}
  14. export default defineComponent({
  15. name: 'MusicList',
  16. props: {
  17. hideSearch: {
  18. type: Boolean,
  19. default: false
  20. },
  21. defauleParams: {
  22. type: Object,
  23. default: () => ({})
  24. },
  25. onItemClick: {
  26. type: Function,
  27. default: noop
  28. },
  29. teacherId: {
  30. type: String || Number,
  31. default: ''
  32. }
  33. },
  34. setup({ hideSearch, defauleParams, onItemClick, teacherId }, { expose }) {
  35. localStorage.setItem('behaviorId', getRandomKey())
  36. const route = useRoute()
  37. // const router = useRouter()
  38. const tempParams: any = {}
  39. if (state.version) {
  40. tempParams.version = state.version || '' // 处理ios审核版本
  41. tempParams.platform =
  42. state.platformType === 'STUDENT' ? 'ios-student' : 'ios-teacher'
  43. }
  44. const params = reactive({
  45. search: (route.query.search as string) || '',
  46. musicTagIds: route.query.tagids || '',
  47. page: 1,
  48. ...tempParams,
  49. ...defauleParams
  50. })
  51. const data = ref<any>(null)
  52. const loading = ref(false)
  53. const finished = ref(false)
  54. const isError = ref(false)
  55. const tagVisibility = ref(false)
  56. const apiSuffix = ref(
  57. state.platformType === 'STUDENT' ? '/api-student' : '/api-teacher'
  58. )
  59. const onSearch = (value: string) => {
  60. params.page = 1
  61. params.search = value
  62. data.value = null
  63. FetchList()
  64. }
  65. const FetchList = async () => {
  66. if (loading.value) {
  67. return
  68. }
  69. loading.value = true
  70. isError.value = false
  71. const tempParams = {
  72. ...params,
  73. idAndName: params.search,
  74. createBy: teacherId
  75. }
  76. if (state.platformType === 'TEACHER') {
  77. tempParams.myself = false
  78. }
  79. try {
  80. const res = await request.post(`${apiSuffix.value}/music/sheet/list`, {
  81. data: tempParams
  82. })
  83. if (data.value) {
  84. const result = (data.value?.rows || []).concat(res.data.rows || [])
  85. data.value.rows = result
  86. }
  87. data.value = data.value || res.data
  88. params.page = res.data.pageNo + 1
  89. finished.value = res.data.pageNo >= res.data.totalPage
  90. } catch (error) {
  91. isError.value = true
  92. }
  93. loading.value = false
  94. }
  95. const onComfirm = tags => {
  96. const d = Object.values(tags).flat().filter(Boolean).join(',')
  97. params.musicTagIds = d
  98. params.page = 1
  99. data.value = null
  100. FetchList()
  101. tagVisibility.value = false
  102. }
  103. const onComfirmSubject = item => {
  104. params.page = 1
  105. params.subjectIds = item.id
  106. subject.id = item.id
  107. subject.name = item.name
  108. data.value = null
  109. FetchList()
  110. subject.show = false
  111. }
  112. const subject = reactive({
  113. show: false,
  114. name: '全部',
  115. id: ''
  116. })
  117. expose({
  118. onSearch,
  119. onComfirm,
  120. onComfirmSubject
  121. })
  122. return () => (
  123. <>
  124. <List
  125. loading={loading.value}
  126. finished={finished.value}
  127. finished-text={
  128. data.value && data.value.rows.length ? '没有更多了' : ''
  129. }
  130. onLoad={FetchList}
  131. error={isError.value}
  132. >
  133. {!hideSearch && (
  134. <Sticky class={styles.sticky}>
  135. <Search
  136. showAction
  137. onSearch={onSearch}
  138. onFilter={() => (tagVisibility.value = true)}
  139. filterDot={!!params.musicTagIds}
  140. v-slots={{
  141. left: () => (
  142. <div
  143. class={styles.label}
  144. onClick={() => (subject.show = true)}
  145. >
  146. {subject.name}
  147. <Icon
  148. classPrefix="iconfont"
  149. name="down"
  150. size={12}
  151. color="#333"
  152. />
  153. </div>
  154. )
  155. }}
  156. />
  157. </Sticky>
  158. )}
  159. {data.value && data.value.rows.length
  160. ? data.value.rows.map(item => (
  161. <Item
  162. data={item}
  163. onClick={() => {
  164. if (onItemClick === noop) {
  165. musicBuy(item)
  166. } else {
  167. onItemClick?.(item)
  168. }
  169. }}
  170. />
  171. ))
  172. : !loading.value && (
  173. <ColResult
  174. tips="暂无曲目"
  175. classImgSize="SMALL"
  176. btnStatus={false}
  177. />
  178. )}
  179. </List>
  180. <Popup
  181. show={tagVisibility.value}
  182. round
  183. closeable
  184. position="bottom"
  185. style={{ height: '60%' }}
  186. teleport="body"
  187. onUpdate:show={val => (tagVisibility.value = val)}
  188. >
  189. <SelectTag
  190. onConfirm={onComfirm}
  191. onCancel={() => {}}
  192. defaultValue={route.query.tagids as string}
  193. />
  194. </Popup>
  195. {/* 声部弹框 */}
  196. <Popup
  197. show={subject.show}
  198. position="bottom"
  199. round
  200. closeable
  201. safe-area-inset-bottom
  202. onClose={() => (subject.show = false)}
  203. onClosed={() => (subject.show = false)}
  204. >
  205. <SelectSubject isReset onComfirm={onComfirmSubject} />
  206. </Popup>
  207. </>
  208. )
  209. }
  210. })