瀏覽代碼

修改 blog相關頁面顯示

oransheep 2 年之前
父節點
當前提交
cdca8fdaca

+ 0 - 3
resources/js/src/@core/auth/jwt/jwtDefaultConfig.js

@@ -4,9 +4,6 @@ export default {
   registerEndpoint: '/jwt/register',
   refreshEndpoint: '/jwt/refresh-token',
   logoutEndpoint: '/api/logout',
-  getDatasetEndpoint: '/api/get_dataset',
-  postCommentEndpoint: '/api/post_comment',
-  deleteCommentEndpoint: '/api/delete_comment',
 
   // This will be prefixed in authorization header with token
   // e.g. Authorization: Bearer <token>

+ 2 - 10
resources/js/src/@core/auth/jwt/jwtService.js

@@ -113,15 +113,7 @@ export default class JwtService {
     })
   }
 
-  getDataset(...args) {
-    return this.axiosIns.post(this.jwtConfig.getDatasetEndpoint, ...args)
-  }
-
-  postComment(...args) {
-    return this.axiosIns.post(this.jwtConfig.postCommentEndpoint, ...args)
-  }
-
-  deleteComment(...args) {
-    return this.axiosIns.post(this.jwtConfig.deleteCommentEndpoint, ...args)
+  getPost(url, ...args) {
+    return this.axiosIns.post(url, ...args)
   }
 }

+ 0 - 0
resources/js/src/assets/images/banner/banner.png → resources/js/src/assets/images/banner/banner-0.png


二進制
resources/js/src/assets/images/banner/parallax-4.jpg


+ 36 - 100
resources/js/src/views/blog/BlogDetail.vue

@@ -6,10 +6,10 @@
       <b-row>
         <!-- blogs -->
         <b-col cols="12">
-          <b-card :img-src="blogDetail.blog.img" img-top img-alt="Blog Detail Pic" :title="blogDetail.blog.title">
+          <b-card :img-src="defaultsImg()" img-top img-alt="Blog Detail Pic" :title="blogDetail.blog.title">
             <b-media no-body>
               <b-media-aside vertical-align="center" class="mr-50">
-                <b-avatar href="javascript:void(0)" size="24" :src="blogDetail.blog.avatar" />
+                <b-avatar href="javascript:void(0)" size="24" :src="getUserAvatar(blogDetail.blog.userId)" />
               </b-media-aside>
               <b-media-body>
                 <small class="text-muted mr-50">by</small>
@@ -17,11 +17,11 @@
                   <b-link class="text-body">{{ blogDetail.blog.userFullName }}</b-link>
                 </small>
                 <span class="text-muted ml-75 mr-50">|</span>
-                <small class="text-muted">{{ blogDetail.blog.createdTime }}</small>
+                <small class="text-muted">{{ dateFormat(blogDetail.blog.createdTime) }}</small>
               </b-media-body>
             </b-media>
             <div class="my-1 py-25">
-              <b-link v-for="tag in blogDetail.blog.tags" :key="tag">
+              <b-link v-for="tag in JSON.parse(blogDetail.blog.tags)" :key="tag">
                 <b-badge pill class="mr-75" :variant="tagsColor(tag)">
                   {{ tag }}
                 </b-badge>
@@ -55,7 +55,7 @@
                   </b-link>
                   <b-link>
                     <div class="text-body">
-                      {{ kFormatter(blogDetail.blog.comments) }}
+                      {{ blogDetail.blog.comments ? kFormatter(blogDetail.blog.comments) : 0 }}
                     </div>
                   </b-link>
                 </div>
@@ -96,13 +96,13 @@
           <b-card v-for="(comment, index) in blogDetail.comments" :key="index">
             <b-media no-body>
               <b-media-aside class="mr-75">
-                <b-avatar :src="comment.avatar" size="38" />
+                <b-avatar :src="getUserAvatar(comment.userId)" size="38" />
               </b-media-aside>
               <b-media-body>
                 <h6 class="font-weight-bolder mb-25">
                   {{ comment.userFullName }}
                 </h6>
-                <b-card-text>{{ comment.commentedAt }}</b-card-text>
+                <b-card-text>{{ dateFormat(comment.commentedAt) }}</b-card-text>
                 <b-card-text>
                   {{ comment.commentText }}
                 </b-card-text>
@@ -132,9 +132,9 @@
                   </b-form-group>
                 </b-col>
                 <b-col cols="12">
