Browse Source

添加搜索操作和搜索结果返回页

reghao 4 years ago
parent
commit
e84acf830f

+ 13 - 1
src/api/media/video.js

@@ -6,7 +6,9 @@ const videoApi = {
   videoInfoApi: '/api/media/video/post/detail',
   videoUrlApi: '/api/media/video/url',
   videoCategoryApi: '/api/media/video/category',
-  videoPostSubmitApi: '/api/media/video/submit'
+  videoPostSubmitApi: '/api/media/video/submit',
+  keywordSuggestApi: '/api/media/video/search/suggest',
+  videoSearchApi: '/api/media/video/search/query'
 }
 
 // 视频推荐接口
@@ -37,3 +39,13 @@ export function videoCategory() {
 export function submitVideoPost(videoPost) {
   return $axios.post(videoApi.videoPostSubmitApi, videoPost)
 }
+
+// 关键词建议
+export function keywordSuggest(keyword) {
+  return $axios.get(videoApi.keywordSuggestApi + '?k=' + keyword)
+}
+
+// 视频搜索
+export function videoQuery(keyword) {
+  return $axios.get(videoApi.videoSearchApi + '?keyword=' + keyword)
+}

+ 109 - 0
src/layout/components/search-input.vue

@@ -0,0 +1,109 @@
+<template>
+  <div @keyup.enter="search">
+    <v-menu offset-y>
+      <template v-slot:activator="{ on }">
+        <v-text-field
+          ref="search"
+          v-model="text"
+          solo
+          hide-details
+          label="想要搜点神马呢"
+          class="input-search"
+          autocomplete="off"
+          v-on="on"
+        />
+      </template>
+      <v-list v-if="items.length > 0" class="border-list" dense>
+        <v-list-item v-for="(item, index) in items" :key="index" @click="itemClick(item)">
+          <v-list-item-title>{{ item.name }}</v-list-item-title>
+        </v-list-item>
+      </v-list>
+    </v-menu>
+  </div>
+</template>
+
+<script>
+import { keywordSuggest } from '@/api/media/video'
+
+export default {
+  name: 'Search',
+  data() {
+    return {
+      text: '',
+      showSelect: true,
+      items: []
+    }
+  },
+  watch: {
+    text: 'handleInput'
+  },
+  methods: {
+    itemClick(item) {
+      this.text = item.name
+      this.$refs.search.blur()
+    },
+    handleInput(text) {
+      if (text.trim() !== '') {
+        this.showSelect = true
+        setTimeout(() => {
+          this.getKeyword(text)
+        }, 300)
+      }
+    },
+    getKeyword(keyword) {
+      keywordSuggest(keyword)
+        .then(res => {
+          if (res.code === 0) {
+            this.items = res.data
+          } else {
+            this.$notify({
+              title: res.code,
+              message: res.msg,
+              type: 'warning',
+              duration: 500
+            })
+          }
+        })
+        .catch(error => {
+          console.error(error.message)
+        })
+    },
+    search() {
+      this.$refs.search.blur()
+      /* this.$router.push({
+        path: '/search/result',
+        query: {
+          keyword: this.text
+        }
+      })*/
+      const routeUrl = this.$router.resolve({
+        path: '/search/result',
+        query: {
+          keyword: this.text
+        }
+      })
+      window.open(routeUrl.href, '_blank')
+    }
+  }
+}
+</script>
+
+<style scoped>
+    /*.input-search {*/
+    /*    width: 40%;*/
+    /*    margin: auto;*/
+    /*}*/
+    /*.width-20-percent {*/
+    /*    width: 20%;*/
+    /*}*/
+    /*.img-div {*/
+    /*    margin: 16vh 0 40px 0;*/
+    /*    text-align: center;*/
+    /*}*/
+    /*.v-menu__content {*/
+    /*    box-shadow: none !important;*/
+    /*}*/
+    /*.border-list {*/
+    /*    border: 1px solid #eee !important;*/
+    /*}*/
+</style>

+ 6 - 3
src/layout/index.vue

@@ -36,14 +36,15 @@
         <span style="cursor:pointer" @click="goToHome()">{{ this.$store.state.webInfo.name }}</span>
       </v-toolbar-title>
 
-      <v-text-field
+      <!--<v-text-field
         v-model="keyword"
         flat
         solo-inverted
         hide-details
         prepend-inner-icon="mdi-magnify"
         label="搜索"
-      />
+      />-->
+      <SearchInput/>
       <v-spacer />
       <v-tooltip bottom>
         <template v-slot:activator="{ on, attrs }">
@@ -98,11 +99,13 @@
 
 <script>
 import Head from '@/layout/components/head.vue'
+import SearchInput from '@/layout/components/search-input.vue'
 
 export default {
   // TODO 增加分类页
   components: {
-    Head
+    Head,
+    SearchInput
   },
   data: () => ({
     userInfo: {},

+ 6 - 0
src/router/index.js

@@ -42,6 +42,12 @@ const routes = [
         component: () => import('@/views/home/playlist.vue'),
         meta: { title: 'HerTube 稍后再看' }
       },
+      {
+        path: '/search/result',
+        name: 'SearchResult',
+        component: () => import('@/views/home/search-result.vue'),
+        meta: { title: 'HerTube 搜索结果' }
+      },
       {
         path: '/video/:id',
         name: 'Vide',

+ 0 - 1
src/views/home/index.vue

@@ -43,7 +43,6 @@ export default {
       videoRecommend(page)
         .then(res => {
           if (res.code === 0) {
-            // this.videoList = []
             for (const item of res.data.list) {
               this.videoList.push(item)
             }

+ 60 - 0
src/views/home/search-result.vue

@@ -0,0 +1,60 @@
+<template>
+  <v-container fill-height fluid style="padding-left: 24px; padding-right: 24px">
+    <div>
+      <v-row no-gutters>
+        <v-col
+            v-for="item in videoList"
+            :key="item.id"
+        >
+          <VideoCared :video="item" />
+        </v-col>
+      </v-row>
+    </div>
+  </v-container>
+</template>
+
+<script>
+import { videoQuery } from '@/api/media/video'
+import VideoCared from '@/components/player/video-card.vue'
+
+export default {
+  name: 'SearchResult',
+  components: {
+    VideoCared
+  },
+  data() {
+    return {
+      videoList: []
+    }
+  },
+  created() {
+    this.search(this.$route.query.keyword)
+  },
+  methods: {
+    search(keyword) {
+      videoQuery(keyword)
+        .then(res => {
+          if (res.code === 0) {
+            for (const item of res.data.list) {
+              this.videoList.push(item)
+            }
+          } else {
+            this.$notify({
+              title: res.code,
+              message: res.msg,
+              type: 'warning',
+              duration: 500
+            })
+          }
+        })
+        .catch(error => {
+          console.error(error.message)
+        })
+    }
+  }
+}
+</script>
+
+<style>
+
+</style>