From e7a292efc59e115b04fd7f28158b7725dd009b65 Mon Sep 17 00:00:00 2001 From: sunface Date: Fri, 9 Apr 2021 17:23:50 +0800 Subject: [PATCH] update --- .../{interaction => dashboard}/followers.tsx | 4 +- .../following-tags.tsx | 4 +- .../following-users.tsx | 4 +- pages/dashboard/stats.tsx | 109 ++++++++++++++++++ server/internal/api/posts.go | 11 ++ server/internal/api/story.go | 1 + server/internal/server.go | 1 + server/internal/storage/sql_tables.go | 1 + server/internal/story/post.go | 4 + server/internal/story/posts.go | 20 ++++ server/internal/user/user.go | 6 + server/pkg/common/reserve_urls.go | 2 +- src/components/user-menu.tsx | 4 +- src/data/links.tsx | 13 ++- src/data/reserve-urls.ts | 2 +- src/types/story.ts | 2 + 16 files changed, 174 insertions(+), 14 deletions(-) rename pages/{interaction => dashboard}/followers.tsx (92%) rename pages/{interaction => dashboard}/following-tags.tsx (96%) rename pages/{interaction => dashboard}/following-users.tsx (93%) create mode 100644 pages/dashboard/stats.tsx diff --git a/pages/interaction/followers.tsx b/pages/dashboard/followers.tsx similarity index 92% rename from pages/interaction/followers.tsx rename to pages/dashboard/followers.tsx index a51271ba..49b1149c 100644 --- a/pages/interaction/followers.tsx +++ b/pages/dashboard/followers.tsx @@ -4,7 +4,7 @@ import Nav from "layouts/nav/nav" import PageContainer from "layouts/page-container" import Sidebar from "layouts/sidebar/sidebar" import React, { useEffect, useState } from "react" -import {adminLinks, interactionLinks} from "src/data/links" +import {dashboardLinks} from "src/data/links" import { requestApi } from "utils/axios/request" import PageContainer1 from "layouts/page-container1" import Empty from "components/empty" @@ -30,7 +30,7 @@ const FollowersPage = () => { <> - + { users.length === 0 ? : diff --git a/pages/interaction/following-tags.tsx b/pages/dashboard/following-tags.tsx similarity index 96% rename from pages/interaction/following-tags.tsx rename to pages/dashboard/following-tags.tsx index 16dff4eb..4da22f50 100644 --- a/pages/interaction/following-tags.tsx +++ b/pages/dashboard/following-tags.tsx @@ -2,7 +2,7 @@ import { Text, Box, Heading, Image, Divider, useToast, HStack, Slider, SliderTra import Card from "components/card" import Sidebar from "layouts/sidebar/sidebar" import React, { useEffect, useState } from "react" -import {interactionLinks} from "src/data/links" +import {dashboardLinks} from "src/data/links" import { requestApi } from "utils/axios/request" import { useRouter } from "next/router" import PageContainer1 from "layouts/page-container1" @@ -42,7 +42,7 @@ const TagsPage = () => { <> - + Adjust tag weight to modify your home feed. Higher values mean more appearances. diff --git a/pages/interaction/following-users.tsx b/pages/dashboard/following-users.tsx similarity index 93% rename from pages/interaction/following-users.tsx rename to pages/dashboard/following-users.tsx index 4522c919..00e8a14e 100644 --- a/pages/interaction/following-users.tsx +++ b/pages/dashboard/following-users.tsx @@ -4,7 +4,7 @@ import Nav from "layouts/nav/nav" import PageContainer from "layouts/page-container" import Sidebar from "layouts/sidebar/sidebar" import React, { useEffect, useState } from "react" -import {interactionLinks} from "src/data/links" +import {dashboardLinks} from "src/data/links" import { requestApi } from "utils/axios/request" import PageContainer1 from "layouts/page-container1" import Empty from "components/empty" @@ -37,7 +37,7 @@ const UsersPage = () => { <> - + { users.length === 0 ? : diff --git a/pages/dashboard/stats.tsx b/pages/dashboard/stats.tsx new file mode 100644 index 00000000..b2c27441 --- /dev/null +++ b/pages/dashboard/stats.tsx @@ -0,0 +1,109 @@ +import { Text, Box, Heading, Image, Center, Button, Flex, VStack, Divider, useToast, Wrap, WrapItem, useColorModeValue, StackDivider, HStack } from "@chakra-ui/react" +import Card from "components/card" +import Nav from "layouts/nav/nav" +import PageContainer from "layouts/page-container" +import Sidebar from "layouts/sidebar/sidebar" +import React, { useEffect, useState } from "react" +import { dashboardLinks } from "src/data/links" +import { requestApi } from "utils/axios/request" +import PageContainer1 from "layouts/page-container1" +import Empty from "components/empty" +import { IDType } from "src/types/id" +import UserCard from "components/users/user-card" +import userCustomTheme from "theme/user-custom" +import { Story } from "src/types/story" +import moment from 'moment' +import { FaComment, FaEye, FaHeart, FaRegComment, FaRegEye, FaRegHeart } from "react-icons/fa" +import Link from "next/link" + +const DashboardPage = () => { + const [stories, setStories]: [Story[], any] = useState([]) + const [totalLikes, setTotalLikes] = useState(0) + const [totalViews, setTotalViews] = useState(0) + const [totalComments, setTotalComments] = useState(0) + const borderColor = useColorModeValue(userCustomTheme.borderColor.light, userCustomTheme.borderColor.dark) + + const getStories = async () => { + const res = await requestApi.get(`/story/posts/dashboard`) + setStories(res.data) + + let likes = 0 + let views = 0 + let comments = 0 + + res.data.forEach(s => { + likes += s.likes + views += s.views + comments += s.comments + }) + + setTotalLikes(likes) + setTotalViews(views) + setTotalComments(comments) + } + + useEffect(() => { + getStories() + }, []) + + return ( + <> + + + + + + + {totalLikes} + Total likes + + + {totalViews} + Total Views + + + {totalComments} + Total Comments + + + + Stories ({stories.length}) + + { + stories.map((s,i) => + + + + {s.title} + created {moment(s.created).fromNow()}  updated {moment(s.updated).fromNow()} + + + + + + {s.likes} + + + + {s.comments} + + + + {s.views} + + + + + ) + } + + + + + + + ) +} +export default DashboardPage + + diff --git a/server/internal/api/posts.go b/server/internal/api/posts.go index d73f37b3..99c18e99 100644 --- a/server/internal/api/posts.go +++ b/server/internal/api/posts.go @@ -151,6 +151,17 @@ func GetHomePosts(c *gin.Context) { c.JSON(http.StatusOK, common.RespSuccess(posts)) } +func GetDashboardPosts(c *gin.Context) { + user := user.CurrentUser(c) + + posts, err := story.DashboardPosts(user) + if err != nil { + c.JSON(err.Status, common.RespError(err.Message)) + return + } + c.JSON(http.StatusOK, common.RespSuccess(posts)) +} + func GetBookmarkPosts(c *gin.Context) { filter := c.Param("filter") user := user.CurrentUser(c) diff --git a/server/internal/api/story.go b/server/internal/api/story.go index 1753d85f..c8cd41ff 100644 --- a/server/internal/api/story.go +++ b/server/internal/api/story.go @@ -69,6 +69,7 @@ func GetStory(c *gin.Context) { ar.Bookmarked, _ = story.Bookmarked(u.ID, ar.ID) } + story.UpdateViews(id) c.JSON(http.StatusOK, common.RespSuccess(ar)) } diff --git a/server/internal/server.go b/server/internal/server.go index 07cad3f4..f08b1dd3 100644 --- a/server/internal/server.go +++ b/server/internal/server.go @@ -77,6 +77,7 @@ func (s *Server) Start() error { r.GET("/story/posts/org/:id", IsLogin(), api.GetOrgPosts) r.GET("/story/posts/drafts", IsLogin(), api.GetEditorDrafts) r.GET("/story/posts/home", api.GetHomePosts) + r.GET("/story/posts/dashboard", IsLogin(), api.GetDashboardPosts) r.POST("/story", IsLogin(), api.SubmitStory) r.POST("/story/pin/:storyID", IsLogin(), api.PinStory) r.POST("/story/series", api.GetSeries) diff --git a/server/internal/storage/sql_tables.go b/server/internal/storage/sql_tables.go index 53ee54a0..b6bf829d 100644 --- a/server/internal/storage/sql_tables.go +++ b/server/internal/storage/sql_tables.go @@ -82,6 +82,7 @@ var sqlTables = map[string]string{ url VARCHAR(255), cover VARCHAR(255), brief TEXT, + views INTEGER DEFAULT 0, likes INTEGER DEFAULT 0, status tinyint NOT NULL, created DATETIME NOT NULL, diff --git a/server/internal/story/post.go b/server/internal/story/post.go index 44f32e03..0799700d 100644 --- a/server/internal/story/post.go +++ b/server/internal/story/post.go @@ -295,6 +295,10 @@ func GetPostCreator(id string) (string, *e.Error) { return uid, nil } +func UpdateViews(storyID string) { + db.Conn.Exec("UPDATE story SET views=views+1 WHERE id=?", storyID) +} + //slug有三个规则 // 1. 长度不能超过127 // 2. 每次title更新,都要重新生成slug diff --git a/server/internal/story/posts.go b/server/internal/story/posts.go index 1f02f7d3..2cffdae0 100644 --- a/server/internal/story/posts.go +++ b/server/internal/story/posts.go @@ -29,6 +29,26 @@ func HomePosts(user *models.User, filter string, page int64, perPage int64) (mod return posts, nil } +func DashboardPosts(user *models.User) ([]*models.Story, *e.Error) { + rows, err := db.Conn.Query("SELECT id,title,url,created,views,likes,updated FROM story WHERE creator=? AND status=? ORDER BY created DESC", user.ID, models.StatusPublished) + if err != nil && err != sql.ErrNoRows { + logger.Warn("get dashboard posts error", "error", err) + return nil, e.New(http.StatusInternalServerError, e.Internal) + } + + stories := make([]*models.Story, 0) + for rows.Next() { + story := &models.Story{} + rows.Scan(&story.ID, &story.Title, &story.URL, &story.Created, &story.Views, &story.Likes, &story.Updated) + story.Comments = GetCommentCount(story.ID) + stories = append(stories, story) + + story.Creator = &models.UserSimple{Username: user.Username} + } + + return stories, nil +} + func UserPosts(tp string, user *models.User, uid string, page int64, perPage int64) (models.Stories, *e.Error) { var rows *sql.Rows var err error diff --git a/server/internal/user/user.go b/server/internal/user/user.go index 1f693ed1..fbf7a6f6 100644 --- a/server/internal/user/user.go +++ b/server/internal/user/user.go @@ -136,6 +136,12 @@ func UpdateUser(u *models.User) *e.Error { } func NameExist(name string) (bool, *e.Error) { + for _, n := range common.ReserverURLs { + if n == "/"+name { + return true, nil + } + } + var username string err := db.Conn.QueryRow("SELECT username FROM user WHERE username=?", name).Scan(&username) if err != nil && err != sql.ErrNoRows { diff --git a/server/pkg/common/reserve_urls.go b/server/pkg/common/reserve_urls.go index 705e20e7..ea091c0c 100644 --- a/server/pkg/common/reserve_urls.go +++ b/server/pkg/common/reserve_urls.go @@ -4,7 +4,7 @@ package common var ReserverURLs = []string{ "/tags", "/courses", - "/interaction", + "/dashboard", "/editor", "/admin", "/bookmarks", diff --git a/src/components/user-menu.tsx b/src/components/user-menu.tsx index bbd7d848..49ce491d 100644 --- a/src/components/user-menu.tsx +++ b/src/components/user-menu.tsx @@ -14,7 +14,7 @@ import { Session } from "src/types/user" import { useRouter } from "next/router" import storage from "utils/localStorage" import { ReserveUrls } from "src/data/reserve-urls" -import { FaRegSun, FaUserAlt ,FaBookmark, FaSignOutAlt,FaEdit,FaStar, FaHeart} from "react-icons/fa" +import { FaRegSun, FaUserAlt ,FaBookmark, FaSignOutAlt,FaEdit,FaStar, FaHeart, FaThLarge} from "react-icons/fa" import { isAdmin, isEditor } from "utils/role" import { logout } from "utils/session" import Link from "next/link" @@ -57,7 +57,7 @@ export const UserMenu = () => { {isEditor(session.user.role) && } >创作中心} }>书签收藏 - }>我的关注 + }>Dashboard {isAdmin(session.user.role) && } >管理员} }>博客设置 diff --git a/src/data/links.tsx b/src/data/links.tsx index 8ff6b2aa..2611b084 100644 --- a/src/data/links.tsx +++ b/src/data/links.tsx @@ -24,20 +24,25 @@ export const editorLinks: Route[] = [{ } ] -export const interactionLinks: any[] = [ +export const dashboardLinks: any[] = [ + { + title: 'Stats', + path: `${ReserveUrls.Dashboard}/stats`, + disabled: false + }, { title: 'Following tags', - path: `${ReserveUrls.Interaction}/following-tags`, + path: `${ReserveUrls.Dashboard}/following-tags`, disabled: false }, { title: 'Following users', - path: `${ReserveUrls.Interaction}/following-users`, + path: `${ReserveUrls.Dashboard}/following-users`, disabled: false }, { title: 'Followers', - path: `${ReserveUrls.Interaction}/followers`, + path: `${ReserveUrls.Dashboard}/followers`, disabled: false }, ] diff --git a/src/data/reserve-urls.ts b/src/data/reserve-urls.ts index 1b75b83a..3372e4ea 100644 --- a/src/data/reserve-urls.ts +++ b/src/data/reserve-urls.ts @@ -2,7 +2,7 @@ export enum ReserveUrls { Tags = "/tags", Courses = "/courses", - Interaction = "/interaction", + Dashboard = "/dashboard", Editor = "/editor", Admin = "/admin", Bookmarks = "/bookmarks", diff --git a/src/types/story.ts b/src/types/story.ts index a90e6ac4..cf4bb34a 100644 --- a/src/types/story.ts +++ b/src/types/story.ts @@ -22,8 +22,10 @@ export interface Story { cover?: string brief?: string created?: string + updated?:string tags?: string[] rawTags?: Tag[] + views?: number likes? : number liked? : boolean pinned?: boolean