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

更新 views/blog 模块

reghao 3 hónapja
szülő
commit
2f036fa8c7

+ 10 - 2
src/api/blog.js

@@ -12,8 +12,8 @@ const blogApi = {
   getBlogQuestion: '/api/blog/v2/question'
 }
 
-export function getPostList(pn) {
-  return get(blogApi.getPost + '/list?pn=' + pn)
+export function getPostList(queryInfo) {
+  return get(blogApi.getPost + '/list', queryInfo)
 }
 
 export function getPost(postId) {
@@ -36,6 +36,10 @@ export function getAbout() {
   return get(blogApi.getAbout)
 }
 
+export function getSearchList(queryInfo) {
+  return get(blogApi.getSearchList, queryInfo)
+}
+
 // blog 后台接口
 export function getBlogCategoryList(queryInfo) {
   return get(blogApi.getBlogCategory + '/list', queryInfo)
@@ -65,6 +69,10 @@ export function deleteBlogPost(formData) {
   return postForm(blogApi.getBlogPost + '/delete', formData)
 }
 
+export function resetBlogPostIndex() {
+  return post(blogApi.getBlogPost + '/reset_index')
+}
+
 export function getBlogQuestionList(queryInfo) {
   return get(blogApi.getBlogQuestion + '/list', queryInfo)
 }

+ 2 - 2
src/router/blog.js

@@ -38,7 +38,7 @@ export default {
       meta: { needAuth: false }
     },
     {
-      path: '/blog/category/:tag',
+      path: '/blog/category/post',
       name: 'TagPage',
       component: TagPage,
       meta: { needAuth: false }
@@ -50,7 +50,7 @@ export default {
       meta: { needAuth: false }
     },
     {
-      path: '/blog/tag/:tag',
+      path: '/blog/tag/post',
       name: 'TagPage',
       component: TagPage,
       meta: { needAuth: false }

+ 10 - 4
src/views/blog/AboutPage.vue

@@ -1,8 +1,14 @@
 <template>
-  <div>
-    <el-row class="movie-list">
-    </el-row>
-  </div>
+  <el-row v-if="blogAbout !== null" class="movie-list">
+    <el-card class="box-card">
+      <div slot="header" class="clearfix">
+        <span>{{ blogAbout.title }}</span>
+      </div>
+      <div class="text item">
+        {{ blogAbout.content }}
+      </div>
+    </el-card>
+  </el-row>
 </template>
 
 <script>

+ 18 - 3
src/views/blog/ArchivePage.vue

@@ -1,8 +1,23 @@
 <template>
-  <div>
+  <el-scrollbar style="width: 100%; height: 80vh;">
     <el-row class="movie-list">
+      <el-col :md="12">
+        <el-card class="box-card">
+          <el-timeline :reverse="true">
+            <el-timeline-item
+              v-for="(item, index) in blogArchive"
+              :key="index"
+              :timestamp="item.pubDate"
+            >
+              <router-link style="text-decoration-line: none" target="_blank" :to="`/blog/post/${item.articleId}`">
+                {{ item.title }}
+              </router-link>
+            </el-timeline-item>
+          </el-timeline>>
+        </el-card>
+      </el-col>
     </el-row>
-  </div>
+  </el-scrollbar>
 </template>
 
 <script>
@@ -12,7 +27,7 @@ export default {
   name: 'ArchivePage',
   data() {
     return {
-      blogArchive: null
+      blogArchive: []
     }
   },
   created() {

+ 46 - 74
src/views/blog/Article.vue

@@ -1,37 +1,34 @@
 <template>
-  <div>
-    <el-row class="movie-list">
-      <el-col :md="12">
+  <el-row class="movie-list">
+    <el-col :md="18">
+      <el-scrollbar style="width: 100%; height: 80vh;">
         <el-row v-for="(item, index) in dataList" :key="index" class="movie-list">
           <el-card class="box-card">
             <div slot="header" class="clearfix">
-              <span style="left: 0;margin-bottom: 0px;color: black;">{{ item.publishAt }}</span>
+              <span style="left: 0;margin-bottom: 0px;color: black;">
+                <router-link style="text-decoration-line: none" target="_blank" :to="`/blog/post/${item.articleId}`">
+                  {{ item.title }}
+                </router-link>
+              </span>
             </div>
             <div class="text item">
               <el-row>
-                <el-col :md="4">
-                  <router-link target="_blank" :to="`/blog/post/${item.articleId}`">
-                    <el-image
-                      lazy
-                      fit="cover"
-                      :src="item.coverUrl"
-                      class="coverImg"
-                    />
-                  </router-link>
+                <span v-html="item.summary" />
+              </el-row>
+              <el-row>
+                <el-col style="padding: 1px" :md="2" :sm="6" :xs="6">
+                  <span style="left: 0;margin-bottom: 0px;color: black;">
+                    <router-link style="text-decoration-line: none" target="_blank" :to="`/blog/category/post?name=${item.category}`">
+                      <el-tag type="warning">
+                        {{ item.category }}
+                      </el-tag>
+                    </router-link>
+                  </span>
                 </el-col>
-                <el-col :md="20">
-                  <router-link style="text-decoration-line: none" target="_blank" :to="`/blog/post/${item.articleId}`">
-                    <el-row>
-                      <div style="padding: 14px">
-                        <span style="left: 0;margin-bottom: 0px;color: black;">{{ item.title | ellipsis }}</span>
-                      </div>
-                    </el-row>
-                  </router-link>
-                  <el-row>
-                    <div style="padding: 14px">
-                      <span style="left: 0;margin-bottom: 0px;color: black;">{{ item.excerpt }}</span>
-                    </div>
-                  </el-row>
+                <el-col style="padding: 1px" :md="6" :sm="16" :xs="16">
+                  <span class="el-icon-watch" style="left: 0;margin-bottom: 0px;color: black;">
+                    {{ item.publishAt }}
+                  </span>
                 </el-col>
               </el-row>
             </div>
@@ -48,46 +45,30 @@
           @prev-click="handleCurrentChange"
           @next-click="handleCurrentChange"
         />
-      </el-col>
-      <el-col :md="6">
-        <el-row class="movie-list">
-          <el-card class="box-card">
-            <div slot="header" class="clearfix">
-              <el-row>
-                <span>热门</span>
-              </el-row>
-            </div>
-            <div class="text item">
-              <el-row />
-            </div>
-          </el-card>
-        </el-row>
-      </el-col>
-    </el-row>
-  </div>
+      </el-scrollbar>
+    </el-col>
+    <el-col :md="6">
+      <el-row class="movie-list">
+        <el-card class="box-card">
+          <div slot="header" class="clearfix">
+            <el-row>
+              <span>热门</span>
+            </el-row>
+          </div>
+          <div class="text item">
+            <el-row />
+          </div>
+        </el-card>
+      </el-row>
+    </el-col>
+  </el-row>
 </template>
 
 <script>
-import {getPostList } from '@/api/blog'
+import { getPostList } from '@/api/blog'
 
 export default {
-  name: 'ArticleIndex',
-  metaInfo: {
-    meta: [
-      { name: 'referrer', content: 'no-referrer' }
-    ]
-  },
-  filters: {
-    ellipsis(value) {
-      if (!value) return ''
-      const max = 50
-      if (value.length > max) {
-        return value.slice(0, max) + '...'
-      }
-      return value
-    }
-  },
-  components: {},
+  name: 'Article',
   data() {
     return {
       queryInfo: {
@@ -109,7 +90,7 @@ export default {
     }
 
     document.title = 'MyBlog'
-    this.getArticlesWrapper(this.currentPage)
+    this.getData()
   },
   mounted() {
     // 当窗口宽度改变时获取屏幕宽度
@@ -128,12 +109,12 @@ export default {
         query: this.queryInfo
       })
       this.currentPage = currentPage
-      this.getArticlesWrapper(this.currentPage)
+      this.getData(this.currentPage)
       // 回到顶部
       scrollTo(0, 0)
     },
-    getArticlesWrapper(page) {
-      getPostList(page).then(resp => {
+    getData() {
+      getPostList(this.queryInfo).then(resp => {
         if (resp.code === 0) {
           const respData = resp.data
           this.dataList = respData.list
@@ -155,21 +136,12 @@ export default {
   .movie-list {
     padding: 5px;
   }
-  .coverImg {
-    height: 120px !important;
-  }
 }
 
 .movie-list {
   padding: 5px;
 }
 
-.coverImg {
-  width: 100%;
-  height: 120px;
-  display: block;
-}
-
 .clearfix:before,
 .clearfix:after {
   display: table;

+ 24 - 31
src/views/blog/ArticlePage.vue

@@ -1,27 +1,30 @@
 <template>
   <el-row class="movie-list">
     <el-col :md="18">
-      <el-row class="movie-list">
-        <el-card class="box-card" v-if="article !== null">
-          <div slot="header" class="clearfix">
-            <el-row>
-              <span v-html="article.title" />
-            </el-row>
-            <el-divider />
-            <el-row>
-              <span v-html="article.publishAt" />
-            </el-row>
-          </div>
-          <div class="text item">
-            <el-row>
-              <markdown :source="article.content"></markdown>
-            </el-row>
-            <el-divider />
-            <el-row>
-            </el-row>
-          </div>
-        </el-card>
-      </el-row>
+      <el-scrollbar style="width: 100%; height: 80vh;">
+        <el-row class="movie-list">
+          <el-card class="box-card" v-if="article !== null">
+            <div slot="header" class="clearfix">
+              <el-row>
+                <span v-html="article.title" />
+              </el-row>
+              <el-divider />
+              <el-row>
+                <span v-html="article.publishAt" />
+              </el-row>
+            </div>
+            <div class="text item">
+              <el-row>
+<!--                <span v-html="article.content"></span>-->
+                <markdown :source="article.content"></markdown>
+              </el-row>
+              <el-divider />
+              <el-row>
+              </el-row>
+            </div>
+          </el-card>
+        </el-row>
+      </el-scrollbar>
     </el-col>
     <el-col :md="6">
       <el-row class="movie-list">
@@ -47,16 +50,6 @@ import { getPost } from '@/api/blog'
 export default {
   name: 'ArticlePage',
   components: { Markdown },
-  filters: {
-    ellipsis(value) {
-      if (!value) return ''
-      const max = 20
-      if (value.length > max) {
-        return value.slice(0, max) + '...'
-      }
-      return value
-    }
-  },
   data() {
     return {
       article: null,

+ 59 - 1
src/views/blog/Blog.vue

@@ -12,7 +12,7 @@
             </li>
           </ul>
         </el-col>
-        <el-col :md="20">
+        <el-col :md="8">
           <el-menu
             class="el-menu--horizontal el-menu"
             :default-active="this.$route.path"
@@ -41,6 +41,22 @@
             </el-menu-item>
           </el-menu>
         </el-col>
+        <el-col :md="6">
+          <ul class="el-menu--horizontal el-menu">
+            <li class="el-menu-item">
+              <el-autocomplete
+                v-model="keyword"
+                :placeholder="searchHint"
+                clearable
+                suffix-icon="el-icon-search"
+                size="medium"
+                :debounce="1000"
+                @keyup.enter.native="onSearch"
+                @select="onSearch"
+              />
+            </li>
+          </ul>
+        </el-col>
       </el-row>
       <router-view />
     </el-main>
@@ -52,6 +68,8 @@ export default {
   name: 'Blog',
   data() {
     return {
+      searchHint: '搜索文章',
+      keyword: ''
     }
   },
   watch: {
@@ -62,6 +80,46 @@ export default {
   },
   created() {
     document.title = 'MyBlog'
+  },
+  methods: {
+    handleSelect(key, keyPath) {
+      console.log(key, keyPath)
+    },
+    onSearch() {
+      // 正则去空格
+      if (this.keyword.replace(/\s*/g, '')) {
+        this.toSearchPage()
+      } else {
+        this.$message({
+          showClose: true,
+          message: '不能为空!',
+          type: 'warning'
+        })
+      }
+    },
+    // 跳转搜索页面,传递搜索框的参数
+    toSearchPage() {
+      const currentPath = this.$route.path
+      if (currentPath === '/blog/search') {
+        this.$router.push({
+          path: '/blog/search',
+          query: {
+            kw: this.keyword,
+            pn: 1
+          }
+        })
+        this.$router.go(0)
+      } else {
+        const routeUrl = this.$router.resolve({
+          path: '/blog/search',
+          query: {
+            kw: this.keyword,
+            pn: 1
+          }
+        })
+        window.open(routeUrl.href, '_blank')
+      }
+    }
   }
 }
 </script>

+ 26 - 9
src/views/blog/BlogPost.vue

@@ -17,6 +17,7 @@
           />
         </el-select>
         <el-button type="success" icon="el-icon-plus" style="margin-left: 5px" @click="handleAdd">添加</el-button>
+        <el-button type="warning" icon="el-icon-delete" style="margin-left: 5px" @click="handleResetIndex">重置索引</el-button>
       </el-row>
     </el-header>
     <el-main>
@@ -125,7 +126,13 @@
       >
         <template>
           <div id="editor">
-            <mavon-editor ref="md" style="height: 100%" :ishljs="true" :value="addForm.content" @change="onEditorChange" />
+            <mavon-editor
+              ref="md"
+              style="height: 100%"
+              :ishljs="true"
+              :value="addForm.content"
+              @change="onEditorChange"
+            />
           </div>
           <el-form :model="addForm" label-width="80px" style="margin: 5px">
             <el-form-item label="标题">
@@ -193,7 +200,7 @@ import {
   getBlogCategoryList,
   getBlogEditPost,
   getBlogPostList,
-  updateBlogPost
+  updateBlogPost, resetBlogPostIndex
 } from '@/api/blog'
 
 export default {
@@ -357,8 +364,23 @@ export default {
       // markdown文本格式
       this.addForm.content = this.$refs.md.d_value
     },
-    onEditorChange1() {
-      this.addForm.content = this.$refs.md1.d_value
+    handleResetIndex() {
+      this.$confirm('确定要重置文章索引?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        resetBlogPostIndex().then(resp => {
+          this.$message.info(resp.msg)
+        }).catch(error => {
+          this.$message.error(error.message)
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '已取消'
+        })
+      })
     }
   }
 }
@@ -370,9 +392,4 @@ export default {
   width: 100%;
   height: 480px;
 }
-#editor1 {
-  margin: auto;
-  width: 100%;
-  height: 480px;
-}
 </style>

+ 72 - 27
src/views/blog/SearchPage.vue

@@ -1,35 +1,75 @@
 <template>
-  <div>
-    <el-row class="movie-list">
-    </el-row>
-  </div>
+  <el-row class="movie-list">
+    <el-col :md="18">
+      <el-row v-for="(item, index) in dataList" :key="index" class="movie-list">
+        <el-card class="box-card">
+          <div slot="header" class="clearfix">
+            <router-link style="text-decoration-line: none" target="_blank" :to="`/blog/post/${item.articleId}`">
+              <span style="left: 0;margin-bottom: 0px;color: black;" v-html="item.title"></span>
+            </router-link>
+          </div>
+          <div class="text item">
+            <el-row>
+              <span v-html="item.summary" />
+            </el-row>
+            <el-row>
+              <el-col style="padding: 1px" :md="2" :sm="6" :xs="6">
+                <span style="left: 0;margin-bottom: 0px;color: black;">
+                    <router-link style="text-decoration-line: none" target="_blank" :to="`/blog/category/post?name=${item.category}`">
+                      <el-tag type="warning">
+                        {{ item.category }}
+                      </el-tag>
+                    </router-link>
+                  </span>
+              </el-col>
+              <el-col style="padding: 1px" :md="6" :sm="16" :xs="16">
+                <span class="el-icon-watch" style="left: 0;margin-bottom: 0px;color: black;">
+                  {{ item.publishAt }}
+                </span>
+              </el-col>
+            </el-row>
+          </div>
+        </el-card>
+      </el-row>
+      <el-pagination
+        background
+        :small="screenWidth <= 768"
+        layout="prev, pager, next"
+        :page-size="pageSize"
+        :current-page="currentPage"
+        :total="totalSize"
+        @current-change="handleCurrentChange"
+        @prev-click="handleCurrentChange"
+        @next-click="handleCurrentChange"
+      />
+    </el-col>
+    <el-col :md="6">
+      <el-row class="movie-list">
+        <el-card class="box-card">
+          <div slot="header" class="clearfix">
+            <el-row>
+              <span>热门</span>
+            </el-row>
+          </div>
+          <div class="text item">
+            <el-row />
+          </div>
+        </el-card>
+      </el-row>
+    </el-col>
+  </el-row>
 </template>
 
 <script>
-import {getPostList } from '@/api/blog'
+import { getSearchList } from '@/api/blog'
 
 export default {
-  name: 'ArticleIndex',
-  metaInfo: {
-    meta: [
-      { name: 'referrer', content: 'no-referrer' }
-    ]
-  },
-  filters: {
-    ellipsis(value) {
-      if (!value) return ''
-      const max = 50
-      if (value.length > max) {
-        return value.slice(0, max) + '...'
-      }
-      return value
-    }
-  },
-  components: {},
+  name: 'SearchPage',
   data() {
     return {
       queryInfo: {
-        pn: 1
+        pn: 1,
+        kw: ''
       },
       // 屏幕宽度, 为了控制分页条的大小
       screenWidth: document.body.clientWidth,
@@ -45,8 +85,13 @@ export default {
       this.currentPage = parseInt(pageNumber)
       this.queryInfo.pn = parseInt(pageNumber)
     }
+    const kw = this.$route.query.kw
+    if (kw !== undefined && kw !== null) {
+      this.queryInfo.kw = kw
+    }
 
     document.title = '搜索结果'
+    this.getData()
   },
   mounted() {
     // 当窗口宽度改变时获取屏幕宽度
@@ -61,16 +106,16 @@ export default {
     handleCurrentChange(currentPage) {
       this.queryInfo.pn = currentPage
       this.$router.push({
-        path: '/blog',
+        path: '/blog/search',
         query: this.queryInfo
       })
       this.currentPage = currentPage
-      this.getArticlesWrapper(this.currentPage)
+      this.getData(this.currentPage)
       // 回到顶部
       scrollTo(0, 0)
     },
-    getArticlesWrapper(page) {
-      getPostList(page).then(resp => {
+    getData() {
+      getSearchList(this.queryInfo).then(resp => {
         if (resp.code === 0) {
           const respData = resp.data
           this.dataList = respData.list

+ 17 - 9
src/views/blog/TagIndex.vue

@@ -1,22 +1,30 @@
 <template>
-  <div>
-    <el-row class="movie-list">
+  <el-scrollbar style="width: 100%; height: 80vh;">
+    <el-row v-if="blogTag" class="movie-list">
       <el-tag
         v-for="(tag,index) in dataList"
         :key="index"
-        class="tag"
-        size="medium"
-        effect="plain"
+        type="success"
+        style="margin: 5px"
       >
-        <router-link v-if="blogTag" style="text-decoration-line: none" target="_blank" :to="`/blog/tag/` + tag.name">
+        <router-link style="text-decoration-line: none" target="_blank" :to="`/blog/tag/post?name=` + tag.name">
           {{ tag.name }}
         </router-link>
-        <router-link v-else style="text-decoration-line: none" target="_blank" :to="`/blog/category/` + tag.name">
+      </el-tag>
+    </el-row>
+    <el-row v-else class="movie-list">
+      <el-tag
+        v-for="(tag,index) in dataList"
+        :key="index"
+        type="success"
+        style="margin: 5px"
+      >
+        <router-link style="text-decoration-line: none" target="_blank" :to="`/blog/category/post?name=` + tag.name">
           {{ tag.name }}
         </router-link>
       </el-tag>
     </el-row>
-  </div>
+  </el-scrollbar>
 </template>
 
 <script>
@@ -44,7 +52,7 @@ export default {
         document.title = '文章标签'
         this.queryInfo.type = 'tag'
         this.blogTag = true
-        this.getData1()
+        this.getData()
       }
     } else {
       document.title = 'BlogTag'

+ 67 - 21
src/views/blog/TagPage.vue

@@ -1,8 +1,67 @@
 <template>
-  <div>
-    <el-row class="movie-list">
-    </el-row>
-  </div>
+  <el-row class="movie-list">
+    <el-col :md="18">
+      <el-scrollbar style="width: 100%; height: 80vh;">
+        <el-row v-for="(item, index) in dataList" :key="index" class="movie-list">
+          <el-card class="box-card">
+            <div slot="header" class="clearfix">
+              <span style="left: 0;margin-bottom: 0px;color: black;">
+                <router-link style="text-decoration-line: none" target="_blank" :to="`/blog/post/${item.articleId}`">
+                  {{ item.title }}
+                </router-link>
+              </span>
+            </div>
+            <div class="text item">
+              <el-row>
+                <span v-html="item.summary" />
+              </el-row>
+              <el-row>
+                <el-col style="padding: 1px" :md="2" :sm="6" :xs="6">
+                  <span style="left: 0;margin-bottom: 0px;color: black;">
+                    <router-link style="text-decoration-line: none" target="_blank" :to="`/blog/category/post?name=${item.category}`">
+                      <el-tag type="warning">
+                        {{ item.category }}
+                      </el-tag>
+                    </router-link>
+                  </span>
+                </el-col>
+                <el-col style="padding: 1px" :md="6" :sm="16" :xs="16">
+                  <span class="el-icon-watch" style="left: 0;margin-bottom: 0px;color: black;">
+                    {{ item.publishAt }}
+                  </span>
+                </el-col>
+              </el-row>
+            </div>
+          </el-card>
+        </el-row>
+        <el-pagination
+          background
+          :small="screenWidth <= 768"
+          layout="prev, pager, next"
+          :page-size="pageSize"
+          :current-page="currentPage"
+          :total="totalSize"
+          @current-change="handleCurrentChange"
+          @prev-click="handleCurrentChange"
+          @next-click="handleCurrentChange"
+        />
+      </el-scrollbar>
+    </el-col>
+    <el-col :md="6">
+      <el-row class="movie-list">
+        <el-card class="box-card">
+          <div slot="header" class="clearfix">
+            <el-row>
+              <span>热门</span>
+            </el-row>
+          </div>
+          <div class="text item">
+            <el-row />
+          </div>
+        </el-card>
+      </el-row>
+    </el-col>
+  </el-row>
 </template>
 
 <script>
@@ -10,22 +69,6 @@ import { getTagPost } from '@/api/blog'
 
 export default {
   name: 'TagPage',
-  metaInfo: {
-    meta: [
-      { name: 'referrer', content: 'no-referrer' }
-    ]
-  },
-  filters: {
-    ellipsis(value) {
-      if (!value) return ''
-      const max = 50
-      if (value.length > max) {
-        return value.slice(0, max) + '...'
-      }
-      return value
-    }
-  },
-  components: {},
   data() {
     return {
       queryInfo: {
@@ -47,6 +90,10 @@ export default {
       this.currentPage = parseInt(pageNumber)
       this.queryInfo.pn = parseInt(pageNumber)
     }
+    const name = this.$route.query.name
+    if (name !== undefined && name !== null) {
+      this.queryInfo.name = name
+    }
 
     const path = this.$route.path
     const arr = path.split('/')
@@ -55,7 +102,6 @@ export default {
       return
     }
 
-    this.queryInfo.name = arr[3]
     if (arr[2] === 'tag') {
       this.queryInfo.type = 'tag'
       document.title = '包含标签 ' + this.queryInfo.name + ' 的文章'