| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872 | import {  defineComponent,  onMounted,  onUnmounted,  onBeforeMount,  reactive,  ref,  watch,  nextTick,} from 'vue'// import WaveSurfer from 'wavesurfer.js';// import Regions from 'wavesurfer.js/dist/plugins/regions.js';import styles from './index.module.less'import { Cell, Image, List, Popup, Slider, Sticky, NoticeBar, Toast } from 'vant'import TextEllipsis from './text-ellipsis/index';import MSticky from '@/components/col-sticky'import MHeader from '@/components/col-header'import iconMember from './images/icon-member.png'import iconZan from './images/icon-zan.png'import iconZanActive from './images/icon-zan-active.png'import logoImg from './images/logo.png';import logo1Img from './images/logo1.png';import backImg from "./images/back.png";import back1Img from "./images/back1.png";import videobg from "./images/videobg.png";import audioPan from './images/audio-pan.png';import audioLabel from './share-model/images/audioLabel.png';import videoLabel from './share-model/images/videoLabel.png';import musicBg from './share-model/images/music-bg.png';import playImg from './images/play.png';import btnImg from './images/btn.png';import iconUpward from './images/upward.png';import vipIcon from './images/vip_icon.png';import svipIcon from './images/svip_icon.png';import wxBg from './images/wx_bg.png';import tyBg from './images/ty.png';import {  browser,  getAuth,  getGradeCh,  getSecondRPM,  removeAuth,  setAuth} from '@/helpers/utils'import { postMessage, promisefiyPostMessage } from '@/helpers/native-message'import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router'import {  api_openUserMusicDetail,  api_openUserMusicPage,  api_userMusicStar,  api_verification} from './api'import MEmpty from '@/components/col-result'import LoginModel from './login-model'import { setLogout } from '@/state'import MWxTip from '@/components/the-wx-tip'import { usePageVisibility } from '@vant/use'import "plyr/dist/plyr.css";import Plyr from "plyr";import audioVisualDraw from "./audioVisualDraw"import Loading from './loading';import { state as originState } from '@/state'export default defineComponent({  name: 'creation-detail',  setup() {    const {isApp, isTablet, weixin, isTeacher} = browser()    const route = useRoute()    const router = useRouter()    const isScreenScroll = ref(false)    const creationHeight = ref(0)    const state = reactive({      id: route.query.id,      isEmpty: false,      loginTag: false, // 是否登录标识      loginStatus: false,      playType: '' as 'Audio' | 'Video' | '', // 播放类型      musicDetail: {} as any,      timer: null as any,      paused: true,      audioWidth: 0,      currentTime: 0,      duration: 0.1,      loop: false,      dragStatus: false, // 是否开始拖动      isClick: false,      list: [] as any,      listState: {        dataShow: true, // 判断是否有数据        loading: false,        finished: false      },      params: {        page: 1,        rows: 4      },      messageStatus: false,      message: '' as any,      _plrl: null as any,      heightV: 0,      heightB: 0,    })    const plyrState = reactive({      duration: 0,      currentTime: 0,      mediaTimeShow: false,      playIngShow: true,      loaded:false    })    // 谱面    const staffState = reactive({      staffSrc: "",      isShow: false,      height:"initial",      speedRate:1,      musicRenderType:"staff",      partIndex:0    })        const isLandscapeScreen = ref(false)    const wxStatus = ref(false)    const staffDom= ref<HTMLIFrameElement>()    const {playStaff, pauseStaff, updateProgressStaff} = staffMoveInstance()    // 点赞    const onStarChange = async () => {      const Authorization = getAuth()      if (!Authorization && route.query.Authorization) {        setAuth(route.query.Authorization)      }      await checkLogin();      // 是否登录      if (!state.loginTag) {        state.loginStatus = true        return      }      try {        await api_userMusicStar({          userMusicId: state.id,          star: !state.musicDetail.starFlag        })        state.musicDetail.starFlag = !state.musicDetail.starFlag        if (state.musicDetail.starFlag) {          state.musicDetail.likeNum += 1        } else {          state.musicDetail.likeNum -= 1        }      } catch {        //      }    }    // 获取列表    const getList = async () => {      try {        if (state.isClick) return        state.isClick = true        const res = await api_openUserMusicPage({          type: 'FORMAL',          exclusionId: state.id,          sort: 1,          ...state.params        })        state.listState.loading = false        const result = res.data || {}        // 处理重复请求数据        // if (state.list.length > 0 && result.current === 1) {        //   return        // }        state.list = result.rows || []        state.listState.finished = result.current >= result.pages        state.params.page = result.current + 1        state.listState.dataShow = state.list.length > 0        state.isClick = false      } catch {        state.listState.dataShow = false        state.listState.finished = true        state.isClick = false      }    }    function handleChangeList() {      if(state.listState.finished){        state.listState.finished = false        state.params.page = 1;        getList()      }else{        getList()      }    }    const onDetail = (item: any) => {      router.push({        path: '/shareCreation',        query: {          id: item.id        }      })    }    // 初始化 媒体播放    function initMediaPlay(){      const id = state.playType === "Audio" ? "#audioMediaSrc" : "#videoMediaSrc";      state._plrl = new Plyr(id, {        controls: ["play", "progress", "current-time", "duration"],        fullscreen: {          enabled: false,          fallback: false        }      });      const player = state._plrl      // 创建音波数据      if(state.playType === "Audio"){        const audioDom = document.querySelector("#audioMediaSrc") as HTMLAudioElement        const canvasDom = document.querySelector("#audioVisualizer") as HTMLCanvasElement        const { pauseVisualDraw, playVisualDraw } = audioVisualDraw(audioDom, canvasDom)        player.on('play', () => {          playVisualDraw()        });        player.on('pause', () => {          pauseVisualDraw()        });      }      // 在微信中运行的时候,微信没有开放自动加载资源的权限,所以要等播放之后才显示播放控制器      player.on('loadedmetadata', () => {        plyrState.loaded = true        //player.currentTime = playProgressData.playProgress      });      player.on("timeupdate", ()=>{        plyrState.currentTime = player.currentTime      })      player.on('play', () => {        plyrState.playIngShow = false        playStaff()      });      player.on('pause', () => {        plyrState.playIngShow = true        pauseStaff()      });      player.on('ended', () => {        player.currentTime = 0        if(!player.playing){          setTimeout(() => {            updateProgressStaff(player.currentTime)          }, 100);        }      });      // 处理按压事件      const handleStart = () => {        if(isLandscapeScreen.value){          return        }        plyrState.duration = player.duration        plyrState.mediaTimeShow = true      };      // 处理松开事件      const handleEnd = () => {        plyrState.mediaTimeShow = false        // 暂停的时候调用        if(!player.playing){          updateProgressStaff(player.currentTime)        }      };      const progressDom = document.querySelector("#playMediaSection .plyr__controls .plyr__progress__container") as HTMLElement      progressDom.addEventListener('mousedown', handleStart);      progressDom.addEventListener('touchstart', handleStart);      progressDom.addEventListener('mouseup', handleEnd);      progressDom.addEventListener('touchend', handleEnd);    }    //点击改变播放状态    function handlerClickPlay(event?:MouseEvent){      // 原生 播放暂停按钮 点击的时候 不触发      // @ts-ignore      if(event?.target?.matches('button.plyr__control')){        return      }      const player = state._plrl;      if (player.playing) {        player.pause();      } else {        player.play();      }    }    function handlerBack(event:any){      event.stopPropagation()      verticalScreen()    }    function landscapeScreen(){      postMessage({        api: "setRequestedOrientation",        content: {          orientation: 0,        },      });      isLandscapeScreen.value = true    }    function verticalScreen(){      postMessage({        api: "setRequestedOrientation",        content: {          orientation: 1,        },      });      isLandscapeScreen.value = false    }    function handlerLandscapeScreen(event:any){      event.stopPropagation()      if(isApp){        landscapeScreen()        return      }      if(weixin){        wxStatus.value = true      }else{        const t = Date.now()        const str  = location.href        shareCall(str)        setTimeout(() => {          if(Date.now() - t < 3500){            if (window.location.pathname.includes('teacher')) {              window.location.href = location.origin + '/student' + '/#/transfer'            } else {              window.location.href = location.origin + '/student' + '/#/download'            }          }        }, 3000)      }    }    const shareCall = (str: string, params?: any) => {      const query = {        url: str,        action: params?.action || 'h5', // app, h5        pageTag: params?.pageTag || 1 // 页面标识      }      const iosStr = encodeURIComponent(JSON.stringify(query))      const userAgent = navigator.userAgent || navigator.vendor;      const platform = navigator.platform || 'unknown';      if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent) || (platform === 'MacIntel')) {        window.location.href = `ColexiuStudent://linkUrl=${iosStr}`      } else if (/(Android)/i.test(userAgent)) {        window.location.href = `colexiustudent://html:8888/SplashActivity?url=${iosStr}`      } else {        Toast('请用手机或移动设备打开')      }    }    const checkLogin = async () => {      try {        // 判断是否登录        const Authorization = getAuth() // storage.get(ACCESS_TOKEN) || ''        if (Authorization) {          await api_verification({            token: Authorization          })          state.loginTag = true          // if (!res.data) {          //   removeAuth()          //   setLogout()          // }        }      } catch (e: any) {        // 登录是否有效        state.loginTag = false        removeAuth()        setLogout()      }    };        const __init = async () => {      await checkLogin();      try {        const res = await api_openUserMusicDetail(state.id)        if (res.code === 999) {          // 没有的时候显示缺省页          state.isEmpty = true          staffState.isShow = true          return        } else {          state.musicDetail = res.data          try{            const jsonConfig = JSON.parse(res.data.jsonConfig)            jsonConfig.speedRate && (staffState.speedRate = jsonConfig.speedRate)            jsonConfig.musicRenderType && (staffState.musicRenderType = jsonConfig.musicRenderType)            jsonConfig["part-index"] && (staffState.partIndex = jsonConfig["part-index"])          }catch{          }          // 五线谱          initStaff()          getList()          // 判断是视频还是音频          if (res.data.videoUrl.lastIndexOf('mp4') !== -1) {            state.playType = 'Video'          } else {            state.playType = 'Audio'          }          // 初始化          nextTick(() => {            initMediaPlay();          });        }      } catch (err) {        state.listState.dataShow = false        // 没有的时候显示缺省页        state.message = err;        state.messageStatus = true;      }    }    // 滚动事件    const handleScroll = () => {      // 作品已删除不让滚动变色      if(state.isEmpty) return      const height =        window.scrollY ||        document.documentElement.scrollTop        // 防止多次调用        if(height > 0 && isScreenScroll.value === false){          isScreenScroll.value = true          if(isApp){            setStatusBarTextColor(false)          }        }        if(height <= 0){          isScreenScroll.value = false          if(isApp){            setStatusBarTextColor(true)          }        }    }    // 跳转下载页    function handlerDownLoad(){      if(weixin){        wxStatus.value = true      }else{        // 如果是老师端        if (window.location.pathname.includes('teacher')) {          window.location.href = location.origin + '/student' + '/#/transfer'        } else {          router.push({            path:"/download"          })        }      }    }    const pageVisibility = usePageVisibility()    watch(pageVisibility, value => {      if (value === 'hidden') {        state._plrl?.pause();      }    });    // 初始化五线谱    function initStaff(){      const systemType = originState.platformType === 'TEACHER' || isTeacher ? 'teacher' : 'student'      const src = `/klx-music-score/#/simple-detail?id=${state.musicDetail.musicSheetId}&musicRenderType=${staffState.musicRenderType}&part-index=${staffState.partIndex}&userMusicId=${state.id}&systemType=${systemType}`;      // const src = `http://192.168.3.68:3000/instrument.html#/simple-detail?id=${state.musicDetail.musicSheetId}&musicRenderType=${staffState.musicRenderType}&part-index=${staffState.partIndex}&userMusicId=${state.id}`;      staffState.staffSrc = src      window.addEventListener('message', (event) => {        const { api, height } = event.data;        if (api === 'api_musicPage') {          staffState.isShow = true          staffState.height = height + "px"          // 如果是播放中自动开始播放  不是播放 自动跳转到当前位置          // if(playProgressData.playState){          //   handlerClickPlay()          // }else{          //   updateProgressStaff(state._plrl.currentTime)          // }        }      });    }    function staffMoveInstance(){      let isPause = true      const requestAnimationFrameFun = () => {        requestAnimationFrame(() => {          staffDom.value?.contentWindow?.postMessage(            {              api: 'api_playProgress',              content: {                currentTime: state._plrl.currentTime * staffState.speedRate              }            },            "*"          )          if (!isPause) {            requestAnimationFrameFun()          }        })      }      const playStaff = () => {        // 没渲染不执行        if(!staffState.isShow) return        isPause = false        staffDom.value?.contentWindow?.postMessage(          {            api: 'api_play'          },          "*"        )        requestAnimationFrameFun()      }      const pauseStaff = () => {        // 没渲染不执行        if(!staffState.isShow) return        isPause = true        staffDom.value?.contentWindow?.postMessage(          {            api: 'api_paused'          },          "*"        )      }      const updateProgressStaff = (currentTime: number) => {        // 没渲染不执行        if(!staffState.isShow) return        staffDom.value?.contentWindow?.postMessage(          {            api: 'api_updateProgress',            content: {              currentTime: currentTime * staffState.speedRate            }          },          "*"        )      }      return {        playStaff,        pauseStaff,        updateProgressStaff      }    }    // 设置导航栏颜色    function setStatusBarTextColor(isWhite:boolean){      postMessage({        api: 'setStatusBarTextColor',        content: { statusBarTextColor: isWhite }      })    }    function setFullHeight(){      creationHeight.value = window.innerHeight    }        onBeforeMount(() => {      if(isApp) {        postMessage({          api: "setRequestedOrientation",          content: {            orientation: 1,          },        });        setStatusBarTextColor(true)      }    })        onMounted(async () => {      window.addEventListener("scroll", handleScroll)      __init()      setFullHeight()      window.addEventListener('resize', setFullHeight)    })    onUnmounted(() => {      window.removeEventListener("scroll", handleScroll)      window.removeEventListener('resize', setFullHeight)      state._plrl?.destroy()    })    onBeforeRouteUpdate((to: any) => {      state.id = to.query.id;      state.playType = '';      state.params.page = 1;      state.list = [];      if(state._plrl){        state._plrl.destroy()      }      plyrState.playIngShow = true      staffState.staffSrc = ""      staffState.isShow = false      staffState.height = "initial"      __init();    })    return () => (      <div        style={          {            '--barheight':state.heightV + "px",            "--creationHeight":creationHeight.value ? creationHeight.value+"px" : "100vh"          }        }        class={[          styles.creation,          isTablet ? styles.creationTablet : '',          isScreenScroll.value && styles.isShareScreenScroll        ]}>        <div class={styles.creationBg}></div>        <MSticky position="top"          onGetHeight={(height: any) => {            console.log(height, 'height', height)            state.heightV = height          }}        >            {              isApp ? <MHeader                  leftClickDefault={false}                  color={isScreenScroll.value ? "#333333" : "#ffffff"}                  background={isScreenScroll.value ? `rgb(255,255,255` : "transparent"}                  border={false}                  isBack={route.query.platformType != 'ANALYSIS'}                  title={"作品详情"}                  onLeftClick={()=>{                    setStatusBarTextColor(false)                    postMessage({                      api: 'back'                    });                  }}                />                : <div class={styles.logoDownload}>                    <img src={isScreenScroll.value ? logo1Img : logoImg} class={styles.logoImg}></img>                    <div class={styles.logTit} onClick={handlerDownLoad}>下载App</div>                  </div>            }        </MSticky>        {          state.isEmpty ?          <div class={styles.isEmpty}>            <MEmpty tips="作品已删除~" btnStatus={false} />          </div> :          <>            <div class={styles.singerBox}>              <div class={styles.musicSheetName}>                <NoticeBar                    text={state.musicDetail?.musicSheetName}                    background="none"                />              </div>              <div class={styles.singerName}>                演奏:{state.musicDetail?.username}              </div>            </div>            <Sticky zIndex={1000} offsetTop={state.heightV - 1 + "px"}>              <div class={[styles.playSection, plyrState.mediaTimeShow && styles.mediaTimeShow,!plyrState.loaded && styles.notLoaded,isLandscapeScreen.value&&styles.isLandscapeScreen, state.playType === 'Audio' && styles.isLandscapeScreen2]} id="playMediaSection" onClick={handlerClickPlay}>                {                  isLandscapeScreen.value &&                    <div class={styles.backBox}>                      <img class={styles.backImg} src={state.playType === 'Video' ? back1Img : backImg} onClick={handlerBack}/>                      <div class={[styles.musicDetail, state.playType === 'Audio' && styles.adMusicDetail]}>                        <div class={styles.musicSheetName}>                            <NoticeBar                                text={state.musicDetail?.musicSheetName}                                background="none"                            />                        </div>                        <div class={styles.username}>演奏:{state.musicDetail?.username}</div>                      </div>                    </div>                }                {                  state.playType &&                  <>                    {                      state.playType === 'Audio' &&                      <div class={styles.audioBox}>                        <canvas class={styles.audioVisualizer} id="audioVisualizer"></canvas>                        <audio                          crossorigin="anonymous"                          id="audioMediaSrc"                          src={state.musicDetail?.videoUrl}                          controls="false"                          preload="metadata"                          playsinline                          webkit-playsinline                        />                        <img src={tyBg} class={styles.tyBg} />                        <div class={styles.audioBoxBg}>                            <div class={[styles.audioPan,  plyrState.playIngShow && styles.imgRotate]}>                              <img class={styles.audioImg} src={state.musicDetail.img || musicBg} />                            </div>                            <i class={styles.audioPoint}></i>                            <i class={[styles.audioZhen, plyrState.playIngShow && styles.active]}></i>                        </div>                                              </div>                    }                    {                      state.playType === 'Video' &&                      <video                        id="videoMediaSrc"                        class={styles.videoBox}                        src={state.musicDetail?.videoUrl}                        data-poster={ state.musicDetail?.videoImg || videobg}                        poster={ state.musicDetail?.videoImg || videobg}                        preload="metadata"                        playsinline                        webkit-playsinline                        x5-playsinline                      />                    }                    <div class={[styles.playLarge, !plyrState.mediaTimeShow && plyrState.playIngShow && styles.playIngShow]}></div>                    <div class={styles.mediaTimeCon}>                      <div class={styles.mediaTime}>                        <div>                          {getSecondRPM(plyrState.currentTime)}                        </div>                        <div class={styles.note}>/</div>                        <div class={styles.duration}>                          {getSecondRPM(plyrState.duration)}                        </div>                      </div>                    </div>                    <div class={styles.landscapeScreen} onClick={handlerLandscapeScreen}></div>                    {/* 谱面 */}                    {                      staffState.staffSrc &&                      <div class={[styles.staffBoxCon, staffState.isShow && styles.staffBoxShow]}>                        <div                          class={[styles.staffBox, state.playType === 'Video' && styles.staffBoxBg]}                          style={                            {                              '--staffBoxHeight':staffState.height                            }                          }                        >                          <div class={styles.mask}></div>                          <iframe                            ref={staffDom}                            class={styles.staff}                            frameborder="0"                            src={staffState.staffSrc}>                          </iframe>                        </div>                      </div>                    }                  </>                }              </div>            </Sticky>            <div class={[styles.musicSection, styles.musicShareSection]}>              <div class={styles.avatarInfoBox}>                <div class={styles.avatar}>                  <div class={styles.avatarImg}>                    <img class={[styles.userLogo, state.musicDetail.vipType === 'VIP' ? styles.vipLogo : state.musicDetail.vipType === 'PERMANENT_SVIP' || state.musicDetail.vipType === 'SVIP' ? styles.svipLogo : '']} src={state.musicDetail.avatar} />                    {                      (state.musicDetail.vipType === 'VIP' || state.musicDetail.vipType === 'PERMANENT_SVIP' || state.musicDetail.vipType === 'SVIP') &&                      <img class={styles.vipIcon} src={state.musicDetail.vipType === 'VIP' ? vipIcon : svipIcon} />                    }                                  </div>                  <div class={styles.infoCon}>                    <div class={styles.info}>                      <span class={styles.userName}>{state.musicDetail?.username}</span>                      {state.musicDetail.vipFlag && (                        <img src={iconMember} class={styles.iconMember} />                      )}                    </div>                    <div class={styles.sub}>                      {state.musicDetail.subjectName}{' '}                      {getGradeCh(state.musicDetail.currentGradeNum - 1)}                    </div>                  </div>                </div>                <div class={styles.linkes}  onClick={onStarChange}>                  <img src={state.musicDetail.starFlag ? iconZanActive : iconZan} class={styles.iconZan} />                  <span>{state.musicDetail.likeNum}</span>                </div>              </div>              <TextEllipsis class={styles.textEllipsis} text={state.musicDetail?.desc || ''} />            </div>            <div class={styles.likeSection}>              <div class={styles.likeTitle}>推荐作品</div>              {state.listState.dataShow ? (                <>                  <List                    finished={true}                    finishedText=" "                    class={[styles.container, styles.containerInformation]}                    //onLoad={getList}                    immediateCheck={false}>                    {state.list.map((item: any, index:number) => (                      <Cell                        class={[styles.likeShareItem, index===state.list.length-1&&styles.likeShareItemLast]}                        border={false}                        onClick={() => onDetail(item)}                      >                        {{                          icon: () => (                            <div class={styles.audioImgBox}>                              <img                                src={audioPan}                                class={styles.audioPan}                                crossorigin="anonymous"                              />                              <img                                src={                                  item.img || musicBg                                }                                class={styles.muploader}                                crossorigin="anonymous"                              />                              <img class={styles.imgLabel} src={item.videoUrl?.lastIndexOf('mp4') !== -1 ? videoLabel : audioLabel} />                            </div>                          ),                          title: () => (                            <div class={styles.userInfo}>                              <div class={[styles.musicSheetName,'van-ellipsis']}>{item.musicSheetName}</div>                              <div class={styles.usernameCon}>                                <div class={styles.likeNum}>                                  <img src={iconZanActive} />                                  <span>{item.likeNum}</span>                                </div>                                <div class={[styles.username, 'van-ellipsis']}>{item.username}</div>                              </div>                            </div>                          ),                          value: () => (                            <img src={playImg} class={styles.playImg} />                          )                        }}                      </Cell>                    ))}                  </List>                  {                    (!state.listState.finished || state.params.page>2) &&                      <div class={styles.btnImg}>                        <img onClick={handleChangeList} onTouchstart={()=>{}} src={btnImg} />                      </div>                  }                </>              ) : (                <MEmpty tips="暂无作品~" btnStatus={false} />              )}            </div>            {              !isScreenScroll.value &&              <MSticky position="bottom" offsetBottom={state.heightB - 1 + "px"} >                <div class={styles.upward}>                  <img src={iconUpward} />                </div>              </MSticky>            }          </>        }        <Popup          v-model:show={state.loginStatus}          style={{ background: 'transparent', overflow: 'inherit' }}        >          <LoginModel            onClose={() => (state.loginStatus = false)}            onConfirm={async (val: boolean) => {              state.loginTag = val              state.loginStatus = false              const { data } = await api_openUserMusicDetail(state.id)              state.musicDetail = data            }}          />        </Popup>        <MWxTip          v-model:show={state.messageStatus}          message={state.message}          showButton={false}        />        {          !staffState.isShow && <Loading></Loading>        }        {wxStatus.value && (          <div            class={styles.wxpopup}            onClick={() => {              wxStatus.value = false;            }}>            <img src={wxBg} alt="" />          </div>        )}              </div>    )  }})
 |