-                  <b-form-checkbox id="checkbox-1" v-model="commentCheckmark" name="checkbox-1" class="mb-2">
+                  <!-- <b-form-checkbox id="checkbox-1" v-model="commentCheckmark" name="checkbox-1" class="mb-2">
                     Save my name, email, and website in this browser for the next time I comment.
-                  </b-form-checkbox>
+                  </b-form-checkbox> -->
                 </b-col>
                 <b-col cols="12">
                   <b-button v-ripple.400="'rgba(255, 255, 255, 0.15)'" variant="primary" @click="postComment">
@@ -172,18 +172,18 @@
         <b-media v-for="(recentpost, index) in blogSidebar.recentPosts" :key="index" no-body
           :class="index ? 'mt-2' : ''">
           <b-media-aside class="mr-2">
-            <b-link>
-              <b-img :src="recentpost.img" :alt="recentpost.img.slice(6)" width="100" rounded height="70" />
+            <b-link :to="{ name: 'blog-detail', params: { id: recentpost.id } }">
+              <b-img :src="defaultsImg()" :alt="defaultsImg().slice(6)" width="100" rounded height="70" />
             </b-link>
           </b-media-aside>
           <b-media-body>
             <h6 class="blog-recent-post-title">
-              <b-link class="text-body-heading">
+              <b-link :to="{ name: 'blog-detail', params: { id: recentpost.id } }" class="text-body-heading">
                 {{ recentpost.title }}
               </b-link>
             </h6>
             <span class="text-muted mb-0">
-              {{ recentpost.createdTime }}
+              {{ dateFormat(recentpost.createdTime) }}
             </span>
           </b-media-body>
         </b-media>
