|
@@ -0,0 +1,317 @@
|
|
|
+import {
|
|
|
+ NBreadcrumb,
|
|
|
+ NBreadcrumbItem,
|
|
|
+ NButton,
|
|
|
+ NImage,
|
|
|
+ NSlider,
|
|
|
+ NSpace,
|
|
|
+ NSpin
|
|
|
+} from 'naive-ui';
|
|
|
+import { computed, defineComponent, onMounted, reactive } from 'vue';
|
|
|
+import styles from './detail.module.less';
|
|
|
+import icon_back from '../../xiaoku-music/images/icon_back.png';
|
|
|
+import icon_arrow from '../../xiaoku-music/images/icon_arrow.png';
|
|
|
+import icon_play from '../../xiaoku-music/images/icon_play.png';
|
|
|
+import icon_pause from '../../xiaoku-music/images/icon_pause.png';
|
|
|
+import icon_default from '../../xiaoku-music/images/icon_default.png';
|
|
|
+import icon_separator from '../../xiaoku-music/images/icon_separator.png';
|
|
|
+import iconT from '../images/icon-t.png';
|
|
|
+import iconAddT from '../images/icon-add-t.png';
|
|
|
+import iconPlusT from '../images/icon-plus-t.png';
|
|
|
+import { useRoute, useRouter } from 'vue-router';
|
|
|
+import PlayLoading from '../../../xiaoku-music/component/play-loading';
|
|
|
+import TheNoticeBar from '/src/components/TheNoticeBar';
|
|
|
+import TheEmpty from '/src/components/TheEmpty';
|
|
|
+import PlayItem from '../../../xiaoku-music/component/play-item';
|
|
|
+import { api_knowledgeWiki_detail } from '/src/views/content-information/api';
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'instrument-detail',
|
|
|
+ setup() {
|
|
|
+ const route = useRoute();
|
|
|
+ const router = useRouter();
|
|
|
+ const forms = reactive({
|
|
|
+ page: 1,
|
|
|
+ rows: 20,
|
|
|
+ status: true,
|
|
|
+ name: '', // 关键词
|
|
|
+ type: route.query.type
|
|
|
+ });
|
|
|
+ const data = reactive({
|
|
|
+ loading: false,
|
|
|
+ finshed: false,
|
|
|
+ reshing: false,
|
|
|
+ details: {} as any,
|
|
|
+ list: [] as any,
|
|
|
+ listActive: 0,
|
|
|
+ playState: 'pause' as 'play' | 'pause',
|
|
|
+ showPlayer: false,
|
|
|
+ showPreivew: false,
|
|
|
+ previewUrl: '',
|
|
|
+ showCloseBtn: true,
|
|
|
+ fontSize: 18 // 默认18
|
|
|
+ });
|
|
|
+
|
|
|
+ /** 选中的item */
|
|
|
+ const activeItem = computed(() => {
|
|
|
+ return data.list[data.listActive] || {};
|
|
|
+ });
|
|
|
+
|
|
|
+ /** 播放曲目 */
|
|
|
+ const handlePlay = (item: any) => {
|
|
|
+ const index = data.list.findIndex((_item: any) => _item.id === item.id);
|
|
|
+ if (index > -1) {
|
|
|
+ if (data.listActive === index) {
|
|
|
+ data.playState = data.playState === 'play' ? 'pause' : 'play';
|
|
|
+ } else {
|
|
|
+ data.playState = 'play';
|
|
|
+ }
|
|
|
+ data.showPlayer = true;
|
|
|
+ data.listActive = index;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 音频控制 */
|
|
|
+ const handleChangeAudio = (
|
|
|
+ type: 'play' | 'pause' | 'pre' | 'next' | 'favitor'
|
|
|
+ ) => {
|
|
|
+ if (type === 'play') {
|
|
|
+ data.playState = 'play';
|
|
|
+ } else if (type === 'pause') {
|
|
|
+ data.playState = 'pause';
|
|
|
+ } else if (type === 'pre') {
|
|
|
+ if (data.list[data.listActive - 1]) {
|
|
|
+ handlePlay(data.list[data.listActive - 1]);
|
|
|
+ }
|
|
|
+ } else if (type === 'next') {
|
|
|
+ if (data.list[data.listActive + 1]) {
|
|
|
+ handlePlay(data.list[data.listActive + 1]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const getDetail = async () => {
|
|
|
+ data.loading = true;
|
|
|
+ let res = {} as any;
|
|
|
+ try {
|
|
|
+ res = await api_knowledgeWiki_detail({ id: route.query.id });
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ }
|
|
|
+ if (data.reshing) {
|
|
|
+ data.list = [];
|
|
|
+ data.reshing = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ data.finshed = true;
|
|
|
+ data.list = res.data.knowledgeWikiResources || [];
|
|
|
+ data.list.forEach((item: any) => {
|
|
|
+ item.audioFileUrl = item.url;
|
|
|
+ item.musicSheetName = item.name;
|
|
|
+ });
|
|
|
+ const knowledgeWikiCategories = res.data.knowledgeWikiCategories || [];
|
|
|
+ res.data.knowledgeName =
|
|
|
+ knowledgeWikiCategories.length > 0
|
|
|
+ ? knowledgeWikiCategories[0].knowledgeWikiCategoryTypeName
|
|
|
+ : '';
|
|
|
+ res.data.intros = res.data.intros.replace(
|
|
|
+ /<video/gi,
|
|
|
+ '<video style="width: 100% !important;" controlslist="nodownload"'
|
|
|
+ );
|
|
|
+ data.details = res.data;
|
|
|
+ data.loading = false;
|
|
|
+ };
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ getDetail();
|
|
|
+ });
|
|
|
+ return () => (
|
|
|
+ <div class={styles.container}>
|
|
|
+ <NSpace align="center" wrapItem={false} size={16}>
|
|
|
+ <img
|
|
|
+ style={{ cursor: 'pointer' }}
|
|
|
+ src={icon_back}
|
|
|
+ class={styles.iconBack}
|
|
|
+ onClick={() => {
|
|
|
+ const path =
|
|
|
+ forms.type === 'MUSICIAN'
|
|
|
+ ? '/content-musician'
|
|
|
+ : '/content-instruments';
|
|
|
+ router.push({ path });
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <NBreadcrumb separator="">
|
|
|
+ <NBreadcrumbItem
|
|
|
+ onClick={() => {
|
|
|
+ const path =
|
|
|
+ forms.type === 'MUSICIAN'
|
|
|
+ ? '/content-musician'
|
|
|
+ : '/content-instruments';
|
|
|
+ router.push({ path });
|
|
|
+ }}>
|
|
|
+ {forms.type === 'MUSICIAN' ? '音乐家' : '乐器百科'}
|
|
|
+ </NBreadcrumbItem>
|
|
|
+ <img class={styles.separator} src={icon_separator} />
|
|
|
+ <NBreadcrumbItem>{route.query.name}</NBreadcrumbItem>
|
|
|
+ </NBreadcrumb>
|
|
|
+ </NSpace>
|
|
|
+
|
|
|
+ <div class={[styles.wrap, data.showPlayer ? styles.wrapBottom : '']}>
|
|
|
+ <div class={styles.content}>
|
|
|
+ <div class={styles.contentWrap}>
|
|
|
+ <div class={[styles.musicList, 'musicList-container']}>
|
|
|
+ <div class={styles.wrapList}>
|
|
|
+ <div class={styles.instrumentGroup}>
|
|
|
+ <NImage
|
|
|
+ class={[
|
|
|
+ styles.instrumentImg,
|
|
|
+ forms.type === 'MUSICIAN' && styles.otherImg
|
|
|
+ ]}
|
|
|
+ src={data.details?.avatar}
|
|
|
+ objectFit="cover"
|
|
|
+ />
|
|
|
+
|
|
|
+ <p class={styles.instrumentName}>{data.details.name}</p>
|
|
|
+ <p class={styles.instrumentTag}>
|
|
|
+ {data.details.knowledgeName}
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class={styles.titlec}>
|
|
|
+ <i class={styles.icon2}></i>代表作
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {data.list.map((item: any, index: any) => {
|
|
|
+ return (
|
|
|
+ <div class={styles.itemContainer}>
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.item
|
|
|
+ // data.listActive === index && styles.active
|
|
|
+ ]}
|
|
|
+ onClick={(e: Event) => {
|
|
|
+ e.stopPropagation();
|
|
|
+ handlePlay(item);
|
|
|
+ }}>
|
|
|
+ <div class={styles.img}>
|
|
|
+ <NImage
|
|
|
+ lazy
|
|
|
+ objectFit="cover"
|
|
|
+ previewDisabled={true}
|
|
|
+ src={item.titleImg || icon_default}
|
|
|
+ onLoad={e => {
|
|
|
+ (e.target as any).dataset.loaded = 'true';
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <PlayLoading
|
|
|
+ class={[
|
|
|
+ data.listActive === index &&
|
|
|
+ data.playState === 'play'
|
|
|
+ ? ''
|
|
|
+ : styles.showPlayLoading
|
|
|
+ ]}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class={styles.title}>
|
|
|
+ <div class={styles.titleName}>
|
|
|
+ <TheNoticeBar
|
|
|
+ text={item.name}
|
|
|
+ style={{ marginRight: '12px' }}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <NButton
|
|
|
+ color="#259CFE"
|
|
|
+ textColor="#fff"
|
|
|
+ round
|
|
|
+ class={styles.btn}
|
|
|
+ type="primary"
|
|
|
+ onClick={(e: Event) => {
|
|
|
+ e.stopPropagation();
|
|
|
+ handlePlay(item);
|
|
|
+ }}>
|
|
|
+ 播放
|
|
|
+ <img
|
|
|
+ src={
|
|
|
+ data.listActive === index &&
|
|
|
+ data.playState === 'play'
|
|
|
+ ? icon_pause
|
|
|
+ : icon_play
|
|
|
+ }
|
|
|
+ />
|
|
|
+ </NButton>
|
|
|
+
|
|
|
+ <img class={styles.arrow} src={icon_arrow} />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ })}
|
|
|
+ {!data.finshed && (
|
|
|
+ <div class={styles.loadingWrap}>
|
|
|
+ <NSpin show={true}></NSpin>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ {!data.loading && data.list.length === 0 && (
|
|
|
+ <div class={styles.empty}>
|
|
|
+ <TheEmpty description="暂无代表作"></TheEmpty>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class={styles.musicStaff}>
|
|
|
+ <div class={styles.musicTitle}>
|
|
|
+ <i
|
|
|
+ class={
|
|
|
+ forms.type === 'MUSICIAN' ? styles.icon3 : styles.icon1
|
|
|
+ }></i>
|
|
|
+ {forms.type === 'MUSICIAN' ? '个人简介' : '乐器简介'}
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class={styles.musicContent}
|
|
|
+ v-html={data.details?.intros}
|
|
|
+ style={{ fontSize: data.fontSize + 'px' }}></div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class={styles.changeSizeSection}>
|
|
|
+ <img src={iconT} class={styles.iconT} />
|
|
|
+ <img
|
|
|
+ src={iconAddT}
|
|
|
+ class={styles.iconAddT}
|
|
|
+ onClick={() => {
|
|
|
+ if (data.fontSize >= 32) return;
|
|
|
+ data.fontSize += 1;
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <NSlider
|
|
|
+ v-model:value={data.fontSize}
|
|
|
+ vertical
|
|
|
+ min={12}
|
|
|
+ max={32}
|
|
|
+ />
|
|
|
+ <img
|
|
|
+ src={iconPlusT}
|
|
|
+ class={styles.iconPlusT}
|
|
|
+ onClick={() => {
|
|
|
+ if (data.fontSize <= 12) return;
|
|
|
+ data.fontSize -= 1;
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {data.list.length !== 0 && (
|
|
|
+ <PlayItem
|
|
|
+ show={data.showPlayer}
|
|
|
+ playState={data.playState}
|
|
|
+ item={activeItem.value}
|
|
|
+ onChange={value => handleChangeAudio(value)}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+});
|