import { computed, defineComponent, nextTick, onMounted, reactive, ref } from 'vue' import { useRoute, useRouter } from 'vue-router' import request from '@/helpers/request' import ColHeader from '@/components/col-header' import { postMessage } from '@/helpers/native-message' import { Button, Dialog, Icon, Image, List, NavBar, Popup, Sticky } from 'vant' // import classNames from 'classnames' // import Footer from '../album/footer' // import FavoriteIcon from '../album/favorite.svg' // import FavoritedIcon from '../album/favorited.svg' import styles from './index.module.less' // import Item from '../list/item' import { useRect } from '@vant/use' import { useEventListener, useWindowScroll } from '@vueuse/core' import { getRandomKey, musicBuy } from '../music' import { state } from '@/state' import IconPan from './pan.png' import oStart from './oStart.png' import iStart from './iStart.png' import Title from '../component/title' import Song from '../component/song' import ColResult from '@/components/col-result' import MusicGrid from '../component/music-grid' import { useEventTracking } from '@/helpers/hooks' import ColSticky from '@/components/col-sticky' import { moneyFormat } from '@/helpers/utils' import { orderStatus } from '@/views/order-detail/orderStatus' import iconShare from '../album/icon_share.svg' import iconShare2 from '../album/icon_share2.svg' import ColShare from '@/components/col-share' const noop = () => {} export default defineComponent({ name: 'AlbumDetail', props: { onItemClick: { type: Function, default: noop } }, setup({ onItemClick }) { localStorage.setItem('behaviorId', getRandomKey()) const router = useRouter() const route = useRoute() const params = reactive({ search: '', relatedNum: 6, //相关专辑数 page: 1, rows: 200 }) const albumDetail = ref(null) // const data = ref(null) const rows = ref([]) const loading = ref(false) const aId = Number(route.query.activityId) || 0 const studentActivityId = ref(aId) // const finished = ref(false) const isError = ref(false) const favorited = ref(0) const albumFavoriteCount = ref(0) const headers = ref(null) const background = ref('rgba(55, 205, 177, 0)') const color = ref('#fff') const heightInfo = ref('auto') const FetchList = async (id?: any) => { if (loading.value) { return } loading.value = true isError.value = false try { const res = await request.post('/music/album/detail', { prefix: state.platformType === 'TEACHER' ? '/api-teacher' : '/api-student', data: { id: id || route.params.id, ...params } }) const { musicSheetList, ...rest } = res.data rows.value = [...musicSheetList.rows] const musicTagNames = rest?.musicTagNames ? rest?.musicTagNames?.split(',') : [] albumDetail.value = { ...rest, musicTagNames } favorited.value = rest.favorite albumFavoriteCount.value = rest.albumFavoriteCount } catch (error) { isError.value = true } loading.value = false } const favoriteLoading = ref(false) onMounted(() => { FetchList() useEventListener(document, 'scroll', evt => { const { y } = useWindowScroll() if (y.value > 20) { background.value = `rgba(255, 255, 255)` color.value = 'black' postMessage({ api: 'backIconChange', content: { iconStyle: 'black' } }) } else { background.value = 'transparent' color.value = '#fff' postMessage({ api: 'backIconChange', content: { iconStyle: 'white' } }) } }) useEventTracking('专辑') }) const toggleFavorite = async (id: number) => { favoriteLoading.value = true try { await request.post('/music/album/favorite/' + id, { prefix: state.platformType === 'TEACHER' ? '/api-teacher' : '/api-student' }) favorited.value = favorited.value === 1 ? 0 : 1 albumFavoriteCount.value += favorited.value ? 1 : -1 } catch (error) {} favoriteLoading.value = false } const onBuy = async () => { const album = albumDetail.value orderStatus.orderObject.orderType = 'ALBUM' orderStatus.orderObject.orderName = album.albumName orderStatus.orderObject.orderDesc = album.albumName orderStatus.orderObject.actualPrice = album.albumPrice orderStatus.orderObject.recomUserId = route.query.recomUserId || 0 orderStatus.orderObject.activityId = route.query.activityId || 0 orderStatus.orderObject.orderNo = '' orderStatus.orderObject.orderList = [ { orderType: 'ALBUM', goodsName: album.albumName, recomUserId: route.query.recomUserId || 0, price: album.albumPrice, ...album } ] const res = await request.post('/api-student/userOrder/getPendingOrder', { data: { goodType: 'ALBUM', bizId: album.id } }) const result = res.data if (result) { Dialog.confirm({ title: '提示', message: '您有一个未支付的订单,是否继续支付?', confirmButtonColor: '#269a93', cancelButtonText: '取消订单', confirmButtonText: '继续支付' }) .then(async () => { orderStatus.orderObject.orderNo = result.orderNo orderStatus.orderObject.actualPrice = result.actualPrice orderStatus.orderObject.discountPrice = result.discountPrice routerTo() }) .catch(() => { Dialog.close() // 只用取消订单,不用做其它处理 cancelPayment(result.orderNo) }) } else { routerTo() } // this.$router.push({ // path: '/orderDetail', // query: { // orderType: 'VIP' // } // }) } const routerTo = () => { const album = albumDetail.value router.push({ path: '/orderDetail', query: { orderType: 'ALBUM', album: album.id } }) } const cancelPayment = async (orderNo: string) => { try { await request.post('/api-student/userOrder/orderCancel', { data: { orderNo } }) // this.routerTo() } catch {} } const shareStatus = ref(false) const shareUrl = ref('') const shareDiscount = ref(0) const onShare = async () => { const userId = state.user.data.userId const id = route.params.id let activityId = 0 console.log(state.user, userId) if (state.platformType === 'TEACHER') { const res = await request.post('/api-teacher/open/vipProfit', { data: { bizId: id, userId } }) // 如果有会员则显示 if (buyVip.value) { activityId = res.data.activityId || 0 shareDiscount.value = res.data.discount || 0 } } shareUrl.value = `${location.origin}/teacher#/shareAblum?id=${id}&recomUserId=${userId}&activityId=${activityId}&userType=${state.platformType}` console.log(shareUrl.value, 'shareUrl') shareStatus.value = true } const buyVip = computed(() => { const album = albumDetail.value?.musicPaymentTypes return album && album.includes('VIP') }) return () => { return (
{ nextTick(() => { const { height } = useRect(headers as any) heightInfo.value = height }) }} v-slots={{ right: () => (
分享
) }} />
{albumDetail.value?.paymentType === 'CHARGE' && ( 付费 )}
{albumDetail.value?.albumName}
{albumDetail.value?.musicTagNames?.map((tag: any) => ( {tag} ))}
{albumDetail.value?.albumDesc}
共{albumDetail.value?.musicSheetCount}首曲目
toggleFavorite(albumDetail.value?.id)} > {albumFavoriteCount.value}人收藏
{albumDetail.value?.paymentType === 'CHARGE' && albumDetail.value?.orderStatus !== 'PAID' && (
此专辑为付费专辑,购买即可自由练习该专辑 ¥{moneyFormat(albumDetail.value?.albumPrice)}
)}
<Song list={rows.value} onDetail={(item: any) => { if (onItemClick === noop || !onItemClick) { router.push({ path: '/music-detail', query: { id: item.id, albumId: route.params.id } }) } else { onItemClick(item) } }} /> {rows.value && rows.value.length <= 0 && ( <ColResult btnStatus={false} tips="暂无曲目" /> )} </div> {albumDetail.value?.relatedMusicAlbum && albumDetail.value?.relatedMusicAlbum.length > 0 && ( <> <Title title="相关专辑" onMore={() => { router.push({ path: '/music-album' }) }} /> <MusicGrid list={albumDetail.value?.relatedMusicAlbum} onGoto={(n: any) => { router .push({ name: 'music-album-detail', params: { id: n.id } }) .then(() => { FetchList(n.id) window.scrollTo(0, 0) }) }} /> </> )} </div> {/* 判断是否是收费 是否是已经购买 */} {albumDetail.value?.paymentType === 'CHARGE' && albumDetail.value?.orderStatus !== 'PAID' && ( <ColSticky position="bottom" background="white"> <div class={[ 'btnGroup', buyVip.value && !state.user.data.isVip && 'btnMore' ]} style={{ paddingTop: '12px' }} > <Button block round type="primary" style={{ fontSize: '16px' }} onClick={onBuy} > 购买专辑 </Button> {buyVip.value && !state.user.data.isVip && ( <Button block round type="primary" style={{ fontSize: '16px' }} onClick={() => { router.push({ path: '/memberCenter', query: { ...route.query } }) }} > {studentActivityId.value > 0 && ( <div class={[styles.buttonDiscount]}>专属优惠</div> )} 开通会员 </Button> )} </div> </ColSticky> )} <Popup v-model:show={shareStatus.value} style={{ background: 'transparent' }} > <ColShare teacherId={state.user.data.userId} shareUrl={shareUrl.value} shareType="album" shareLength={1} > <div class={styles.shareVip}> {shareDiscount.value === 1 && ( <div class={styles.tagDiscount}>专属优惠</div> )} <img class={styles.icon} src={albumDetail.value?.albumCoverUrl} /> <div class={styles.info}> <h4 class="van-multi-ellipsis--l2"> {albumDetail.value?.albumName} </h4> <p class={['van-multi-ellipsis--l3']} style={{ height: '48px', lineHeight: '16px' }} > {albumDetail.value?.albumDesc} </p> </div> </div> </ColShare> </Popup> </div> ) } } })