Forráskód Böngészése

首页基本完成

1
mo 3 éve
szülő
commit
bba28fa439

BIN
src/components/albumItem/images/lineStart.png


BIN
src/components/albumItem/images/player.png


BIN
src/components/albumItem/images/start.png


+ 83 - 25
src/components/albumItem/index.module.less

@@ -1,42 +1,99 @@
 .itemWrap {
+  margin-bottom: 25px;
+  margin-right: 14px;
+  position: relative;
+
   &:hover {
+
     .hold {
+      transform: translateY(-10px);
+      transition: linear 0.1s;
+      .masker {
+        // transition: all linear 0.2s;
+        visibility: visible;
+        img {
+          width: 48px;
+          height: 48px;
+          animation-name: showPaly;
+          animation-duration: .6s;
+          animation-timing-function: linear;
+          animation-fill-mode: forwards;
+          // animation-delay: 1s;
+        }
+      }
+      @keyframes showPaly {
+        0% {
+         transform: scale(.5);
+
+        }
+        50% {
+          transform: scale(1.2);
+
+        }
+        100% {
+          transform: scale(1);
+        }
+      }
+      // img {
+      //   transform: scale(1.1);
+      //   transition: all 0.3s ease-in-out;
+      // }
+    }
+  }
+  .hold {
+    .masker {
+      visibility: hidden;
+      width: 160px;
+      height: 160px;
+      background-color: rgba(0, 0, 0, 0.4);
+      position: absolute;
+      top: 0;
+      left: 0;
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      justify-content: center;
+      position: absolute;
       img {
-        transform: scale(1.1);
-        transition: all 0.3s ease-in-out;
+        width: 48px;
+        height: 48px;
       }
     }
+    position: relative;
+    width: 160px;
+    height: 160px;
+    border-radius: 10px;
+    overflow: hidden;
+    img {
+      width: 100%;
+      transition: all 0.3s ease-in-out;
+    }
   }
   cursor: pointer;
-  &:nth-child(5n) {
+  &:nth-child(4n) {
     margin-right: 0;
   }
-  margin-bottom: 28px;
-  margin-right: 26px;
-
+  .startImage {
+    width: 24px;
+    height: 24px;
+    z-index: 1000;
+    position: absolute;
+    top: 8px;
+    right: 8px;
+  }
   h2 {
     line-height: 30px;
     font-size: 18px;
-    font-weight: 600;
-    color: #333;
-    line-height: 30px;
-    margin: 6px 0;
+    font-weight: 400;
+    color: #000;
+    line-height: 25px;
+    margin: 18px 0 3px;
     overflow: hidden;
     text-overflow: ellipsis;
     white-space: nowrap;
-    width: 219px;
-  }
-  .hold {
-    width: 219px;
-    height: 219px;
-    border-radius: 4px;
-    overflow: hidden;
-    transition: 2s;
-    img {
-      width: 100%;
-      transition: all 0.3s ease-in-out;
-    }
+    width: 160px;
   }
+
   span {
     color: #999;
     font-size: 14px;
@@ -44,14 +101,14 @@
   .itemBottom {
     display: flex;
     flex-direction: row;
-    justify-content: flex-start;
+    justify-content: space-between;
     img {
       width: 18px;
       margin-right: 4px;
       // height: 18px;
     }
-    .itemBottomL {
-      margin-right: 21px;
+    .itemBottomR {
+      margin-right: 1px;
     }
     .itemBottomL,
     .itemBottomR {
@@ -60,6 +117,7 @@
       justify-content: flex-start;
       align-items: center;
       font-size: 14px;
+      line-height: 20px;
     }
   }
 }

+ 12 - 5
src/components/albumItem/index.tsx

@@ -3,7 +3,9 @@ import { defineComponent, toRefs, reactive, onMounted, ref, watch } from 'vue'
 import classes from './index.module.less'
 import hold from './images/hold.png'
 import start from './images/start.png'
+import lineStart from './images/lineStart.png'
 import pan from './images/pan.png'
+import player from './images/player.png'
 import { useRouter } from 'vue-router'
 export default defineComponent({
   name: 'albumItem',
@@ -28,8 +30,9 @@ export default defineComponent({
         sortNumber: 0,
         topFlag: null,
         updateBy: 34,
-        updateTime: ''
-      }
+        updateTime: '',
+        favorite:0
+      } as any
     }
   },
   setup(props) {
@@ -54,7 +57,11 @@ export default defineComponent({
             gotoAlbum()
           }}
         >
+          <img class={classes.startImage} src={state.detail.favorite?lineStart:start} alt="" />
           <div class={classes.hold}>
+            <div class={classes.masker}>
+              <img src={player} alt="" />
+            </div>
             <img
               src={
                 state.detail.albumCoverUrl ? state.detail.albumCoverUrl : hold
@@ -66,11 +73,11 @@ export default defineComponent({
           <h2>{state.detail.albumName}</h2>
           <div class={classes.itemBottom}>
             <div class={classes.itemBottomL}>
-              <img src={pan} alt="" />
-              <span>{state.detail.musicSheetCount}</span>
+              {/* <img src={pan} alt="" /> */}
+              <span>{state.detail.musicSheetCount}曲目</span>
             </div>
             <div class={classes.itemBottomR}>
-              <img src={start} alt="" />
+              {/* <img src={start} alt="" /> */}
               <span>{state.detail.albumFavoriteCount}收藏</span>
             </div>
           </div>

BIN
src/components/banner/images/bannerArrow.png


BIN
src/components/banner/images/bannerArrowAcitive.png


+ 57 - 40
src/components/banner/index.module.less

@@ -1,52 +1,69 @@
 .mySwiper {
-  min-height: 300px;
+  min-height: 400px;
   /deep/.swiper-slide {
-    min-height: 300px;
+    min-height: 400px;
   }
   cursor: pointer;
 }
 :global {
-  .mySwiper {
-    &:hover {
-      .myprev,
-      .mynext {
-        visibility: visible!important;
+  .bannerSwiper {
+    .mySwiper {
+      &:hover {
+        .myprev,
+        .mynext {
+          visibility: visible !important;
+          &:active {
+            opacity: 0.9;
+           }
+        }
       }
+
     }
-  }
-  .myprev,
-  .mynext {
-    width: 40px;
-    height: 72px;
-    background: rgba(0, 0, 0, 0.26);
-    border-radius: 8px;
-    position: absolute;
-    z-index: 100;
-    position: absolute;
-    top: 50%;
-    margin-top: calc(0px - (var(--swiper-navigation-size) / 2));
-    z-index: 10;
-    cursor: pointer;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    color: var(--swiper-navigation-color, var(--swiper-theme-color));
-    img {
-      width: 20px;
-      height: 20px;
+    .myprev,
+    .mynext {
+      // width: 40px;
+      // height: 72px;
+      // background: rgba(0, 0, 0, 0.26);
+      // border-radius: 8px;
+      z-index: 100;
+      position: absolute;
+      top: 50%;
+      margin-top: calc(0px - (var(--swiper-navigation-size) / 2));
+      z-index: 10;
+      cursor: pointer;
+      // display: flex;
+      // align-items: center;
+      // justify-content: center;
+      // color: var(--swiper-navigation-color, var(--swiper-theme-color));
+      img {
+        width: 44px;
+        height: 44px;
+      }
+      visibility: hidden;
     }
-    visibility: hidden;
-  }
-  .myprev {
-    left: 130px;
-  }
-  .mynext {
-    right: 130px;
-    img {
-      transform: rotate(180deg);
+    .myprev {
+      left: 130px;
+    }
+    .mynext {
+      right: 130px;
+      img {
+        transform: rotate(180deg);
+      }
+    }
+    .swiper-pagination {
+      bottom: 31px !important;
+    }
+    .swiper-pagination-bullet-active {
+      width: 50px;
+      height: 6px;
+      background: #2dc7aa!important;
+      border-radius: 3px;
+    }
+    .swiper-pagination-bullet {
+      width: 50px;
+      height: 6px;
+      background: #999999;
+      border-radius: 3px;
     }
-  }
-  .swiper-pagination-bullet-active {
-    background-color: #fff!important;
   }
 }

+ 82 - 39
src/components/banner/index.tsx

@@ -1,9 +1,10 @@
 import { defineComponent, toRefs, reactive, onMounted, ref } from 'vue'
 import classes from './index.module.less'
 import { Swiper, SwiperSlide } from 'swiper/vue'
-import { Navigation, Pagination, Scrollbar, A11y } from 'swiper'
+import { Navigation, Pagination, Scrollbar, A11y, Autoplay } from 'swiper'
 import request from '@/helpers/request'
-import bannerArray from './images/bannerArray.png'
+import bannerArrow from './images/bannerArrow.png'
+import bannerArrowAcitive from './images/bannerArrowAcitive.png'
 import { useRouter } from 'vue-router'
 export default defineComponent({
   name: 'banner',
@@ -20,8 +21,10 @@ export default defineComponent({
   setup(props, conent) {
     const state = reactive({
       title: props.title,
-      modules: [Navigation, Pagination, Scrollbar, A11y],
-      bannerList:[]
+      modules: [Navigation, Pagination, Scrollbar, Autoplay,A11y ],
+      bannerList: [],
+      leftHover: false,
+      rightHover: false
     })
     const router = useRouter()
     const onSwiper = swiper => {
@@ -33,9 +36,7 @@ export default defineComponent({
     const getBannerList = async () => {
       try {
         const res = await request.get('/api-website/open/banner/list', {
-          data: {
-
-          }
+          data: {}
         })
 
         state.bannerList = res.data
@@ -43,44 +44,86 @@ export default defineComponent({
         console.log(e)
       }
     }
-    const gotoBannerInfo = (item:any)=>{
-      if(item.linkUrl.indexOf('http')!= -1){
+    const gotoBannerInfo = (item: any) => {
+      if (item.linkUrl.indexOf('http') != -1) {
         window.open(item.linkUrl)
-      }else{
-        router.push({path:item.linkUrl})
+      } else {
+        router.push({ path: item.linkUrl })
       }
-
     }
-      onMounted(()=>{
-        getBannerList()
-      })
+    onMounted(() => {
+      getBannerList()
+    })
     return () => (
       <>
-        <swiper
-          modules={state.modules}
-          class={[classes.mySwiper,'mySwiper']}
-          slides-per-view={1}
-          space-between={50}
-          pagination={{ clickable: true }}
-          navigation={{
-            nextEl: '.myprev',
-            prevEl: '.mynext'
-          }}
-          loop={true}
-          onSwiper={onSwiper}
-          onSlideChange={onSlideChange}
-        >
-          {
-          state.bannerList.map((item:any)=>{
-            return < ><swiper-slide><img src={item.coverImage} alt=""  onClick={()=>{gotoBannerInfo(item)}} /></swiper-slide></>
-          })
-        }
-
-
+        <div class="bannerSwiper">
+          <swiper
+            modules={state.modules}
+            class={[classes.mySwiper, 'mySwiper']}
+            slides-per-view={1}
+            space-between={0}
+            autoplay={{
+              delay: 3000,
+              disableOnInteraction: false,
+              loop: true,
+              pauseOnMouseEnter: true,
+              reverseDirection: true
+            }}
+            pagination={{ clickable: true }}
+            navigation={{
+              nextEl: '.myprev',
+              prevEl: '.mynext'
+            }}
+            loop={true}
+            onSwiper={onSwiper}
+            onSlideChange={onSlideChange}
+          >
+            {state.bannerList.map((item: any) => {
+              return (
+                <>
+                  <swiper-slide>
+                    <img
+                      src={item.coverImage}
+                      alt=""
+                      onClick={() => {
+                        gotoBannerInfo(item)
+                      }}
+                    />
+                  </swiper-slide>
+                </>
+              )
+            })}
 
-          <div class="myprev"><img src={bannerArray} alt="" /></div>
-          <div class="mynext"><img src={bannerArray} alt="" /></div>
-        </swiper>
+            <div
+              class="myprev"
+              onMouseover={() => {
+                state.leftHover = true
+              }}
+              onMouseout={() => {
+                state.leftHover = false
+              }}
+            >
+              <img
+                src={state.leftHover ? bannerArrowAcitive : bannerArrow}
+                alt=""
+              />
+            </div>
+            <div
+              class="mynext"
+              onMouseover={() => {
+                state.rightHover = true
+              }}
+              onMouseout={() => {
+                state.rightHover = false
+              }}
+            >
+              <img
+                src={state.rightHover ? bannerArrowAcitive : bannerArrow}
+                alt=""
+              />
+            </div>
+          </swiper>
+        </div>
       </>
     )
   }

+ 1 - 1
src/components/col-header/index.css

@@ -43,7 +43,7 @@
   border-radius: 2px;
 }
 
-.activeItem:hover::after {
+.activeItem:active::after {
   transform: scaleX(0);
 }
 

+ 26 - 9
src/components/tagItem/index.module.less

@@ -1,15 +1,32 @@
 .tag {
   cursor: pointer;
-  // color: #2dc7aa;
-  line-height: 24px;
-  // background: #e9f6f4;
-  border-radius: 4px;
-  border: 1px solid #2dc7aa;
-  padding: 0 12px;
-  font-size: 13px;
+  min-width: 80px;
+  text-align: center;
+  padding: 0 22px;
+  border-radius: 10px;
+  line-height: 40px;
+  font-size: 16px;
   margin-right: 10px;
-  &:last-child{
-    margin-right: 0!important;
+  display: inline-block;
+  margin-bottom: 14px;
+  border: 1px solid #dcdcdc;
+  color: #666;
+  &:hover {
+    border: 1px solid #4bb39e;
+    color: #07b491;
+  }
+  &:last-child {
+    margin-right: 0 !important;
+  }
+  &:active {
+    border: 1px solid #4bb39e;
+    color: #ffffff;
+    background: #2dc7aa;
   }
 }
 
+.active.tag {
+  border: 1px solid #4bb39e;
+  color: #ffffff;
+  background: #2dc7aa;
+}

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

@@ -46,7 +46,8 @@ export default defineComponent({
     }
     return () => (
       <>
-        <ElTag  effect={state.isCheck ? 'dark' : 'light'} onClick={()=>shioseTag(state.title)} class={classes.tag}>{state.title}</ElTag>
+      {/* effect={state.isCheck ? 'dark' : 'light'} */}
+        <div  onClick={()=>shioseTag(state.title)} class={classes.tag}>{state.title}</div>
       </>
     )
   }

+ 143 - 13
src/components/videoDetailItem/index.module.less

@@ -10,7 +10,7 @@
       height: 187px !important;
     }
   }
-  &:nth-last-child(1){
+  &:nth-last-child(1) {
     border-bottom: none;
   }
   border-bottom: 1px solid #f0f0f0;
@@ -20,26 +20,138 @@
   }
 }
 .itemWrap {
-  width: 386px;
+  border: 1px solid #E0E0E0;
+  width: 312px;
   margin-bottom: 20px;
-  margin-right: 20px;
-  border-radius: 4px;
+  margin-right: 33px;
+  border-radius: 10px;
+  overflow: hidden;
   background-color: #fff;
   cursor: pointer;
   &:nth-child(3n) {
     margin-right: 0;
   }
-  .detaile {
-    border-radius: 4px;
-    width: 387px;
-    height: 216px;
+  &:hover {
+    transform: translateY(-10px);
+    transition: all linear 0.1s;
+    .detaileWrap {
+      .masker {
+        // transition: all linear 0.2s;
+        visibility: visible;
+        img {
+          width: 48px;
+          height: 48px;
+          animation-name: showPaly;
+          animation-duration: 0.5s;
+          animation-timing-function: linear;
+          animation-fill-mode: forwards;
+          // animation-delay: 1s;
+        }
+      }
+      @keyframes showPaly {
+        0% {
+          transform: scale(0.5);
+        }
+        50% {
+          transform: scale(1.2);
+        }
+        100% {
+          transform: scale(1);
+        }
+      }
+    }
   }
-  .itemBottom {
+  .detaileWrap {
+    position: relative;
+
+    .detaileStudy {
+      position: absolute;
+      left: 0;
+      bottom: 0;
+      padding: 0 12px;
+      line-height: 38px;
+      width: 100%;
+      background-color: rgba(0, 0, 0, 0.6);
+      // opacity: .6;
+      color: #52ffdc;
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-end;
+      align-items: center;
+      .detaileDot {
+        display: inline-block;
+        width: 6px;
+        height: 6px;
+        background: #6fffe2;
+        border-radius: 50%;
+        margin-right: 7px;
+      }
+    }
+
+    .detaile {
+      border-radius: 4px;
+      width: 312px;
+      height: 174px;
+    }
+    .masker {
+      visibility: hidden;
+      width: 312px;
+      height: 174px;
+      background-color: rgba(0, 0, 0, 0.4);
+      position: absolute;
+      top: 0;
+      left: 0;
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      justify-content: center;
+      position: absolute;
+      z-index: 900;
+      img {
+        width: 48px;
+        height: 48px;
+      }
+    }
+    // &:hover {
+
+    // }
+  }
+  .infoBottom {
     display: flex;
     flex-direction: row;
     align-items: center;
     padding: 12px;
     justify-content: space-between;
+    .infoBottomL {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      .itemHead {
+        width: 28px;
+        height: 28px;
+        border-radius: 50%;
+        border: 2px solid #4bb39e;
+        margin-right: 12px;
+      }
+      .itemTitle {
+        font-size: 20px;
+        font-weight: 500;
+        color: #333333;
+        line-height: 28px;
+      }
+      .course {
+        color: #666;
+        font-size: 18px;
+        line-height: 25px;
+      }
+    }
+  }
+  .itemBottom {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    padding: 0 12px 12px;
+    justify-content: space-between;
     .itemBottomL {
       display: flex;
       flex-direction: row;
@@ -68,10 +180,28 @@
         line-height: 22px;
       }
     }
-    .buy {
-      color: #ff802c;
-      font-size: 16px;
-      line-height: 22px;
+    // .buy {
+    //   color: #ff802c;
+    //   font-size: 16px;
+    //   line-height: 22px;
+    // }
+    .itemBottomR {
+      width: 95px;
+      height: 35px;
+      background: #2dc7aa;
+      border-radius: 10px;
+      border: 1px solid #4bb39e;
+      line-height: 33px;
+      cursor: pointer;
+      text-align: center;
+      color: #ffffff;
+      font-size: 18px;
+      &:hover {
+        opacity: 0.9;
+      }
+      &:active {
+        opacity: 0.8;
+      }
     }
   }
 }

+ 57 - 33
src/components/videoDetailItem/index.tsx

@@ -1,39 +1,40 @@
-import { defineComponent, toRefs, reactive, onMounted, ref,watch} from 'vue'
+import { defineComponent, toRefs, reactive, onMounted, ref, watch } from 'vue'
 
 import classes from './index.module.less'
 import detaile from './images/detaile.png'
+import player from '@/components/albumItem/images/player.png'
 import icon from './images/icon.png'
 import { useRouter } from 'vue-router'
 export default defineComponent({
   name: 'albumItem',
-  emits:['getDetail'],
+  emits: ['getDetail'],
   props: {
     detail: {
       type: Object,
       default: {
-        "auditStatus": "",
-        "endTime": "",
-        "lessonSubject": "",
-        "order": "",
-        "orderNo": "",
-        "page": 0,
-        "rows": 0,
-        "search": "",
-        "sort": "",
-        "startTime": "",
-        "userId": 0,
-        "videoLessonGroupId": 0
+        auditStatus: '',
+        endTime: '',
+        lessonSubject: '',
+        order: '',
+        orderNo: '',
+        page: 0,
+        rows: 0,
+        search: '',
+        sort: '',
+        startTime: '',
+        userId: 0,
+        videoLessonGroupId: 0
       }
     },
-    isFull:{
-      type:Boolean,
-      default:false
+    isFull: {
+      type: Boolean,
+      default: false
     }
   },
-  setup(props,conent) {
+  setup(props, conent) {
     const state = reactive({
-      detail:props.detail,
-      isFull:props.isFull
+      detail: props.detail,
+      isFull: props.isFull
     })
     watch(
       () => props.detail,
@@ -42,27 +43,50 @@ export default defineComponent({
       }
     )
     const router = useRouter()
-    const gotoVideoDetail = ()=>{
-      if(state.isFull){
-        conent.emit('getDetail',state.detail.id)
+    const gotoVideoDetail = () => {
+      if (state.isFull) {
+        conent.emit('getDetail', state.detail.id)
       }
-        router.push({path:'/videoDetail',query:{id:state.detail.id}})
-
-
+      router.push({ path: '/videoDetail', query: { id: state.detail.id } })
     }
     return () => (
       <>
-        <div class={[classes.itemWrap,state.isFull?classes.isFull:'']} onClick={gotoVideoDetail}>
-          <img src={state.detail.lessonCoverUrl?state.detail.lessonCoverUrl:detaile} alt="" class={classes.detaile} />
-          <div class={classes.itemBottom}>
-            <div class={classes.itemBottomL}>
+        <div
+          class={[classes.itemWrap, state.isFull ? classes.isFull : '']}
+          onClick={gotoVideoDetail}
+        >
+          <div class={classes.detaileWrap}>
+          <div class={classes.masker}>
+              <img src={player} alt="" />
+            </div>
+            <p class={classes.detaileStudy}>
+              <span class={classes.detaileDot}></span>
+              {state.detail.countStudent}人在学
+            </p>
+            <img
+              src={
+                state.detail.lessonCoverUrl
+                  ? state.detail.lessonCoverUrl
+                  : detaile
+              }
+              alt=""
+              class={classes.detaile}
+            />
+          </div>
+          <div class={classes.infoBottom}>
+            <div class={classes.infoBottomL}>
               <img src={icon} class={classes.itemHead} alt="" />
               <span class={classes.itemTitle}>{state.detail.username}</span>
-              <div class={classes.line}></div>
-              <span class={classes.course}>共{state.detail.lessonCount}课时</span>
+            </div>
+            <span class={classes.course}>{state.detail.lessonCount}课时</span>
+          </div>
+          <div class={classes.itemBottom}>
+            <div class={classes.itemBottomL}>
+              <span class={classes.itemTitle}>{state.detail.lessonSubjectName}</span>
+              {/* <div class={classes.line}></div> */}
             </div>
             <div class={classes.itemBottomR}>
-              <span class={classes.buy}>{state.detail.countStudent}人购买</span>
+              了解更多
             </div>
           </div>
         </div>

BIN
src/views/home/images/moreArrow.png


BIN
src/views/home/images/search.png


BIN
src/views/home/images/titleDot.png


+ 135 - 23
src/views/home/index.module.less

@@ -1,41 +1,151 @@
-
 .title {
   font-size: 20px;
   color: red;
 }
 .w1200 {
-  width: 1200px !important;
+  width: 1002px !important;
   margin: 0 auto;
 }
 .section {
-  padding: 44px 0 16px;
+  padding: 62px 0 16px;
   .titleWrap {
-    text-align: center;
-    margin: 0 auto;
+    text-align: left;
+    margin-bottom: 11px;
     display: flex;
     flex-direction: row;
     align-items: center;
-    justify-content: center;
-    .dotImg {
-      width: 44px;
-      height: 44px;
+    justify-content: space-between;
+    .titleWrapLeft {
+      text-align: left;
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+
+      .dotImg {
+        width: 30px;
+        height: 20px;
+      }
+      h4 {
+        margin-right: 10px;
+        font-size: 24px;
+        font-weight: 500;
+        color: #1d1f26;
+        line-height: 33px;
+      }
     }
-    h4 {
-      margin: 0 10px;
-      font-size: 28px;
-      font-weight: 600;
-      color: #333333;
-      line-height: 45px;
+    .titleWrapMore {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      cursor: pointer;
+      margin-right: 24px;
+      img {
+        width: 20px;
+        height: 20px;
+        margin-left: 8px;
+      }
+      span {
+        height: 28px;
+        font-size: 20px;
+        font-weight: 400;
+        color: #1d1f26;
+        line-height: 28px;
+      }
+      &:active {
+        opacity: 0.9;
+      }
     }
+    // justify-content: center;
   }
-  .albumList {
+  .hotAlbum {
+    width: 707px;
+  }
+  .albumMoudel {
     display: flex;
     flex-direction: row;
-    align-items: center;
-    flex-wrap: wrap;
-    // margin-bottom: 25px;
-    margin-top: 25px;
+    // align-items: center;
+    .albumWrap {
+      // border-right:2px solid #979797;
+      // display: flex;
+      // flex-direction: row;
+      // align-items: center;
+      position: relative;
+      .line {
+        opacity: 0.2;
+        border: 1px solid #979797;
+        width: 1px;
+        height: calc(100% - 30px);
+        position: absolute;
+        right: 0;
+        top: 5px;
+      }
+      width: 707px;
+      .albumList {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        flex-wrap: wrap;
+        // margin-bottom: 25px;
+        // margin-top: 25px;
+      }
+    }
+    .albumSearch {
+      padding-left: 24px;
+      padding-top: 5px;
+      width: 100%;
+      .inputWrap {
+        position: relative;
+        .searchIcon {
+          width: 24px;
+          height: 25px;
+          position: absolute;
+          z-index: 1000;
+          top: 12px;
+          right: 27px;
+          cursor: pointer;
+          &:active {
+            opacity: 0.8;
+          }
+        }
+        :global {
+          input::placeholder {
+            height: 25px;
+            font-size: 16px;
+            font-family: PingFangSC-Regular, PingFang SC;
+            font-weight: 400;
+            color: #7c7c7c;
+            line-height: 25px;
+          }
+
+          .el-input {
+            .el-input__wrapper {
+              box-shadow: none;
+              padding: 0;
+              .el-input__inner {
+                padding: 0 52px 0 24px;
+                height: 50px;
+                line-height: 50px;
+                background: #ffffff;
+                border-radius: 25px;
+                border: 1px solid #2dc7aa;
+              }
+            }
+          }
+        }
+      }
+      .chioseRow {
+        margin-top: 38px;
+        p {
+          font-size: 20px;
+          font-weight: 600;
+          color: #000000;
+          line-height: 28px;
+          margin-bottom: 22px;
+        }
+      }
+    }
   }
+
   .videoList {
     display: flex;
     flex-direction: row;
@@ -72,9 +182,11 @@
   }
 }
 .mb48 {
-  margin-bottom: 44px!important;
+  margin-bottom: 44px !important;
 }
 .mb32 {
-  margin-bottom: 32px!important;
+  margin-bottom: 32px !important;
+}
+.pt41 {
+  padding-top: 41px !important;
 }
-

+ 96 - 38
src/views/home/index.tsx

@@ -8,13 +8,16 @@ import musicLIstItem from '@/components/musicLIstItem'
 import titleDot from './images/titleDot.png'
 import hotSearch from '@/components/hotSearch'
 import banner from '@/components/banner'
-
+import moreArrow from './images/moreArrow.png'
+import searchIcon from './images/search.png'
 import request from '@/helpers/request'
+import tagItem from '@/components/tagItem'
 import 'swiper/css'
 import 'swiper/css/navigation'
 import 'swiper/css/pagination'
 import 'swiper/css/scrollbar'
 import { useRouter } from 'vue-router'
+import { ElInput } from 'element-plus'
 export default defineComponent({
   name: 'home',
   components: {
@@ -22,12 +25,15 @@ export default defineComponent({
     videoDetailItem,
     musicLIstItem,
     hotSearch,
-    banner
+    banner,
+    tagItem
   },
   setup() {
     const state = reactive({
       albumList: [],
-      videoList: []
+      videoList: [],
+      search: '',
+      tagTree: []
     })
     const router = useRouter()
     const getAlbumList = async () => {
@@ -36,7 +42,7 @@ export default defineComponent({
           data: {
             albumStatus: 1,
             page: 1,
-            rows: 10
+            rows: 8
           }
         })
 
@@ -63,17 +69,27 @@ export default defineComponent({
         console.log(e)
       }
     }
-    const gotoSearch = (val: string) => {
-      router.push({ path: '/searchdetail', query: { search: val } })
+    const gotoSearch = (val: string,type) => {
+      router.push({ name: 'searchdetail', params: { search: val,type } })
     }
+    const getTagTree = async () => {
+      try {
+        const res = await request.get('/api-website/open/MusicTag/tree', {})
+        state.tagTree = res.data
 
-    const gotoVideoList = (val: string) => {
-      router.push({ path: '/videoDetailList', query: { search: val } })
+        // state.hotList = res.data
+      } catch (e) {
+        console.log(e)
+      }
+    }
+    const gotoVideoList = () => {
+      router.push({ path: '/videoDetailList',  })
     }
     //
     onMounted(() => {
       getAlbumList()
       getVideoList()
+      getTagTree()
     })
     return () => (
       <div>
@@ -81,47 +97,89 @@ export default defineComponent({
         <div class="bg-white">
           <div class={styles.w1200}>
             <div class={styles.section}>
-              <div class={[styles.titleWrap, styles.mb48]}>
-                <img src={titleDot} class={styles.dotImg} alt="" />
-                <h4>热门专辑</h4>
-                <img src={titleDot} class={styles.dotImg} alt="" />
-              </div>
-              <hotSearch
+              {/* <hotSearch
                 searchType="MUSIC"
                 onHotTag={(val: string) => {
                   gotoSearch(val)
                 }}
-              ></hotSearch>
-              <div class={styles.albumList}>
-                {state.albumList.map(item => {
-                  return <albumItem detail={item}></albumItem>
-                })}
+              ></hotSearch> */}
+              <div class={styles.albumMoudel}>
+                <div class={styles.albumWrap}>
+                  <div class={[styles.titleWrap, styles.hotAlbum]}>
+                    <div class={[styles.titleWrapLeft]}>
+                      <h4>热门专辑</h4>
+                      <img src={titleDot} class={styles.dotImg} alt="" />
+                    </div>
+                    <div class={[styles.titleWrapMore]}    onClick={() => gotoSearch('','album')}>
+                      <span>更多</span>
+                      <img src={moreArrow} alt="" />
+                    </div>
+                  </div>
+                  <div class={styles.albumList}>
+                    {state.albumList.map(item => {
+                      return <albumItem detail={item}></albumItem>
+                    })}
+                  </div>
+                  <div class={styles.line}></div>
+                </div>
+                <div class={styles.albumSearch}>
+                  <div class={styles.inputWrap}>
+                    <img
+                      src={searchIcon}
+                      class={styles.searchIcon}
+                      onClick={() => gotoSearch(state.search,'music')}
+                      alt=""
+                    />
+                    <ElInput
+                      placeholder="搜索你想要的曲目"
+                      v-model={state.search}
+                    ></ElInput>
+                  </div>
+                  <div class={styles.chioseLineWrap}>
+                    {state.tagTree.map((tree: any) => {
+                      return (
+                        <div class={styles.chioseRow}>
+                          <p>{tree.name}:</p>
+                          <div class={[styles.chioseTagWrap, 'chioseTagWrap']}>
+                            {tree.children.map((tag: any) => {
+                              return (
+                                //  effect={isChiose(tag)}
+
+                                <tagItem
+                                  class={styles.tags}
+                                  title={tag.name}
+                                  onSearchTag={() => {
+                                    gotoSearch(tag.name)
+                                  }}
+                                >
+                                  {/* {} */}
+                                </tagItem>
+                              )
+                            })}
+                          </div>
+                        </div>
+                      )
+                    })}
+                  </div>
+                </div>
               </div>
             </div>
           </div>
         </div>
-        <div>
+        <div class="bg-white">
           <div class={styles.w1200}>
-            <div class={styles.section}>
-              <div class={[styles.titleWrap, styles.mb32]}>
-                <img src={titleDot} class={styles.dotImg} alt="" />
-                <h4>精品视频课</h4>
-                <img src={titleDot} class={styles.dotImg} alt="" />
-              </div>
-              {/* <div class={styles.videoNav}>
-                <h5>精品视频课</h5>
-                <div class={styles.wrapRight} onClick={()=>gotoVideoList()}>
+            <div class={[styles.section,styles.pt41]}>
+              <div class={[styles.titleWrap]}>
+                {/* <img src={titleDot} class={styles.dotImg} alt="" /> */}
+                <div class={[styles.titleWrapLeft]}>
+                  <h4>热门专辑</h4>
+                  <img src={titleDot} class={styles.dotImg} alt="" />
+                </div>
+                <div class={[styles.titleWrapMore]} onClick={()=>gotoVideoList()}>
                   <span>更多</span>
-                  <img class={styles.arrow} src={arrow} alt="" />
+                  <img src={moreArrow} alt="" />
                 </div>
-              </div> */}
-              <hotSearch
-                searchType="COURSE"
-                onHotTag={(val: string) => {
-                  gotoVideoList(val)
-                }}
-                gotoPath='/videoDetailList'
-              ></hotSearch>
+              </div>
               <div class={styles.videoList}>
                 {state.videoList.map(item => {
                   return <videoDetailItem detail={item}></videoDetailItem>

+ 7 - 6
src/views/musicLibrary/searchdetail.tsx

@@ -104,14 +104,15 @@ export default defineComponent({
       }
     )
     onMounted(() => {
-      if (route.query.search) {
-        state.searchs.search = route.query.search as string
+      console.log(route.name)
+      if (route.params.search) {
+        state.searchs.search = route.params.search as string
       }
-      if (route.query.subject) {
-        state.searchs.subject = route.query.subject as string
+      if (route.params.subject) {
+        state.searchs.subject = route.params.subject as string
       }
-      if (route.query.type) {
-        state.chiose = route.query.type as string
+      if (route.params.type) {
+        state.chiose = route.params.type as string
       }
       nextTick(() => {
         search()