Explorar o código

到视频课列表

1
mo %!s(int64=2) %!d(string=hai) anos
pai
achega
08c87a7183

+ 7 - 1
src/components/albumItem/index.tsx

@@ -4,6 +4,7 @@ import classes from './index.module.less'
 import hold from './images/hold.png'
 import start from './images/start.png'
 import pan from './images/pan.png'
+import { useRouter } from 'vue-router'
 export default defineComponent({
   name: 'albumItem',
   props: {
@@ -35,9 +36,14 @@ export default defineComponent({
     const state = reactive({
       detail: props.detail
     })
+    const router = useRouter()
+    const gotoAlbum = ()=>{
+
+      router.push({path:'/albumDetail',query:{id:state.detail.id}})
+    }
     return () => (
       <>
-        <div class={classes.itemWrap}>
+        <div class={classes.itemWrap} onClick={()=>{gotoAlbum()}}>
           <img
             src={state.detail.albumCoverUrl ? state.detail.albumCoverUrl : hold}
             alt=""

BIN=BIN
src/components/hotSearch/images/clearIcon.png


+ 115 - 2
src/components/hotSearch/index.module.less

@@ -1,4 +1,5 @@
 .wrap {
+  margin-top: 20px;
   display: flex;
   flex-direction: row;
   align-items: center;
@@ -27,7 +28,7 @@
     display: flex;
     flex-direction: row;
     cursor: pointer;
-    font-size: 18px;
+    font-size: 16px;
     span {
       color: #666;
     }
@@ -40,7 +41,7 @@
   .searchWrap {
     cursor: pointer;
     span {
-      color: #000!important;
+      color: #000 !important;
       line-height: 28px;
     }
     .search {
@@ -48,6 +49,118 @@
       height: 28px;
       margin-left: 8px;
     }
+  }
+}
 
+.searchDetail {
+  .searchResult {
+    // height: 58px;
+    line-height: 58px;
+    display: flex;
+    flex-direction: row;
+    .resultTitle {
+      padding: 0 20px 0 14px;
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      color: #999;
+      font-size: 18px;
+      img {
+        width: 14px;
+        height: 14px;
+        margin-left: 4px;
+      }
+    }
+    .tagList {
+      width: 1010px;
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+    }
+    .clearBtn {
+      cursor: pointer;
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      font-size: 16px;
+      font-family: PingFangSC-Regular, PingFang SC;
+      font-weight: 400;
+      color: #666666;
+      .clearIcon {
+        width: 28px;
+        height: 28px;
+        margin-left: 6px;
+      }
+    }
+  }
+  .searchChioseWrap {
+    background-color: #fff;
+    border-radius: 8px;
+    padding: 20px;
+    .chioseLineWrap {
+      border-bottom: 1px solid #ededed;
+      .chioseRow {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        p {
+          margin-bottom: 14px;
+          width: 112px;
+          text-align: center;
+          margin-right: 5px;
+        }
+        .chioseTagWrap {
+          flex: 1;
+          &::before {
+            position: absolute;
+            content: '';
+            width: 1px;
+            height: calc(100% - 14px);
+            background: #ededed;
+            left: 0;
+          }
+          position: relative;
+          padding-left: 20px;
+          /deep/.el-tag {
+            margin-bottom: 14px;
+          }
+        }
+      }
+    }
+  }
+  .submitBtn {
+    width: 194px;
+    height: 42px;
+    background: #2dc7aa;
+    border-radius: 23px;
+    text-align: center;
+    line-height: 42px;
+    margin: 18px auto 0;
+    color: #fff;
+    cursor: pointer;
+  }
+}
+:global {
+  .el-tag--Light,.el-tag--light {
+    border: 1px solid #2dc7aa;
+    font-size: 14px;
+    font-family: PingFangSC-Medium, PingFang SC;
+    font-weight: 500;
+    color: #2dc7aa;
+    line-height: 20px;
+    border-radius: 6px;
+  }
+  .chioseTagWrap {
+    .el-tag {
+      margin-bottom: 14px;
+      margin-right: 12px;
+      cursor: pointer;
+      &:last-child {
+        margin-right: 0 !important;
+      }
+    }
+  }
+  .chioseTag {
+    margin-right: 14px;
   }
 }

+ 191 - 25
src/components/hotSearch/index.tsx

@@ -1,25 +1,35 @@
 import { defineComponent, toRefs, reactive, onMounted, ref } from 'vue'
-
+import { ElButton, ElTag } from 'element-plus'
 import classes from './index.module.less'
 import tagItem from '@/components/tagItem'
 import hot from './images/hot.png'
 import arrow from '@/components/musicLIstItem/images/arrow.png'
 import search from '@/components/hotSearch/images/search.png'
 import request from '@/helpers/request'
+import clearIcon from './images/clearIcon.png'
+import item from '@/views/user-info/components/item'
+import { useRouter } from 'vue-router'
 export default defineComponent({
   name: 'hotSearch',
   components: { tagItem },
+  emits:['searchRust','hotTag'],
   props: {
     type: {
       type: String,
       default: 'more'
     }
   },
-  setup(props) {
+  setup(props,conent) {
     const state = reactive({
       hotList: [],
-      type: props.type
+      type: props.type,
+      showDetail: true,
+      tagTree: [],
+      chioseTagList: [],
+      chioseParentList: [],
+      searchTagList: []
     })
+    const router = useRouter()
     const getHotList = async () => {
       try {
         const res = await request.get('/api-website/open/music/sheet/hotTag', {
@@ -33,37 +43,193 @@ export default defineComponent({
         console.log(e)
       }
     }
+
+    const getTagTree = async () => {
+      try {
+        const res = await request.get('/api-website/open/MusicTag/tree', {})
+        state.tagTree = res.data
+
+        // state.hotList = res.data
+      } catch (e) {
+        console.log(e)
+      }
+    }
+
+    const chioseTag = (tag: any) => {
+      // 选择判断
+
+      let chioseParentIndex = state.chioseParentList.indexOf(
+        tag.parentTagId as never
+      )
+      let chioseIndex = state.chioseTagList.indexOf(tag.id as never)
+      if (chioseParentIndex !== -1 && chioseIndex !== -1) {
+        // 这里就是反复点击这一个
+        tag.isCheck = false
+        state.chioseParentList.splice(chioseParentIndex, 1)
+        state.chioseTagList.splice(chioseIndex, 1)
+        setSearchTagList()
+        return
+      }
+
+      if (chioseIndex == -1 && chioseParentIndex == -1) {
+        state.chioseParentList.push(tag.parentTagId as never)
+        state.chioseTagList.push(tag.id as never)
+        tag.isCheck = true
+        // 添加进去 并且设置其余的元素不可点击
+        setSearchTagList()
+        return
+      }
+
+      if (chioseIndex !== -1 || chioseParentIndex !== -1) {
+        // 选的没有且父元素也没有选中
+        state.tagTree.forEach((tree: any) => {
+          if (tree.id == tag.parentTagId) {
+            tree.children.forEach((item: any) => {
+              item.isCheck = false
+              let index = state.chioseTagList.indexOf(item.id as never)
+              if (index !== -1) {
+                state.chioseTagList.splice(index, 1)
+              }
+            })
+          }
+        })
+        tag.isCheck = true
+        state.chioseTagList.push(tag.id as never)
+        setSearchTagList()
+        return
+      }
+    }
+    const setSearchTagList = () => {
+      state.searchTagList = []
+      state.tagTree.forEach((tree: any) => {
+        tree.children.forEach((item: any) => {
+          if (state.chioseTagList.indexOf(item.id as never) != -1) {
+            state.searchTagList.push(item as never)
+          }
+        })
+      })
+      console.log(state.searchTagList, 'searchTagList')
+    }
+    const isChiose = (tag: any) => {
+      if (tag.isCheck) {
+        return 'dark'
+      } else {
+        return 'light'
+      }
+    }
+
+    const closeChioseTag = (tag: any) => {
+      chioseTag(tag)
+    }
+    const clearSearch = () => {
+      state.chioseTagList = []
+      state.chioseParentList = []
+      state.searchTagList = []
+      state.tagTree.forEach((tree: any) => {
+        tree.children.forEach((item: any) => {
+          item.isCheck = false
+        })
+      })
+    }
+    const searchSubmit = ()=>{
+      // 请求
+      conent.emit('searchRust',state.chioseTagList)
+      state.showDetail = true
+    }
+
+    const clickHotTag = (key:string)=>{
+      conent.emit('hotTag',key)
+    }
+    const gotoSearch = ()=>{
+      router.push({path:'/searchdetail'})
+    }
     onMounted(() => {
       getHotList()
+      getTagTree()
     })
     return () => (
       <>
-        <div class={classes.wrap}>
-          <div class={classes.wrapLeft}>
-            <img src={hot} class={classes.hotIcon} alt="" />
-            <h5>热门搜索:</h5>
-            <div class={classes.tagWrap}>
-              {state.hotList.map((item: any) => {
-                return <tagItem title={item.key}></tagItem>
-              })}
+        {state.showDetail ? (
+          <div class={classes.wrap}>
+            <div class={classes.wrapLeft}>
+              <img src={hot} class={classes.hotIcon} alt="" />
+              <h5>热门搜索:</h5>
+              <div class={classes.tagWrap}>
+                {state.hotList.map((item: any) => {
+                  //
+                  return <tagItem title={item.key} onSearchTag={(key)=>clickHotTag(key)}>{item.key}</tagItem>
+                })}
+              </div>
             </div>
+            {state.type == 'more' ? (
+              <div class={classes.wrapRight} onClick={gotoSearch}>
+                <span>更多</span>
+                <img class={classes.arrow} src={arrow} alt="" />
+              </div>
+            ) : null}
+            {state.type == 'search' ? (
+              <div class={[classes.wrapRight, classes.searchWrap]} onClick={()=>state.showDetail = false}>
+                <span>筛选</span>
+                <img class={classes.search} src={search} alt="" />
+              </div>
+            ) : null}
           </div>
-          {state.type == 'more' ? (
-            <div class={classes.wrapRight}>
-              <span>更多</span>
-              <img class={classes.arrow} src={arrow} alt="" />
+        ) : (
+          <div class={classes.searchDetail}>
+            <div class={classes.searchResult}>
+              <div class={classes.resultTitle}>
+                <span>搜索结果</span>
+                <img src={arrow} alt="" />
+              </div>
+              <div class={classes.tagList}>
+                {state.searchTagList.map((item: any) => {
+                  return (
+                    <ElTag
+                      closable
+                      onClose={() => closeChioseTag(item)}
+                      class="chioseTag"
+                      size="large"
+                    >
+                      {item.name}
+                    </ElTag>
+                  )
+                })}
+              </div>
+              <div class={classes.clearBtn} onClick={clearSearch}>
+                <span>清空</span>
+                <img src={clearIcon} class={classes.clearIcon} alt="" />
+              </div>
             </div>
-          ) : null}
-          {state.type == 'search' ? (
-            <div class={[classes.wrapRight, classes.searchWrap]}>
-              <span>筛选</span>
-              <img class={classes.search} src={search} alt="" />
+            <div class={classes.searchChioseWrap}>
+              <div class={classes.chioseLineWrap}>
+                {state.tagTree.map((tree: any) => {
+                  return (
+                    <div class={classes.chioseRow}>
+                      <p>{tree.name}:</p>
+                      <div class={[classes.chioseTagWrap, 'chioseTagWrap']}>
+                        {tree.children.map((tag: any) => {
+                          return (
+                            <ElTag
+                              class={classes.tags}
+                              size="large"
+                              effect={isChiose(tag)}
+                              onClick={() => {
+                                chioseTag(tag)
+                              }}
+                            >
+                              {tag.name}
+                            </ElTag>
+                          )
+                        })}
+                      </div>
+                    </div>
+                  )
+                })}
+              </div>
+              <div class={classes.submitBtn} onClick={searchSubmit}>搜索</div>
             </div>
-          ) : null}
-        </div>
-        <div class={classes.searchDetail}>
-          <div ></div>
-        </div>
+          </div>
+        )}
       </>
     )
   }

+ 1 - 1
src/components/searchInput/index.module.less

@@ -1,6 +1,6 @@
 
 .wrap {
-  margin-bottom: 20px;
+  // margin-bottom: 20px;
 }
 .inputSelect {
   line-height: 54px;

+ 43 - 18
src/components/searchInput/index.tsx

@@ -1,5 +1,5 @@
 import { Search } from '@element-plus/icons-vue'
-import { defineComponent, toRefs, reactive, onMounted, ref } from 'vue'
+import { defineComponent, toRefs, reactive, onMounted, ref, watch } from 'vue'
 import {
   ElButton,
   ElForm,
@@ -10,7 +10,7 @@ import {
   ElIcon
 } from 'element-plus'
 
-import white from './while.module.less';
+import white from './while.module.less'
 import classes from './index.module.less'
 import request from '@/helpers/request'
 
@@ -21,45 +21,66 @@ export default defineComponent({
       type: String,
       default: ''
     },
-    isWhile:{
+    isWhile: {
       type: Boolean,
       default: true
+    },
+    searchVal: {
+      type: String,
+      default: ''
     }
   },
+  emits: ['startSearch'],
   setup(props, conent) {
     const state = reactive({
       title: props.title,
-      search: '',
+      search: props.searchVal,
       subject: '',
-      subjectList:[]
+      subjectList: []
     })
-
-    const getSubjectList = async ()=>{
+    watch(
+      () => props.searchVal,
+      searchVal => {
+        state.search = searchVal
+      }
+    )
+    const getSubjectList = async () => {
       try {
-        const res = await request.get('/api-website/open/subject/subjectSelect', {
-        })
+        const res = await request.get(
+          '/api-website/open/subject/subjectSelect',
+          {}
+        )
 
         state.subjectList = res.data
       } catch (e) {
         console.log(e)
       }
     }
-    onMounted(()=>{
+
+    const startSearch = () => {
+      conent.emit('startSearch', {
+        search: state.search,
+        subject: state.subject
+      })
+    }
+    onMounted(() => {
       getSubjectList()
     })
     let classStyle
-    props.isWhile? classStyle=white: classStyle=classes
+    props.isWhile ? (classStyle = white) : (classStyle = classes)
     return () => (
       <>
-        <div class={[classStyle.wrap,props.isWhile?'While':'']}>
+        <div class={[classStyle.wrap, props.isWhile ? 'While' : '']}>
           <ElInput
+          clearable
             v-model={state.search}
             placeholder="搜一搜你想练习的曲目"
             class={classStyle.inputSelect}
             v-slots={{
               prepend: () => (
-                <div   class={classStyle.selectWrap}>
+                <div class={classStyle.selectWrap}>
                   <ElSelect
+                   clearable
                     v-model={state.subject}
                     placeholder="请选择声部"
                     style="width: 115px"
@@ -68,20 +89,24 @@ export default defineComponent({
                       suffix: () => <div class={classStyle.san}></div>
                     }}
                   >
-                    {state.subjectList.map((item:any) => <ElOption label={item.name} value={item.id} />)}
+                    {state.subjectList.map((item: any) => (
+                      <ElOption label={item.name} value={item.id} />
+                    ))}
                   </ElSelect>
                   <div class={classStyle.line}></div>
                 </div>
               ),
               append: () => (
                 <ElButton
+                  onClick={startSearch}
                   v-slots={{
-                    icon:()=><ElIcon  class={classStyle.searchIcon} >
-                      <Search></Search>
-                    </ElIcon>
+                    icon: () => (
+                      <ElIcon class={classStyle.searchIcon}>
+                        <Search></Search>
+                      </ElIcon>
+                    )
                   }}
                   style={{ color: '#2DC7AA', font: '20px' }}
-
                 />
               )
             }}

+ 1 - 1
src/components/searchInput/while.module.less

@@ -1,5 +1,5 @@
 .wrap {
-  margin-bottom: 20px;
+  // margin-bottom: 20px;
 }
 .inputSelect {
   line-height: 54px;

+ 6 - 2
src/components/tagItem/index.tsx

@@ -1,10 +1,11 @@
 
 import { defineComponent , toRefs, reactive, onMounted, ref } from 'vue'
-
+import { ElTag } from 'element-plus'
 import classes from './index.module.less'
 
 export default defineComponent({
   name: 'tagItem',
+  emits:['searchTag'],
   props: {
     title: {
       type: String,
@@ -15,9 +16,12 @@ export default defineComponent({
     const state = reactive({
       title:props.title
     })
+    const shioseTag =(key:string)=>{
+      conent.emit('searchTag',key)
+    }
     return () => (
       <>
-        <div class={classes.tag}>{state.title}</div>
+        <ElTag size="large" onClick={()=>shioseTag(state.title)} class={classes.tag}>{state.title}</ElTag>
       </>
     )
   }

+ 1 - 0
src/components/videoDetailItem/index.module.less

@@ -4,6 +4,7 @@
   margin-right: 20px;
   border-radius: 4px;
   background-color: #fff;
+  cursor: pointer;
   &:nth-child(3n){
     margin-right:0;
   }

+ 6 - 1
src/components/videoDetailItem/index.tsx

@@ -3,6 +3,7 @@ import { defineComponent, toRefs, reactive, onMounted, ref} from 'vue'
 import classes from './index.module.less'
 import detaile from './images/detaile.png'
 import icon from './images/icon.png'
+import { useRouter } from 'vue-router'
 export default defineComponent({
   name: 'albumItem',
   props: {
@@ -28,9 +29,13 @@ export default defineComponent({
     const state = reactive({
       detail:props.detail
     })
+    const router = useRouter()
+    const gotoVideoDetail = ()=>{
+      router.push({path:'/videoDetail',query:{id:state.detail.id}})
+    }
     return () => (
       <>
-        <div class={classes.itemWrap}>
+        <div class={classes.itemWrap} onClick={gotoVideoDetail}>
           <img src={state.detail.lessonCoverUrl?state.detail.lessonCoverUrl:detaile} alt="" class={classes.detaile} />
           <div class={classes.itemBottom}>
             <div class={classes.itemBottomL}>

+ 14 - 3
src/views/albumDetail/index.tsx

@@ -12,6 +12,8 @@ import pagination from '@/components/pagination'
 import albumItem from './modals/albumItem'
 import request from '@/helpers/request'
 import musicLIstItem from '@/components/musicLIstItem'
+import { useRoute, useRouter } from 'vue-router'
+import { watch } from 'fs'
 export default defineComponent({
   name: 'albumDetail',
   props: {
@@ -27,6 +29,7 @@ export default defineComponent({
       hotList: [],
       hotTagList:[],
       relatedMusicAlbum:[],
+      id:'',
       musicList: [],
       pageInfo: {
         // 分页规则
@@ -37,11 +40,12 @@ export default defineComponent({
       },
       details:{} as any
     })
+    const route = useRoute()
     const getList = async () => {
       try{
         const res = await request.post('/api-website/open/music/album/detail', {
           data: {
-            id: 15,
+            id: state.id,
             page: state.pageInfo.page,
             rows: state.pageInfo.limit
           }
@@ -57,8 +61,15 @@ export default defineComponent({
       }
     }
     onMounted(()=>{
+      if(route.query.id){
+        state.id = route.query.id as string
+      }
       getList()
     })
+    const getDetail = (id:number|string)=>{
+      state.id = id as string;
+      getList()
+    }
     return () => (
       <>
         <div class={classes.wall}></div>
@@ -134,7 +145,7 @@ export default defineComponent({
               </div>
 
               <div class={classes.someWrap}>
-                {state.relatedMusicAlbum.map(item=> <albumItem detail={item}></albumItem>)}
+                {state.relatedMusicAlbum.map(item=> <albumItem detail={item} onAlbumDetail={(id)=>getDetail(id)}></albumItem>)}
 
               </div>
             </div>
@@ -151,7 +162,7 @@ export default defineComponent({
               </div>
 
               <div class={classes.someWrap}>
-              {state.hotList.map(item=> <albumItem detail={item}></albumItem>)}
+              {state.hotList.map(item=> <albumItem detail={item} onAlbumDetail={(id)=>getDetail(id)}></albumItem>)}
               </div>
             </div>
           </div>

+ 8 - 2
src/views/albumDetail/modals/albumItem.tsx

@@ -2,6 +2,7 @@ import { defineComponent, toRefs, reactive, onMounted, ref } from 'vue'
 
 import classes from './index.module.less'
 import hold from '@/components/albumItem/images/hold.png'
+import { useRouter } from 'vue-router'
 export default defineComponent({
   name: 'albumItem',
   props: {
@@ -29,13 +30,18 @@ export default defineComponent({
       }
     }
   },
-  setup(props) {
+  emits:['albumDetail'],
+  setup(props,conent) {
     const state = reactive({
       detail: props.detail
     })
+    const router = useRouter()
+    const gotoAlbum = ()=>{
+      conent.emit('albumDetail',state.detail.id)
+    }
     return () => (
       <>
-        <div class={classes.itemWrap}>
+        <div class={classes.itemWrap} onClick={gotoAlbum}>
           <img
             src={state.detail.albumCoverUrl ? state.detail.albumCoverUrl : hold}
             alt=""

+ 13 - 4
src/views/home/index.tsx

@@ -13,6 +13,7 @@ import 'swiper/css'
 import 'swiper/css/navigation'
 import 'swiper/css/pagination'
 import 'swiper/css/scrollbar'
+import { useRouter } from 'vue-router'
 export default defineComponent({
   name: 'home',
   components: {
@@ -27,7 +28,7 @@ export default defineComponent({
       albumList: [],
       videoList: []
     })
-
+    const router = useRouter()
     const getAlbumList = async () => {
       try {
         const res = await request.post('/api-website/open/music/album/list', {
@@ -61,7 +62,15 @@ export default defineComponent({
         console.log(e)
       }
     }
+    const gotoSearch = (val:string)=>{
+      router.push({path:'/searchdetail',query:{search:val}})
+    }
 
+
+    const gotoVideoList = ()=>{
+      router.push({path:'/videoDetailList'})
+    }
+    //
     onMounted(() => {
       getAlbumList()
       getVideoList()
@@ -77,10 +86,10 @@ export default defineComponent({
                 <h4>热门专辑</h4>
                 <img src={titleDot} class={styles.dotImg} alt="" />
               </div>
-              <hotSearch></hotSearch>
+              <hotSearch onHotTag={(val:string)=>{gotoSearch(val)}}></hotSearch>
               <div class={styles.albumList}>
                 {state.albumList.map(item => {
-                  return <albumItem detail={item}></albumItem>
+                  return  <albumItem detail={item} ></albumItem>
                 })}
               </div>
             </div>
@@ -96,7 +105,7 @@ export default defineComponent({
               </div>
               <div class={styles.videoNav}>
                 <h5>精品视频课</h5>
-                <div class={styles.wrapRight}>
+                <div class={styles.wrapRight} onClick={()=>gotoVideoList()}>
                   <span>更多</span>
                   <img class={styles.arrow} src={arrow} alt="" />
                 </div>

+ 26 - 14
src/views/musicLibrary/modals/searchAlbum.tsx

@@ -28,6 +28,7 @@ export default defineComponent({
     const state = reactive({
       albumList: [],
       musicList: [],
+      search: {},
       pageInfo: {
         // 分页规则
         limit: 5, // 限制显示条数
@@ -42,8 +43,9 @@ export default defineComponent({
         const res = await request.post('/api-website/open/music/album/list', {
           data: {
             albumStatus: 1,
+            ...state.search,
             page: state.pageInfo.page,
-            rows: state.pageInfo.limit,
+            rows: state.pageInfo.limit
           }
         })
 
@@ -53,31 +55,41 @@ export default defineComponent({
         console.log(e)
       }
     }
-    onMounted(() => {
+    const getList = (val: any) => {
+      state.search = { ...val }
+      state.pageInfo.page = 1
       getAlbumList()
+    }
+    onMounted(() => {
+      // getAlbumList()
       // getMusicList()
     })
-    return () => (
+    return {
+      ...toRefs(state),
+      getList,
+      getAlbumList
+    }
+  },
+  render() {
+    return (
       <div>
-        <div >
+        <div>
           <div class={styles.w1200}>
             <div class={styles.section}>
-            <div class={styles.albumList}>
-                {state.albumList.map(item=>{
-                  return  <albumItem detail={item}></albumItem>
+              <div class={styles.albumList}>
+                {this.albumList.map(item => {
+                  return <albumItem detail={item}></albumItem>
                 })}
-
-
               </div>
             </div>
           </div>
         </div>
         <pagination
-          total={state.pageInfo.total}
-          v-model:page={state.pageInfo.page}
-          limit={state.pageInfo.limit}
-          pageSizes={state.pageInfo.page_size}
-          pagination={getAlbumList}
+          total={this.pageInfo.total}
+          v-model:page={this.pageInfo.page}
+          limit={this.pageInfo.limit}
+          pageSizes={this.pageInfo.page_size}
+          pagination={this.getAlbumList}
         />
       </div>
     )

+ 27 - 12
src/views/musicLibrary/modals/searchMusic.tsx

@@ -27,14 +27,14 @@ export default defineComponent({
   },
   setup() {
     const state = reactive({
-      albumList: [],
       musicList: [],
+      search:{},
       pageInfo: {
         // 分页规则
         limit:5, // 限制显示条数
         page: 1, // 当前页
         total: 0, // 总条数
-        page_size: [10, 20, 40, 50] // 选择限制显示条数
+        page_size: [5,10, 20, 40, 50] // 选择限制显示条数
       }
     })
 
@@ -58,6 +58,7 @@ export default defineComponent({
         const res = await request.post('/api-website/open/music/sheet/list', {
           data: {
             albumStatus: 'PASS',
+            ...state.search,
             page: state.pageInfo.page,
             rows: state.pageInfo.limit,
             state: 1
@@ -70,18 +71,32 @@ export default defineComponent({
         console.log(e)
       }
     }
-
+    const getList = (val: any) => {
+      console.log(val)
+      state.search = {subjectIds:val.subject,
+        musicTagIds:val.albumTagIds,
+        idAndName:val.search }
+      state.pageInfo.page = 1
+      getMusicList()
+    }
     onMounted(() => {
       // getAlbumList()
-      getMusicList()
+      // getList(state.search)
     })
-    return () => (
+    return {
+      ...toRefs(state),
+      getList,
+      getMusicList,
+
+    }},
+    render() {
+     return(
       <div>
         <div>
           <div class={styles.w1200}>
             <div class={styles.section}>
               <div class={styles.musicList}>
-                {state.musicList.map(item => {
+                {this.musicList.map(item => {
                   return <musicListItem item={item}></musicListItem>
                 })}
               </div>
@@ -89,13 +104,13 @@ export default defineComponent({
           </div>
         </div>
         <pagination
-          total={state.pageInfo.total}
-          v-model:page={state.pageInfo.page}
-          limit={state.pageInfo.limit}
-          pageSizes={state.pageInfo.page_size}
-          pagination={getMusicList}
+          total={this.pageInfo.total}
+          v-model:page={this.pageInfo.page}
+          limit={this.pageInfo.limit}
+          pageSizes={this.pageInfo.page_size}
+          pagination={this.getMusicList}
         />
       </div>
     )
-  }
+              }
 })

+ 73 - 36
src/views/musicLibrary/searchdetail.tsx

@@ -13,6 +13,7 @@ import 'swiper/css/navigation'
 import 'swiper/css/pagination'
 import 'swiper/css/scrollbar'
 import { ElTabPane, ElTabs } from 'element-plus'
+import { useRoute } from 'vue-router'
 export default defineComponent({
   name: 'searchdetail',
   components: {
@@ -26,59 +27,95 @@ export default defineComponent({
     const state = reactive({
       albumList: [],
       musicList: [],
-      chiose: 'album'
+      chiose: 'album',
+      searchs:{
+        albumTagIds:'',
+        search:'',
+        subject:''
+      }
     })
+    const route = useRoute()
+    const searchAlbumRef = ref()
+    const searchMusicRef = ref()
+    // const getAlbumList = async () => {
+    //   try {
+    //     const res = await request.post('/api-website/open/music/album/list', {
+    //       data: {
+    //         albumStatus: 1,
+    //         page: 1,
+    //         rows: 10
+    //       }
+    //     })
 
-    const getAlbumList = async () => {
-      try {
-        const res = await request.post('/api-website/open/music/album/list', {
-          data: {
-            albumStatus: 1,
-            page: 1,
-            rows: 10
-          }
-        })
+    //     state.albumList = res.data.rows
+    //   } catch (e) {
+    //     console.log(e)
+    //   }
+    // }
+    // const getMusicList = async () => {
+    //   try {
+    //     const res = await request.post('/api-website/open/music/sheet/list', {
+    //       data: {
+    //         albumStatus: 'PASS',
+    //         page: 1,
+    //         rows: 5,
+    //         state: 1
+    //       }
+    //     })
 
-        state.albumList = res.data.rows
-      } catch (e) {
-        console.log(e)
-      }
+    //     state.musicList = res.data.rows
+    //   } catch (e) {
+    //     console.log(e)
+    //   }
+    // }
+    const searchRust = (val:any)=>{
+      state.searchs.albumTagIds = val.join(',') as string
+      startSearch(state.searchs)
+    }
+    const startSearch = (val:any)=>{
+     state.searchs = {...state.searchs,...val}
+     search()
     }
-    const getMusicList = async () => {
-      try {
-        const res = await request.post('/api-website/open/music/sheet/list', {
-          data: {
-            albumStatus: 'PASS',
-            page: 1,
-            rows: 5,
-            state: 1
-          }
-        })
 
-        state.musicList = res.data.rows
-      } catch (e) {
-        console.log(e)
+    const search = ()=>{
+      if(state.chiose == 'album'){
+       searchAlbumRef.value.getList(state.searchs)
+      }
+      if(state.chiose == 'music' ){
+        searchMusicRef.value.getList(state.searchs)
       }
     }
-
     onMounted(() => {
-      getAlbumList()
-      getMusicList()
+      if(route.query.search){
+        state.searchs.search = route.query.search as string
+      }
+      search()
+      // getAlbumList()
+      // getMusicList()
     })
-    return () => (
+    return {
+      ...toRefs(state),
+      startSearch,
+      searchRust,
+      searchAlbumRef,
+      searchMusicRef
+    }
+  },
+    render() {
+    return  (
       <div>
         <div class="">
           <div class="wall" style={{ height: '70px' }}></div>
           <div class={styles.w1200}>
             <div class={styles.section}>
-              <searchInput isWhile={true}></searchInput>
-              <hotSearch type={'search'}></hotSearch>
-              <ElTabs class={styles.myTab} v-model={state.chiose}>
+              <searchInput isWhile={true} searchVal={this.searchs.search} onStartSearch={(val:any)=>{this.startSearch(val)}}></searchInput>
+              <hotSearch type={'search'} onSearchRust={(val:any)=>this.searchRust(val)} onHotTag={(val:string)=>{this.searchs.search = val}}></hotSearch>
+              <ElTabs class={styles.myTab} v-model={this.chiose}>
                 <ElTabPane label="专辑" name="album">
-                  {state.chiose == 'album' ? <searchAlbum /> : null}
+                  {this.chiose == 'album' ? <searchAlbum ref='searchAlbumRef'/> : null}
                 </ElTabPane>
                 <ElTabPane label="乐谱" name="music">
-                  {state.chiose == 'music' ? <searchMusic /> : null}
+                  {this.chiose == 'music' ? <searchMusic ref='searchMusicRef'/> : null}
                 </ElTabPane>
               </ElTabs>
             </div>

BIN=BIN
src/views/videoDetailList/images/player.png


BIN=BIN
src/views/videoDetailList/images/teacher.png


+ 188 - 1
src/views/videoDetailList/index.module.less

@@ -40,7 +40,6 @@
     }
   }
   .courseInfo {
-
     margin-top: 10px;
     padding-bottom: 20px;
     border-bottom: 1px solid #f0f0f0;
@@ -52,3 +51,191 @@
     }
   }
 }
+
+.courseListWrap {
+  margin-top: 16px;
+  .courseTitle {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 16px;
+    .courseTitleLeft {
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-start;
+      font-size: 20px;
+      font-family: PingFangSC-Medium, PingFang SC;
+      font-weight: 500;
+      color: #000000;
+      line-height: 28px;
+      align-items: center;
+      img {
+        width: 26px;
+        height: 26px;
+        margin-right: 8px;
+      }
+    }
+    .courseTitlTimer {
+      font-size: 20px;
+      font-family: PingFangSC-Medium, PingFang SC;
+      font-weight: 500;
+      color: #2dc7aa;
+      line-height: 28px;
+    }
+  }
+}
+
+.detailRight {
+  width: 494px;
+  .teacherInfo {
+    padding: 20px;
+    background-color: #fff;
+    .teacherHeadWrap {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      justify-content: space-between;
+      .teacherHeadLeft {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        .teacherHeader {
+          width: 54px;
+          height: 54px;
+          border-radius: 50%;
+          overflow: hidden;
+          margin-right: 16px;
+        }
+        .teacherHeadName {
+          padding-top: 2px;
+          display: flex;
+          flex-direction: row;
+          align-items: center;
+          font-size: 20px;
+          font-family: PingFangSC-Semibold, PingFang SC;
+          font-weight: 600;
+          color: #000000;
+          line-height: 28px;
+          span {
+            margin-right: 12px;
+          }
+          .teacherIcon {
+            width: 54px;
+            height: 22px;
+          }
+        }
+        .fens {
+          font-size: 16px;
+          font-family: PingFangSC-Regular, PingFang SC;
+          font-weight: 400;
+          color: #999999;
+          line-height: 22px;
+          span {
+            color: #333333;
+          }
+        }
+      }
+      .teacherHeadRight {
+        width: 67px;
+        height: 30px;
+        background: #2dc7aa;
+        border-radius: 21px;
+        font-size: 18px;
+        font-family: PingFangSC-Semibold, PingFang SC;
+        font-weight: 600;
+        color: #ffffff;
+        line-height: 30px;
+        text-align: center;
+        cursor: pointer;
+      }
+    }
+    //
+    .courseWrap {
+      padding: 20px;
+      background-color: #fff;
+      .courseTitle {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        font-size: 20px;
+        font-family: PingFangSC-Medium, PingFang SC;
+        font-weight: 500;
+        color: #000000;
+        line-height: 28px;
+        img {
+          width: 26px;
+          height: 26px;
+          margin-right: 8px;
+        }
+      }
+    }
+
+    .titleWrap {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      justify-content: flex-start;
+      margin-top: 20px;
+      padding-bottom: 12px;
+      span {
+        font-size: 20px;
+        color: #000;
+        line-height: 28px;
+        font-weight: 600;
+      }
+      img {
+        width: 24px;
+        height: 24px;
+        margin-right: 10px;
+      }
+    }
+    .teacherDetail {
+      font-size: 18px;
+      font-family: PingFangSC-Regular, PingFang SC;
+      font-weight: 400;
+      color: #666666;
+      line-height: 25px;
+    }
+    .teacherVideoList {
+      display: flex;
+      flex-direction: row;
+      .videoItem {
+        .Styles {
+          width: 218px;
+          height: 145px;
+        }
+        margin-right: 18px;
+        margin-bottom: 12px;
+        width: 218px;
+        height: 145px;
+        position: relative;
+        &:nth-child(2n) {
+          margin-right: 0;
+        }
+      }
+    }
+  }
+  .otherCourse {
+    margin-top: 18px;
+    padding: 16px 20px 22px;
+    background-color: #fff;
+    h2 {
+      font-size: 22px;
+      font-family: PingFangSC-Semibold, PingFang SC;
+      font-weight: 600;
+      color: #000000;
+      line-height: 30px;
+      margin-bottom: 11px;
+    }
+  }
+}
+.player {
+  position: absolute;
+  width: 32px;
+  height: 32px;
+  left: 50%;
+  top: 50%;
+  margin-left: -16px;
+  margin-top: -16px;
+}

+ 31 - 0
src/views/videoDetailList/modals/videoCourseItem.module.less

@@ -0,0 +1,31 @@
+.videoWrap {
+  display: flex;
+  flex-direction: row;
+  margin-bottom: 12px;
+  img {
+    width: 240px;
+    margin-right: 10px;
+  }
+  .courseInfo {
+    padding-top: 8px;
+    h4 {
+      font-size: 20px;
+      font-weight: 600;
+      color: #000000;
+      line-height: 28px;
+      margin-bottom: 2px;
+    }
+    .courseDetial {
+      font-size: 18px;
+      font-family: PingFangSC-Regular, PingFang SC;
+      font-weight: 400;
+      color: #666666;
+      line-height: 25px;
+      display: -webkit-box;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      -webkit-line-clamp: 4;
+      -webkit-box-orient: vertical;
+    }
+  }
+}

+ 36 - 0
src/views/videoDetailList/modals/videoCourseItem.tsx

@@ -0,0 +1,36 @@
+
+import { defineComponent , toRefs, reactive, onMounted, ref } from 'vue'
+
+import classes from './videoCourseItem.module.less'
+import detaile from '@/components/videoDetailItem/images/detaile.png'
+export default defineComponent({
+  name: 'videoCourseItem',
+  props: {
+    item: {
+      type: Object,
+      default: {}
+    }
+  },
+  components:{
+
+  },
+  setup(props, conent) {
+    const state = reactive({
+      title:props.item
+    })
+    return () => (
+      <>
+        <div class={classes.videoWrap}>
+            <img src={detaile} alt="" />
+            <div class={classes.courseInfo}>
+              <h4>第1课时</h4>
+              <p class={classes.courseDetial}>
+              小酷老师带您零基础学习竖笛,通过4节课的学习掌握竖笛演奏的基本方式,培养良好的吐息习惯,完整的演奏曲目。
+              </p>
+            </div>
+
+        </div>
+      </>
+    )
+  }
+})

+ 99 - 25
src/views/videoDetailList/videoDetail.tsx

@@ -2,14 +2,20 @@ import { defineComponent, toRefs, reactive, onMounted, ref } from 'vue'
 
 // import classes from './index.module.less'
 import detaile from '@/components/videoDetailItem/images/detaile.png'
+import videoCourseItem from './modals/videoCourseItem'
 import courseIcon from './images/courseIcon.png'
 import peopleIcon from './images/peopleIcon.png'
 import teacherIcon from './images/teacherIcon.png'
+import player from './images/player.png'
+import teacher from './images/teacher.png'
+import teacherHeader from '@/common/images/icon_teacher.png'
 import TimetableIcon from './images/TimetableIcon.png'
 import styles from './index.module.less'
 import videoDetailItem from '@/components/videoDetailItem'
+
 import request from '@/helpers/request'
 import pagination from '@/components/pagination'
+import { useRoute } from 'vue-router'
 export default defineComponent({
   name: 'videoDetailList',
   props: {
@@ -20,12 +26,14 @@ export default defineComponent({
   },
   components: {
     videoDetailItem,
+    videoCourseItem,
     pagination
   },
   setup(props, conent) {
     const state = reactive({
       title: props.title,
       videoList: [],
+      id:'',
       pageInfo: {
         // 分页规则
         limit: 9, // 限制显示条数
@@ -34,55 +42,121 @@ export default defineComponent({
         page_size: [9, 20, 40, 50] // 选择限制显示条数
       }
     })
-
+    const route = useRoute()
     const getVideoList = async () => {
       try {
         const res = await request.post(
-          '/api-website/open/videoLessonGroup/page',
+          '/api-website/open/videoLessonGroup/selectVideoLesson',
           {
             data: {
-              albumStatus: 'PASS',
+              groupId: state.id,
               page: state.pageInfo.page,
               rows: state.pageInfo.limit
             }
           }
         )
         state.videoList = res.data.rows
-        state.pageInfo.total = res.data.total;
+        state.pageInfo.total = res.data.total
       } catch (e) {
         console.log(e)
       }
     }
     onMounted(() => {
+      if(route.query.id){
+        state.id = route.query.id as string
+      }
       getVideoList()
     })
     return () => (
       <>
         <div>
           <div class="wall" style={{ height: '70px' }}></div>
-          <div class={[styles.w1200,styles.detailWrap]}>
-          <div class={styles.detailLeft}>
-            <img src={detaile} class={styles.detailTopImg} alt="" />
-            <div class={styles.courseWrap}>
-            <div class={styles.courseTitle}>
-              <img src={courseIcon} alt="" />
-              <span>课程介绍</span>
-            </div>
-            <div  class={styles.courseInfo} >
-              <p>小酷老师带您零基础学习竖笛,通过8节课的学习掌握竖笛演奏的基本方式,培养良好的吐息习惯。</p>
+          <div class={[styles.w1200, styles.detailWrap]}>
+            <div class={styles.detailLeft}>
+              <img src={detaile} class={styles.detailTopImg} alt="" />
+              <div class={styles.courseWrap}>
+                <div class={styles.courseTitle}>
+                  <img src={courseIcon} alt="" />
+                  <span>课程介绍</span>
+                </div>
+                <div class={styles.courseInfo}>
+                  <p>
+                    小酷老师带您零基础学习竖笛,通过8节课的学习掌握竖笛演奏的基本方式,培养良好的吐息习惯。
+                  </p>
+                </div>
+                {/* courseList */}
+                <div class={styles.courseListWrap}>
+                  <div class={styles.courseTitle}>
+                    <div class={styles.courseTitleLeft}>
+                      <img src={TimetableIcon} alt="" />
+                      <span>课程介绍</span>
+                    </div>
+                    <span class={styles.courseTitlTimer}>共8课时</span>
+                  </div>
+                  <videoCourseItem></videoCourseItem>
+                </div>
+              </div>
+              <pagination
+                total={state.pageInfo.total}
+                v-model:page={state.pageInfo.page}
+                limit={state.pageInfo.limit}
+                pageSizes={state.pageInfo.page_size}
+                pagination={getVideoList}
+              />
             </div>
+            <div class={styles.detailRight}>
+              <div class={styles.teacherInfo}>
+                <div class={styles.teacherHeadWrap}>
+                  <div class={styles.teacherHeadLeft}>
+                    <img
+                      src={teacherHeader}
+                      alt=""
+                      class={styles.teacherHeader}
+                    />
+                    <div class={styles.teacherHeadInfo}>
+                      <div class={styles.teacherHeadName}>
+                        <span>李老师</span>
+                        <img src={teacher} class={styles.teacherIcon} alt="" />
+                      </div>
+                      <p class={styles.fens}>
+                        粉丝 <span>126</span>
+                      </p>
+                    </div>
+                  </div>
+                  <div class={styles.teacherHeadRight}>关注</div>
+                </div>
+                <div class={styles.titleWrap}>
+                  <img src={peopleIcon} alt="" />
+                  <span>个人介绍</span>
+                </div>
+                <p class={styles.teacherDetail}>
+                  毕业与中央音乐学员长笛专业,师从央音长笛系不得了大师,曾获2016年不得了长笛大赛冠军,自2018年起研究长笛启蒙、考级到专业考试教育,总结出一套适合各个阶段需要的教学方式,所教学员考级通过率100%,专业院校复试率92%
+                </p>
+                <div class={styles.titleWrap}>
+                  <img src={teacherIcon} alt="" />
+                  <span>老师风采</span>
+                </div>
+                <div class={styles.teacherVideoList}>
+                  <div class={styles.videoItem}>
+                    <img src={detaile} alt="" class={styles.Styles} />
+                    <img src={player} alt="" class={styles.player} />
+                  </div>
+                  <div class={styles.videoItem}>
+                    <img src={detaile} alt="" class={styles.Styles} />
+                    <img src={player} alt="" class={styles.player} />
+                  </div>
+                </div>
+              </div>
+              <div  class={styles.otherCourse}>
+                <h2>
+                  其他课程
+                </h2>
+                <div>
+                  <videoDetailItem></videoDetailItem>
+                {/* videoDetailItem */}
+                </div>
+              </div>
             </div>
-          <pagination
-              total={state.pageInfo.total}
-              v-model:page={state.pageInfo.page}
-              limit={state.pageInfo.limit}
-              pageSizes={state.pageInfo.page_size}
-              pagination={getVideoList}
-            />
-          </div>
-          <div class={styles.detailRight}></div>
-
-
           </div>
         </div>
       </>