index.tsx 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. import { defineComponent, reactive, ref } from 'vue'
  2. import { Sticky, List, Popup, Icon, Tabs, Tab } 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 { state as baseState } from '@/state'
  11. import SelectSubject from '../search/select-subject'
  12. import { SubjectEnum, useSubjectId } from '@/helpers/hooks'
  13. import MusicGrid from '../component/music-grid'
  14. import { useAsyncState } from '@vueuse/core'
  15. import ColHeader from '@/components/col-header'
  16. import TheSticky from '@/components/the-sticky'
  17. export default defineComponent({
  18. name: 'Album',
  19. props: {
  20. hideSearch: {
  21. type: Boolean,
  22. default: false
  23. },
  24. defauleParams: {
  25. type: Object,
  26. default: () => ({})
  27. }
  28. },
  29. setup({ hideSearch, defauleParams }, { expose }) {
  30. const { isLoading, state } = useAsyncState(
  31. request(baseState.platformApi + '/MusicTag/tree', {
  32. params: {
  33. type: 'ALBUM'
  34. }
  35. }),
  36. null
  37. )
  38. const teacherDetaultSubject = ref({
  39. id: '',
  40. name: ''
  41. })
  42. if (baseState.platformType === 'TEACHER') {
  43. const users = baseState.user.data
  44. teacherDetaultSubject.value = {
  45. name: users.defaultSubjectName || '全部声部',
  46. id: users.defaultSubject || ''
  47. }
  48. } else {
  49. const subjects: any = useSubjectId(SubjectEnum.SEARCH)
  50. // 判断是否已有数据
  51. if (!subjects.id) {
  52. const users = baseState.user.data
  53. const subjectId = users.subjectId
  54. ? Number(users.subjectId.split(',')[0])
  55. : ''
  56. const subjectName = users.subjectName
  57. ? users.subjectName.split(',')[0]
  58. : ''
  59. if (subjectId) {
  60. useSubjectId(
  61. SubjectEnum.SEARCH,
  62. JSON.stringify({
  63. id: subjectId,
  64. name: subjectName
  65. }),
  66. 'set'
  67. )
  68. }
  69. }
  70. }
  71. const router = useRouter()
  72. const route = useRoute()
  73. const tempParams: any = {}
  74. if (baseState.version) {
  75. tempParams.version = baseState.version || '' // 处理ios审核版本
  76. tempParams.platform =
  77. baseState.platformType === 'STUDENT' ? 'ios-student' : 'ios-teacher'
  78. }
  79. tempParams.myself = false
  80. if (!hideSearch) {
  81. if (baseState.platformType === 'TEACHER') {
  82. tempParams.subjectIds = teacherDetaultSubject.value.id
  83. } else {
  84. const getSubject: any = useSubjectId(SubjectEnum.SEARCH)
  85. tempParams.subjectIds = getSubject.id
  86. }
  87. }
  88. const params = reactive({
  89. search: (route.query.search as string) || '',
  90. albumTagIds: route.query.tagids || '',
  91. page: 1,
  92. ...defauleParams,
  93. ...tempParams
  94. })
  95. const data = ref<any>(null)
  96. const loading = ref(false)
  97. const finished = ref(false)
  98. const isError = ref(false)
  99. const tagVisibility = ref(false)
  100. const onSearch = (value: string) => {
  101. params.page = 1
  102. params.search = value
  103. data.value = null
  104. FetchList()
  105. }
  106. const FetchList = async () => {
  107. if (loading.value) {
  108. return
  109. }
  110. loading.value = true
  111. isError.value = false
  112. try {
  113. const res = await request.post('/music/album/list', {
  114. prefix:
  115. baseState.platformType === 'TEACHER'
  116. ? '/api-teacher'
  117. : '/api-student',
  118. data: {
  119. ...params,
  120. idAndName: params.search
  121. }
  122. })
  123. if (data.value) {
  124. const result = (data.value?.rows || []).concat(res.data.rows || [])
  125. data.value.rows = result
  126. }
  127. data.value = data.value || res.data
  128. params.page = res.data.pageNo + 1
  129. finished.value = res.data.pageNo >= res.data.totalPage
  130. } catch (error) {
  131. isError.value = true
  132. }
  133. loading.value = false
  134. }
  135. // 设置默认声部
  136. const setDefaultSubject = async (subjectId: any) => {
  137. try {
  138. await request.post('/api-teacher/teacher/defaultSubject', {
  139. params: {
  140. subjectId
  141. }
  142. })
  143. } catch {
  144. //
  145. }
  146. }
  147. const onComfirm = tags => {
  148. const d = Object.values(tags).flat().filter(Boolean).join(',')
  149. params.albumTagIds = d
  150. params.page = 1
  151. data.value = null
  152. FetchList()
  153. tagVisibility.value = false
  154. }
  155. const onComfirmSubject = item => {
  156. params.page = 1
  157. params.subjectIds = item.id
  158. data.value = null
  159. if (baseState.platformType === 'TEACHER') {
  160. teacherDetaultSubject.value = {
  161. name: item.name,
  162. id: item.id
  163. }
  164. setDefaultSubject(item.id)
  165. } else {
  166. subject.id = item.id
  167. subject.name = item.name
  168. useSubjectId(
  169. SubjectEnum.SEARCH,
  170. JSON.stringify({
  171. id: item.id,
  172. name: item.name
  173. }),
  174. 'set'
  175. )
  176. }
  177. FetchList()
  178. subject.show = false
  179. }
  180. expose({
  181. onSearch,
  182. onComfirm,
  183. onComfirmSubject
  184. })
  185. const getSubject: any = useSubjectId(SubjectEnum.SEARCH)
  186. const subject = reactive({
  187. show: false,
  188. name: getSubject.name || '全部声部',
  189. id: getSubject.id || ''
  190. })
  191. return () => {
  192. const tagList = ((state.value && state.value.data) as any) || []
  193. return (
  194. <>
  195. <List
  196. loading={loading.value}
  197. finished={finished.value}
  198. finished-text={
  199. data.value && data.value.rows.length ? '没有更多了' : ''
  200. }
  201. onLoad={FetchList}
  202. error={isError.value}
  203. >
  204. {!hideSearch && (
  205. <TheSticky class={styles.sticky}>
  206. <ColHeader border={false} />
  207. <Search
  208. modelValue={params.search}
  209. onSearch={onSearch}
  210. placeholder="请输入专辑名称 "
  211. v-slots={{
  212. left: () => (
  213. <div
  214. class={styles.label}
  215. onClick={() => (subject.show = true)}
  216. >
  217. {baseState.platformType === 'TEACHER'
  218. ? teacherDetaultSubject.value.name
  219. : subject.name}
  220. <Icon
  221. classPrefix="iconfont"
  222. name="down"
  223. size={12}
  224. color="#333"
  225. />
  226. </div>
  227. )
  228. }}
  229. />
  230. <Tabs
  231. shrink
  232. class={styles.tagTabs}
  233. lineHeight={0}
  234. onClick-tab={(obj: any) => {
  235. params.albumTagIds = obj.name
  236. data.value = null
  237. params.page = 1
  238. FetchList()
  239. }}
  240. >
  241. <Tab title="全部" name=""></Tab>
  242. {tagList.map((tag: any) => (
  243. <Tab title={tag.name} name={tag.id}></Tab>
  244. ))}
  245. </Tabs>
  246. </TheSticky>
  247. )}
  248. {data.value && data.value.rows.length ? (
  249. <div class={styles.musicGrid}>
  250. <MusicGrid
  251. list={data.value.rows}
  252. onGoto={(n: any) => {
  253. router.push({
  254. name: 'music-album-detail',
  255. params: {
  256. id: n.id
  257. }
  258. })
  259. }}
  260. />
  261. </div>
  262. ) : (
  263. // data.value.rows.map(item => <Item data={item} />)
  264. !loading.value && (
  265. <ColResult
  266. tips="暂无专辑"
  267. classImgSize="SMALL"
  268. btnStatus={false}
  269. />
  270. )
  271. )}
  272. </List>
  273. {/* <Popup
  274. show={tagVisibility.value}
  275. round
  276. closeable
  277. position="bottom"
  278. style={{ height: '60%' }}
  279. teleport="body"
  280. onUpdate:show={val => (tagVisibility.value = val)}
  281. >
  282. <SelectTag
  283. defaultValue={route.query.tagids as string}
  284. onConfirm={onComfirm}
  285. onCancel={() => {}}
  286. />
  287. </Popup> */}
  288. <Popup
  289. show={subject.show}
  290. position="bottom"
  291. round
  292. closeable
  293. safe-area-inset-bottom
  294. onClose={() => (subject.show = false)}
  295. onClosed={() => (subject.show = false)}
  296. >
  297. <SelectSubject
  298. type="ALBUM"
  299. searchParams={
  300. baseState.platformType === 'TEACHER'
  301. ? teacherDetaultSubject.value
  302. : subject
  303. }
  304. onComfirm={onComfirmSubject}
  305. />
  306. </Popup>
  307. </>
  308. )
  309. }
  310. }
  311. })