| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 | import {  TransitionGroup,  defineComponent,  nextTick,  onMounted,  reactive,  ref,  watch} from 'vue';import styles from './index.module.less';import MSearch from '@/components/m-search';import icon_play from '@/common/images/icon_play.svg';import {  Empty,  List,  Loading,  NoticeBar,  showLoadingToast,  showToast} from 'vant';import icon_back from './image/icon_back.svg';import icon_down from '@/common/images/icon_down.svg';import icon_jianpu from '@/common/images/icon_jianpu.svg';import icon_jianpuActive from '@/common/images/icon_jianpuActive.svg';import icons from '@/common/images/index.json';import {  listenerMessage,  postMessage,  promisefiyPostMessage} from '@/helpers/native-message';import { rows } from './data.json';import html2canvas from 'html2canvas';import { api_musicSheetCategoriesPage, api_musicSheetPage } from './api';import { state } from '@/state';import MEmpty from '@/components/m-empty';import { usePageVisibility } from '@vant/use';export default defineComponent({  name: 'co-ai',  setup() {    const categorForms = reactive({      page: 1,      rows: 999,      subjectId: state.user.data?.subjectId || ''    });    const musicForms = reactive({      page: 1,      rows: 20,      status: 1,      keyword: '', // 关键词      musicSheetCategoriesId: ''    });    const titles = rows;    const data = reactive({      /** 教材Index */      typeIndex: 0,      /** 音乐Index */      musicIndex: 0,      /** 显示简谱 */      isShowJianpu: false,      /** 教材列表 */      types: [] as any[],      /** 音乐列表 */      musics: [] as any[],      loading: true,      finshed: false,      searchNoticeShow: false,      searchNotice: {        left: '',        top: '',        width: '',        height: ''      }    });    const downRef = ref();    // 返回    const goback = () => {      postMessage({ api: 'goBack' });    };    /** 去云教练 */    const handleGoto = () => {      let src = `${location.origin}/instrument?id=${        data.musics[data.musicIndex]?.id      }`;      console.log(src);      postMessage({        api: 'openAccompanyWebView',        content: {          url: src,          orientation: 0,          isHideTitle: true,          statusBarTextColor: false,          isOpenLight: true        }      });    };    /** 保存图片 */    const handleSave = async () => {      showLoadingToast({ message: '正在保存', duration: 0 });      try {        html2canvas(downRef.value, {          backgroundColor: '#fff',          allowTaint: true,          useCORS: true        })          .then(async canvas => {            var dataURL = canvas.toDataURL('image/png', 1); //可选取多种模式            setTimeout(() => {              showToast('保存成功');            }, 500);            const res = await promisefiyPostMessage({              api: 'savePicture',              content: {                base64: dataURL              }            });          })          .catch(() => {            setTimeout(() => {              showToast('保存失败');            }, 500);          });      } catch (error) {        setTimeout(() => {          showToast('保存失败');        }, 500);      }    };    /** 获取音乐教材列表 */    const getMusicSheetCategories = async () => {      try {        const res = await api_musicSheetCategoriesPage({          ...categorForms        });        if (res.code === 200 && Array.isArray(res?.data?.rows)) {          data.types = res.data.rows;          if (!musicForms.musicSheetCategoriesId && data.types.length > 0) {            musicForms.musicSheetCategoriesId = data.types[0].id;          }        }      } catch (error) {        console.log('🚀 ~ error:', error);      }    };    /** 获取曲谱列表 */    const getMusicList = async () => {      data.loading = true;      try {        const res = await api_musicSheetPage({          ...musicForms        });        if (res.code === 200 && Array.isArray(res?.data?.rows)) {          data.musics = [...data.musics, ...res.data.rows];          data.finshed = !res.data.next;        }      } catch (error) {        console.log('🚀 ~ error:', error);      }      data.loading = false;    };    const handleReset = () => {      musicForms.page = 1;      data.musics = [];      getMusicList();    };    const spinRef = ref();    const handleResh = () => {      if (data.loading || data.finshed) return;      musicForms.page = musicForms.page + 1;      getMusicList();    };    const setSearchBox = () => {      const el = document.querySelector('.searchNotice .van-field__control');      if (el) {        const rect = el.getBoundingClientRect();        data.searchNotice.left = rect.x + 'px';        data.searchNotice.top = rect.y + 'px';        data.searchNotice.width = rect.width + 'px';        data.searchNotice.height = rect.height + 'px';      }    };    onMounted(async () => {      await getMusicSheetCategories();      getMusicList();      const obv = new IntersectionObserver(entries => {        if (entries[0].intersectionRatio > 0) {          handleResh();        }      });      nextTick(() => {        obv.observe(spinRef.value);      });      listenerMessage('webViewOnResume', () => {        handleReset();      });      setSearchBox();    });    return () => (      <div class={styles.container}>        <div class={styles.back} onClick={goback}>          <img src={icon_back} />        </div>        <div class={styles.content}>          <div class={[styles.leftContent]}>            <div class={styles.leftBg2}></div>            <div class={styles.leftBg}></div>            <div class={styles.types}>              {data.types.map((item, index) => {                return (                  <div                    class={[                      styles.type,                      musicForms.musicSheetCategoriesId === item.id &&                        styles.typeActive                    ]}                    onClick={() => {                      musicForms.musicSheetCategoriesId = item.id;                      handleReset();                    }}>                    <div class={styles.typeImg}>                      <img                        class={styles.typeIcon}                        src={item.coverImg}                        onLoad={(e: Event) => {                          const el = e.target as HTMLImageElement;                          el.setAttribute('loaded', 'true');                        }}                      />                    </div>                  </div>                );              })}            </div>            <div class={styles.center}>              <MSearch                class={["searchNotice", data.searchNoticeShow ? styles.searchNoticeShow : '']}                shape="round"                background="transparent"                clearable={false}                placeholder="请输入曲目名称"                onFocus={() => (data.searchNoticeShow = false)}                onBlur={(val) => {                  musicForms.keyword = val;                  requestAnimationFrame(() => {                    requestAnimationFrame(() => {                      data.searchNoticeShow = true;                    });                  });                }}                onSearch={val => {                  musicForms.keyword = val;                  handleReset();                }}              />              <div class={styles.musicContent}>                {data.musics.map((item: any, index: number) => {                  return (                    <div                      class={[                        styles.musicItem,                        data.musicIndex === index                          ? styles.musicActive                          : styles.disableNotic                      ]}                      onClick={() => (data.musicIndex = index)}>                      <img                        class={styles.musicAvtor}                        src={item.titleImg}                        onLoad={(e: Event) => {                          const el = e.target as HTMLImageElement;                          el.setAttribute('loaded', 'true');                        }}                      />                      <div class={styles.musicInfo}>                        <div class={styles.musicName}>                          <NoticeBar                            text={item.musicSheetName}                            class={styles.noticeBar}                            background="none"                          />                        </div>                        <div class={styles.musicDes}>                          <div class={styles.musicFavitor}>{item.usedNum}</div>                          <div class={[styles.musicAuthor, 'van-ellipsis']}>                            {item.composer}                          </div>                        </div>                      </div>                      {/* <img class={[styles.musicIcon]} src={icon_play} /> */}                    </div>                  );                })}                {!data.finshed && (                  <div ref={spinRef} class={styles.loadingWrap}>                    <Loading color="#259CFE" />                  </div>                )}                {!data.loading && data.musics.length === 0 && (                  <div class={styles.empty}>                    <MEmpty description="暂无曲谱" />                  </div>                )}              </div>            </div>          </div>          <div class={[styles.opacityBg, styles.right]}>            <div ref={downRef}>              <div class={styles['right-musicName']}>                {data.musics[data.musicIndex]?.musicSheetName}              </div>              {data.isShowJianpu ? (                <>                  <TransitionGroup name="van-fade">                    {data.musics[data.musicIndex]?.firstTone                      ?.split(',')                      .map((item: any, index: number) => {                        return (                          <img                            class={styles.staff}                            src={item + '?v=' + Date.now()}                            key={item}                          />                        );                      })}                  </TransitionGroup>                </>              ) : (                <>                  <TransitionGroup name="van-fade">                    {data.musics[data.musicIndex]?.musicImg                      ?.split(',')                      .map((item: any, index: number) => {                        return (                          <img                            class={styles.staff}                            src={item + '?v=' + Date.now()}                            key={item}                            crossorigin="anonymous"                          />                        );                      })}                  </TransitionGroup>                </>              )}            </div>            <div class={styles.rightBtns}>              <img                src={data.isShowJianpu ? icon_jianpuActive : icon_jianpu}                onClick={() => (data.isShowJianpu = !data.isShowJianpu)}              />              <img src={icon_down} onClick={handleSave} />              <img src={icons.icon_start} onClick={() => handleGoto()} />            </div>          </div>        </div>        {data.searchNotice.width && data.searchNoticeShow && (          <div class={styles.searchNotice} style={{ ...data.searchNotice }}>            <NoticeBar              text={musicForms.keyword}              color="#333"              background="none"            />          </div>        )}      </div>    );  }});
 |