@@ -280,95 +280,20 @@ export default {
       blogId: this.$route.params.id,
       search_query: '',
       commentCheckmark: '',
-      blogDetail: [],
+      blogDetail: {},
       blogSidebar: {},
       socialShareIcons: ['GithubIcon', 'GitlabIcon', 'FacebookIcon', 'TwitterIcon', 'LinkedinIcon'],
+      userData: getUserData(),
     }
   },
   created() {
-    this.blogDetail.blog = {};
-    this.blogDetail.comments = [];
-    this.blogSidebar.recentPosts = [];
-
-    useJwt.getDataset({
-      sql: `SELECT title, content, tags, users.id AS userId, users.name AS userFullName, blogs.created_at AS createdTime, bookmarked
-      FROM [laravel_kevin].[dbo].[blogs]
-      RIGHT JOIN [dbo].[users] ON [blogs].[writer] = [users].[id]
-      WHERE blogs.id=` + this.blogId
+    useJwt.getPost('/api/get_blog/detail', { blogId: this.blogId }).then(res => {
+      this.blogDetail = res.data
     })
-      .then(res => {
-        this.blogDetail.blog = res.data[0]
-        this.blogDetail.blog.createdTime = format(new Date(this.blogDetail.blog.createdTime), 'yyyy-MM-dd hh:mm', { locale: zhTW })
-        this.blogDetail.blog.img = require('@/assets/images/banner/banner-27.jpg')
-        this.blogDetail.blog.tags = JSON.parse(res.data[0].tags)
-        this.blogDetail.blog.avatar = require('@/assets/images/avatars/' + res.data[0].userId + '-small.png')
-        this.blogDetail.blog.comment = 2
-      })
 
-    useJwt.getDataset({
-      sql: `SELECT comment AS commentText, comments.created_at AS commentedAt, users.id AS userId, users.name AS userFullName
-      FROM [laravel_kevin].[dbo].[comments]
-      RIGHT JOIN [dbo].[users] ON [comments].[writer] = [users].[id]
-      WHERE [blogId]=` + this.blogId
+    useJwt.getPost('/api/get_blog/sidebar').then(res => {
+      this.blogSidebar = res.data
     })
-      .then(res => {
-        var temp;
-        res.data.forEach(element => {
-          temp = element
-          temp.commentedAt = format(new Date(temp.commentedAt), 'yyyy-MM-dd hh:mm', { locale: zhTW })
-          temp.avatar = require('@/assets/images/avatars/' + temp.userId + '-small.png')
-
-          this.blogDetail.comments.push(temp)
-        });
-      })
-
-    useJwt.getDataset({
-      sql: `SELECT blogs.id, title, blogs.created_at AS blogPosted
-      FROM [laravel_kevin].[dbo].[blogs]
-      RIGHT JOIN [dbo].[users] ON [blogs].[writer] = [users].[id]` })
-      .then(res => {
-        var temp;
-        res.data.forEach(element => {
-          temp = element
-          temp.blogPosted = format(new Date(temp.blogPosted), 'yyyy-MM-dd hh:mm', { locale: zhTW })
-          temp.img = require('@/assets/images/banner/banner-27.jpg')
-
-          this.blogSidebar.recentPosts.push({ id: temp.id, img: temp.img, title: temp.title, createdTime: temp.blogPosted })
-        });
-      })
-
-    this.blogSidebar.categories = [
-      { category: 'Fashion', icon: 'WatchIcon' },
-      { category: 'Food', icon: 'ShoppingCartIcon' },
-      { category: 'Gaming', icon: 'CommandIcon' },
-      { category: 'Quote', icon: 'HashIcon' },
-      { category: 'Video', icon: 'VideoIcon' },
-    ]
-
-    // this.blogDetail.blog = {
-    //   "title": "Mouse, sharply and.",
-    //   "content": "Trims his belt and his friends shared their never-ending meal, and the Hatter added as an explanation. 'Oh, you're sure to do with this creature when I find a thing,' said the March Hare. 'Then it.",
-    //   "tags": [
-    //     "Gaming",
-    //     "Video",
-    //     "Fashion",
-    //     "Test"
-    //   ],
-    //   "userId": "2",
-    //   "userFullName": "kevin",
-    //   "createdTime": "2022-12-14 06:38:31.603",
-    //   "bookmarked": "8677",
-    //   "img": "/images/_/_/_/_/MessagePractise/resources/js/src/assets/images/banner/banner-27.jpg",
-    //   "avatar": "/images/_/_/_/_/MessagePractise/resources/js/src/assets/images/avatars/2-small.png",
-    //   "comment": 2
-    // }
-
-    // this.$http.get('/blog/list/data/detail').then(res => {
-    //   this.blogDetail = res.data
-    // })
-    // this.$http.get('/blog/list/data/sidebar').then(res => {
-    //   this.blogSidebar = res.data
-    // })
   },
   methods: {
     kFormatter,
@@ -380,18 +305,29 @@ export default {
       if (tag === 'Food') return 'light-success'
       return 'light-primary'
     },
+    dateFormat(date) {
+      return format(new Date(date), 'yyyy-MM-dd hh:mm', { locale: zhTW })
+    },
+    getUserAvatar(userId) {
+      return require('@/assets/images/avatars/' + userId + '-small.png')
+    },
+    defaultsImg() {
+      return require('@/assets/images/banner/banner-27.jpg')
+    },
     postComment() {
-      useJwt.postComment({
+      useJwt.getPost('/api/comment/post', {
         comment: document.getElementById("comment-text").value,
         blogId: this.$route.params.id,
       })
         .then(res => {
-          alert(res.data)
+          this.blogDetail.comments.push({
+            userId: this.userData.id,
+            userFullName: this.userData.name,
+            commentedAt: new Date(),
+            commentText: document.getElementById("comment-text").value,
+          })
+          document.getElementById("comment-text").value = ''
         })
-
-      document.getElementById("comment-text").value = ''
-      // this.$router.push({ name: 'blog-detail', params: { id: this.blogId } })
-      // return Redirect::refresh()
     }
   },
 }

+ 23 - 42
resources/js/src/views/blog/BlogList.vue

@@ -1,12 +1,12 @@
 <template>
-  <content-with-sidebar class="blog-wrapper">
+  <content-with-sidebar v-if="Object.keys(blogList).length" class="blog-wrapper">
 
     <!-- blogs -->
     <b-row class="blog-list-wrapper">
       <b-col v-for="(blog, index) in blogList" :key="index" md="6">
         <b-card tag="article" no-body>
           <b-link :to="{ name: 'blog-detail', params: { id: blog.id } }">
-            <b-img :src="blog.img" :alt="blog.img.slice(5)" class="card-img-top" />
+            <b-img :src="defaultsImg()" :alt="defaultsImg().slice(5)" class="card-img-top" />
           </b-link>
           <b-card-body>
             <b-card-title>
@@ -17,7 +17,7 @@
             </b-card-title>
             <b-media no-body>
               <b-media-aside vertical-align="center" class="mr-50">
-                <b-avatar href="javascript:void(0)" size="24" :src="blog.avatar" />
+                <b-avatar href="javascript:void(0)" size="24" :src="getUserAvatar(blog.userId)" />
               </b-media-aside>
               <b-media-body>
                 <small class="text-muted mr-50">by</small>
@@ -25,11 +25,11 @@
                   <b-link class="text-body">{{ blog.userFullName }}</b-link>
                 </small>
                 <span class="text-muted ml-75 mr-50">|</span>
-                <small class="text-muted">{{ blog.blogPosted }}</small>
+                <small class="text-muted">{{ dateFormat(blog.blogPosted) }}</small>
               </b-media-body>
             </b-media>
             <div class="my-1 py-25">
-              <b-link v-for="(tag, index) in blog.tags" :key="index">
+              <b-link v-for="(tag, index) in JSON.parse(blog.tags)" :key="index">
                 <b-badge pill class="mr-75" :variant="tagsColor(tag)">
                   {{ tag }}
                 </b-badge>
@@ -43,7 +43,7 @@
               <b-link :to="{ path: `/pages/blog/${blog.id}#blogComment` }">
                 <div class="d-flex align-items-center text-body">
                   <feather-icon icon="MessageSquareIcon" class="mr-50" />
-                  <span class="font-weight-bold">{{ kFormatter(blog.comment) }} Comments</span>
+                  <span class="font-weight-bold">{{ blog.comment ? kFormatter(blog.comment) : 0 }} Comments</span>
                 </div>
               </b-link>
               <b-link :to="{ name: 'blog-detail', params: { id: blog.id } }" class="font-weight-bold">
@@ -93,7 +93,7 @@
           :class="index ? 'mt-2' : ''">
           <b-media-aside class="mr-2">
             <b-link :to="{ name: 'blog-detail', params: { id: recentpost.id } }">
-              <b-img :src="recentpost.img" :alt="recentpost.img.slice(6)" width="100" rounded height="70" />
+              <b-img :src="defaultsImg()" :alt="defaultsImg().slice(6)" width="100" rounded height="70" />
             </b-link>
           </b-media-aside>
           <b-media-body>
@@ -103,7 +103,7 @@
               </b-link>
             </h6>
             <span class="text-muted mb-0">
-              {{ recentpost.createdTime }}
+              {{ dateFormat(recentpost.createdTime) }}
             </span>
           </b-media-body>
         </b-media>
@@ -196,41 +196,13 @@ export default {
     }
   },
   created() {
-    this.blogSidebar.recentPosts = [];
+    useJwt.getPost('/api/get_blog/list').then(res => {
+      this.blogList = res.data
+    })
 
-    useJwt.getDataset({
-      sql: `SELECT blogs.id, title, content AS excerpt, tags, users.id AS userId, users.name AS userFullName, blogs.created_at AS blogPosted
-      FROM [laravel_kevin].[dbo].[blogs]
-      RIGHT JOIN [dbo].[users] ON [blogs].[writer] = [users].[id]` })
-      .then(res => {
-        var temp;
-        res.data.forEach(element => {
-          temp = element
-          temp.blogPosted = format(new Date(temp.blogPosted), 'yyyy-MM-dd hh:mm', { locale: zhTW });
-          temp.img = require('@/assets/images/banner/banner-27.jpg')
-          temp.tags = JSON.parse(temp.tags)
-          temp.avatar = require('@/assets/images/avatars/' + temp.userId + '-small.png')
-          temp.comment = 2
-
-          this.blogList.push(temp)
-          this.blogSidebar.recentPosts.push({ id: temp.id, img: temp.img, title: temp.title, createdTime: temp.blogPosted })
-        });
-      })
-
-    this.blogSidebar.categories = [
-      { category: 'Fashion', icon: 'WatchIcon' },
-      { category: 'Food', icon: 'ShoppingCartIcon' },
-      { category: 'Gaming', icon: 'CommandIcon' },
-      { category: 'Quote', icon: 'HashIcon' },
-      { category: 'Video', icon: 'VideoIcon' },
-    ]
-
-    // this.$http.get('/blog/list/data').then(res => {
-    //   this.blogList = res.data
-    // })
-    // this.$http.get('/blog/list/data/sidebar').then(res => {
-    //   this.blogSidebar = res.data
-    // })
+    useJwt.getPost('/api/get_blog/sidebar').then(res => {
+      this.blogSidebar = res.data
+    })
   },
   methods: {
     kFormatter,
@@ -242,6 +214,15 @@ export default {
       if (tag === 'Food') return 'light-success'
       return 'light-primary'
     },
+    dateFormat(date) {
+      return format(new Date(date), 'yyyy-MM-dd hh:mm', { locale: zhTW })
+    },
+    getUserAvatar(userId) {
+      return require('@/assets/images/avatars/' + userId + '-small.png')
+    },
+    defaultsImg() {
+      return require('@/assets/images/banner/banner-27.jpg')
+    },
   },
 }
 </script>

+ 67 - 12
routes/api.php

@@ -8,6 +8,7 @@ use Illuminate\Support\Facades\DB;
 
 use App\Models\User;
 use App\Models\Message;
+use App\Models\Blog;
 use App\Models\Comment;
 
 /*
@@ -51,16 +52,7 @@ Route::middleware('auth:sanctum')->post('/logout', function (Request $request) {
     return $user;
 });
 
-Route::middleware('auth:sanctum')->post('/get_dataset', function (Request $request) {
-    $request->validate([
-        'sql' => 'required',
-    ]);
-
-    $dataset = DB::select($request->sql);
-    return $dataset;
-});
-
-Route::middleware('auth:sanctum')->post('/post_comment', function (Request $request) {
+Route::middleware('auth:sanctum')->post('/comment/post', function (Request $request) {
     $request->validate([
         'comment' => 'required',
         'blogId' => 'required',
@@ -77,7 +69,7 @@ Route::middleware('auth:sanctum')->post('/post_comment', function (Request $requ
     return 'success';
 });
 
-Route::middleware('auth:sanctum')->post('/delete_comment', function (Request $request) {
+Route::middleware('auth:sanctum')->post('/comment/delete', function (Request $request) {
     $request->validate([
         'commentID' => 'required',
     ]);
@@ -85,4 +77,67 @@ Route::middleware('auth:sanctum')->post('/delete_comment', function (Request $re
     Comment::where('id', '=', $request->commentID)->delete();
 
     return 'success';
-});
+});
+
+Route::middleware('auth:sanctum')->post('/get_blog/list', function (Request $request) {
+    $blogList = DB::select("SELECT 
+            blogs.id, 
+            title, 
+            content AS excerpt, 
+            tags, users.id AS userId, 
+            users.name AS userFullName, 
+            blogs.created_at AS blogPosted, 
+            t.total AS comment
+        FROM [laravel_kevin].[dbo].[blogs]
+        RIGHT JOIN [dbo].[users] ON [blogs].[writer] = [users].[id]
+        LEFT JOIN (
+            SELECT [blogId],COUNT(*) AS total
+            FROM [laravel_kevin].[dbo].[comments]
+            GROUP BY [blogId]) as t ON [blogs].[id] = [t].[blogId]");
+
+    return $blogList;
+});
+
+Route::middleware('auth:sanctum')->post('/get_blog/detail', function (Request $request) {
+    $request->validate([
+        'blogId' => 'required',
+    ]);
+    $blog = DB::select("SELECT 
+            title, 
+            content, 
+            tags, 
+            users.id AS userId, 
+            users.name AS userFullName, 
+            blogs.created_at AS createdTime, 
+            bookmarked, 
+            t.total AS comments
+        FROM [laravel_kevin].[dbo].[blogs]
+        RIGHT JOIN [dbo].[users] ON [blogs].[writer] = [users].[id]
+        LEFT JOIN (
+            SELECT [blogId],COUNT(*) AS total
+            FROM [laravel_kevin].[dbo].[comments]
+            GROUP BY [blogId]) as t ON [blogs].[id] = [t].[blogId]
+        WHERE blogs.id=" . $request->blogId);
+
+    $comments = DB::select("SELECT comment AS commentText, comments.created_at AS commentedAt, users.id AS userId, users.name AS userFullName
+        FROM [laravel_kevin].[dbo].[comments]
+        RIGHT JOIN [dbo].[users] ON [comments].[writer] = [users].[id]
+        WHERE [blogId]=" . $request->blogId);
+    return ['blog' => $blog[0], 'comments' => $comments];
+});
+
+Route::middleware('auth:sanctum')->post('/get_blog/sidebar', function (Request $request) {
+    $recentPosts = DB::select("SELECT blogs.id, title, blogs.created_at AS createdTime
+        FROM [laravel_kevin].[dbo].[blogs]
+        RIGHT JOIN [dbo].[users] ON [blogs].[writer] = [users].[id]");
+
+    $categories = [
+        ['category' => 'Fashion', 'icon' => 'WatchIcon'],
+        ['category' => 'Food', 'icon' => 'ShoppingCartIcon'],
+        ['category' => 'Gaming', 'icon' => 'CommandIcon'],
+        ['category' => 'Quote', 'icon' => 'HashIcon'],
+        ['category' => 'Video', 'icon' => 'VideoIcon'],
+    ];
+
+    return ['recentPosts' => $recentPosts, 'categories' => $categories];
+});