|
@@ -0,0 +1,416 @@
|
|
|
+import { defineComponent, onMounted, reactive, ref } from 'vue'
|
|
|
+import { Image, Tabs, Tab, List, Button, Popup, Dialog } from 'vant'
|
|
|
+import styles from './index.module.less'
|
|
|
+import TheSticky from '@/components/the-sticky'
|
|
|
+import ColHeader from '@/components/col-header'
|
|
|
+import { useWindowScroll, useEventListener } from '@vueuse/core'
|
|
|
+import request from '@/helpers/request'
|
|
|
+import iconMenu from './images/icon-menu.png'
|
|
|
+import iconRightTop from './images/icon-right-top.png'
|
|
|
+import { state as baseState } from '@/state'
|
|
|
+import Song from '../component/song'
|
|
|
+import { useRouter } from 'vue-router'
|
|
|
+import ColResult from '@/components/col-result'
|
|
|
+import { moneyFormat } from '@/helpers/utils'
|
|
|
+import { orderStatus } from '@/views/order-detail/orderStatus'
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'train-tool',
|
|
|
+ setup() {
|
|
|
+ const router = useRouter()
|
|
|
+ const background = ref<string>('rgba(55, 205, 177, 0)')
|
|
|
+ const color = ref<string>('#fff')
|
|
|
+ const state = reactive({
|
|
|
+ details: {} as any,
|
|
|
+ activeTab: 'SUBJECT',
|
|
|
+ loading: false,
|
|
|
+ finished: false,
|
|
|
+ isError: false,
|
|
|
+ list: [] as any,
|
|
|
+ popupStatus: false,
|
|
|
+ selectMember: {} as any, // 购买的月份
|
|
|
+ buyList: [
|
|
|
+ {
|
|
|
+ purchaseCycle: 6,
|
|
|
+ salePrice: 0,
|
|
|
+ costPrice: 0,
|
|
|
+ status: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ purchaseCycle: 12,
|
|
|
+ salePrice: 0,
|
|
|
+ costPrice: 0,
|
|
|
+ status: false
|
|
|
+ },
|
|
|
+ {
|
|
|
+ purchaseCycle: 18,
|
|
|
+ salePrice: 0,
|
|
|
+ costPrice: 0,
|
|
|
+ status: false
|
|
|
+ },
|
|
|
+ {
|
|
|
+ purchaseCycle: 24,
|
|
|
+ salePrice: 0,
|
|
|
+ costPrice: 0,
|
|
|
+ status: false
|
|
|
+ },
|
|
|
+ {
|
|
|
+ purchaseCycle: 30,
|
|
|
+ salePrice: 0,
|
|
|
+ costPrice: 0,
|
|
|
+ status: false
|
|
|
+ },
|
|
|
+ {
|
|
|
+ purchaseCycle: 36,
|
|
|
+ salePrice: 0,
|
|
|
+ costPrice: 0,
|
|
|
+ status: false
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ })
|
|
|
+ const params = reactive({
|
|
|
+ page: 1,
|
|
|
+ rows: 20
|
|
|
+ })
|
|
|
+ const apiSuffix = ref(
|
|
|
+ baseState.platformType === 'STUDENT' ? '/api-student' : '/api-teacher'
|
|
|
+ )
|
|
|
+
|
|
|
+ const getDetails = async () => {
|
|
|
+ try {
|
|
|
+ const { data } = await request.post(
|
|
|
+ apiSuffix.value + '/userTenantAlbumRecord/detail'
|
|
|
+ )
|
|
|
+ state.details = data || {}
|
|
|
+
|
|
|
+ state.buyList.forEach((item: any, index: number) => {
|
|
|
+ item.salePrice = (index + 1) * data.salePrice
|
|
|
+ item.costPrice = (index + 1) * data.costPrice
|
|
|
+ })
|
|
|
+
|
|
|
+ state.selectMember = {
|
|
|
+ ...state.buyList[0]
|
|
|
+ }
|
|
|
+ } catch {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const FetchList = async () => {
|
|
|
+ if (state.loading) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ state.loading = true
|
|
|
+ state.isError = false
|
|
|
+ const tempParams = {
|
|
|
+ albumId: state.details.id || null,
|
|
|
+ subjectType: state.activeTab,
|
|
|
+ ...params
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ const { data } = await request.post(
|
|
|
+ `${apiSuffix.value}/tenantAlbumMusic/page`,
|
|
|
+ {
|
|
|
+ data: tempParams
|
|
|
+ }
|
|
|
+ )
|
|
|
+ if (state.list.length > 0 && data.pageNo === 1) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ state.list = state.list.concat(data.rows || [])
|
|
|
+ params.page = data.pageNo + 1
|
|
|
+ // showContact.value = state.list.length > 0
|
|
|
+ state.loading = false
|
|
|
+ state.finished = data.pageNo >= data.totalPage
|
|
|
+ params.page = data.pageNo + 1
|
|
|
+ } catch (error) {
|
|
|
+ state.isError = true
|
|
|
+ }
|
|
|
+ state.loading = false
|
|
|
+ }
|
|
|
+
|
|
|
+ onMounted(async () => {
|
|
|
+ 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' }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ await getDetails()
|
|
|
+ await FetchList()
|
|
|
+ })
|
|
|
+
|
|
|
+ const onSubmit = async () => {
|
|
|
+ const album = state.selectMember
|
|
|
+ const details = state.details
|
|
|
+ orderStatus.orderObject.orderType = 'TENANT_ALBUM'
|
|
|
+ orderStatus.orderObject.orderName = details.name
|
|
|
+ orderStatus.orderObject.orderDesc = details.name
|
|
|
+ orderStatus.orderObject.actualPrice = album.salePrice
|
|
|
+ // orderStatus.orderObject.recomUserId = route.query.recomUserId || 0
|
|
|
+ // orderStatus.orderObject.activityId = route.query.activityId || 0
|
|
|
+ orderStatus.orderObject.orderNo = ''
|
|
|
+ orderStatus.orderObject.orderList = [
|
|
|
+ {
|
|
|
+ orderType: 'TENANT_ALBUM',
|
|
|
+ goodsName: details.name,
|
|
|
+ actualPrice: album.salePrice,
|
|
|
+ // recomUserId: route.query.recomUserId || 0,
|
|
|
+ price: album.salePrice,
|
|
|
+ ...details,
|
|
|
+ ...album
|
|
|
+ }
|
|
|
+ ]
|
|
|
+
|
|
|
+ // const res = await request.post('/api-student/userOrder/getPendingOrder', {
|
|
|
+ // data: {
|
|
|
+ // goodType: 'TENANT_ALBUM',
|
|
|
+ // bizId: details.id
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+
|
|
|
+ // const result = res.data
|
|
|
+ if (false) {
|
|
|
+ state.popupStatus = false
|
|
|
+ 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()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const routerTo = () => {
|
|
|
+ const album = state.details
|
|
|
+ router.push({
|
|
|
+ path: '/orderDetail',
|
|
|
+ query: {
|
|
|
+ orderType: 'ALBUM',
|
|
|
+ album: album.id
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const cancelPayment = async (orderNo: string) => {
|
|
|
+ try {
|
|
|
+ await request.post('/api-student/userOrder/orderCancel/v2', {
|
|
|
+ data: {
|
|
|
+ orderNo
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } catch {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return () => (
|
|
|
+ <div class={styles.trainTool}>
|
|
|
+ <TheSticky position="top">
|
|
|
+ <ColHeader
|
|
|
+ background={background.value}
|
|
|
+ border={false}
|
|
|
+ isFixed={false}
|
|
|
+ color={color.value}
|
|
|
+ backIconColor="white"
|
|
|
+ />
|
|
|
+ </TheSticky>
|
|
|
+ <img class={styles.bgImg} src={state.details?.coverImg} />
|
|
|
+ <div class={styles.musicContent}></div>
|
|
|
+ <div class={styles.bg}>
|
|
|
+ <div class={styles.alumWrap}>
|
|
|
+ <div class={styles.img}>
|
|
|
+ <Image
|
|
|
+ class={styles.image}
|
|
|
+ width="100%"
|
|
|
+ height="100%"
|
|
|
+ fit="cover"
|
|
|
+ src={state.details?.coverImg}
|
|
|
+ />
|
|
|
+ <span class={styles.numContent}>
|
|
|
+ <img src={iconMenu} class={styles.iconMenu} />共
|
|
|
+ {state.details?.musicNum}首
|
|
|
+ </span>
|
|
|
+
|
|
|
+ <div class={styles.iconPian}>
|
|
|
+ <Image
|
|
|
+ class={styles.image}
|
|
|
+ width="100%"
|
|
|
+ height="100%"
|
|
|
+ fit="cover"
|
|
|
+ src={state.details?.coverImg}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class={styles.alumDes}>
|
|
|
+ <div class={[styles.alumTitle, 'van-ellipsis']}>
|
|
|
+ {state.details?.name}
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class={[styles.des, 'van-multi-ellipsis--l2']}
|
|
|
+ style={{
|
|
|
+ height: '32px',
|
|
|
+ lineHeight: '16px'
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {state.details?.describe}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class={styles.musicList}>
|
|
|
+ <Tabs
|
|
|
+ color="var(--van-primary)"
|
|
|
+ background="transparent"
|
|
|
+ lineWidth={20}
|
|
|
+ shrink
|
|
|
+ v-model:active={state.activeTab}
|
|
|
+ onChange={val => {
|
|
|
+ state.activeTab = val
|
|
|
+
|
|
|
+ params.page = 1
|
|
|
+ state.list = []
|
|
|
+ FetchList()
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Tab title="声部练习" name="SUBJECT"></Tab>
|
|
|
+ <Tab title="合奏练习" name="ENSEMBLE"></Tab>
|
|
|
+ <Tab title="独奏曲目" name="MUSIC"></Tab>
|
|
|
+ </Tabs>
|
|
|
+
|
|
|
+ <div class={styles.alumnList}>
|
|
|
+ <List
|
|
|
+ loading={state.loading}
|
|
|
+ finished={state.finished}
|
|
|
+ finished-text={' '}
|
|
|
+ onLoad={FetchList}
|
|
|
+ error={state.isError}
|
|
|
+ >
|
|
|
+ {state.list && state.list.length ? (
|
|
|
+ <Song
|
|
|
+ showNumber
|
|
|
+ list={state.list}
|
|
|
+ onDetail={(item: any) => {
|
|
|
+ router.push({
|
|
|
+ path: '/music-detail',
|
|
|
+ query: {
|
|
|
+ id: item.id
|
|
|
+ // albumId: route.params.id
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ ) : (
|
|
|
+ !state.loading && (
|
|
|
+ <ColResult
|
|
|
+ tips="暂无曲目"
|
|
|
+ classImgSize="SMALL"
|
|
|
+ btnStatus={false}
|
|
|
+ />
|
|
|
+ )
|
|
|
+ )}
|
|
|
+ </List>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ {!state.loading && !state.details.ifBuy && (
|
|
|
+ <TheSticky position="bottom">
|
|
|
+ <div class={styles.btnGroup}>
|
|
|
+ <Button
|
|
|
+ round
|
|
|
+ block
|
|
|
+ color="#FE2451"
|
|
|
+ onClick={() => (state.popupStatus = true)}
|
|
|
+ >
|
|
|
+ 购买教程
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </TheSticky>
|
|
|
+ )}
|
|
|
+ <Popup
|
|
|
+ v-model:show={state.popupStatus}
|
|
|
+ position="bottom"
|
|
|
+ round
|
|
|
+ zIndex={9999}
|
|
|
+ safe-area-inset-bottom
|
|
|
+ closeable={false}
|
|
|
+ class={styles.popupStatus}
|
|
|
+ onClose={() => (state.popupStatus = false)}
|
|
|
+ // onClosed={() => (this.openStatus = false)}
|
|
|
+ >
|
|
|
+ <div class={styles.bottom_function}>
|
|
|
+ <i
|
|
|
+ class={styles.iconClose}
|
|
|
+ onClick={() => (state.popupStatus = false)}
|
|
|
+ ></i>
|
|
|
+ <img src={iconRightTop} class={styles.iconRightTop} />
|
|
|
+ <div class={styles.memberMeal}>
|
|
|
+ <div class={styles.titleMeal}>
|
|
|
+ <span>请选择教程购买周期</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class={styles['system-list']}>
|
|
|
+ {state.buyList.map((item: any) => (
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles['system-item'],
|
|
|
+ item.status && styles.active
|
|
|
+ ]}
|
|
|
+ onClick={() => {
|
|
|
+ state.buyList.forEach((item: any) => {
|
|
|
+ item.status = false
|
|
|
+ })
|
|
|
+ item.status = true
|
|
|
+ state.selectMember = item
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <p class={styles.title}>{item.purchaseCycle}个月</p>
|
|
|
+ <p class={styles.price}>
|
|
|
+ <span>¥</span>
|
|
|
+ {moneyFormat(item.salePrice, '0,0[.]00')}
|
|
|
+ </p>
|
|
|
+ <del class={styles.originalPrice}>
|
|
|
+ ¥{moneyFormat(item.costPrice, '0,0[.]00')}
|
|
|
+ </del>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class={styles.btnGroup}>
|
|
|
+ <Button round block class={styles.btn} onClick={onSubmit}>
|
|
|
+ 点击购买
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </Popup>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+})
|