From a7833a50c032a5eb886ad64a2befc97fa1577250 Mon Sep 17 00:00:00 2001 From: sunface Date: Fri, 5 Mar 2021 10:17:05 +0800 Subject: [PATCH] update --- config.yaml | 1 + configs/config.ts | 2 +- layouts/nav/vertical-nav.tsx | 2 +- pages/[username]/[post_id].tsx | 2 +- pages/[username]/index.tsx | 7 ++- pages/admin/tag/[id].tsx | 2 +- pages/admin/tags.tsx | 4 +- pages/bookmarks.tsx | 2 +- pages/editor/post/[id].tsx | 4 +- pages/editor/posts.tsx | 8 ++-- pages/index.tsx | 4 +- pages/login.tsx | 2 +- pages/settings/profile.tsx | 6 +-- pages/tags/index.tsx | 6 +-- server/internal/api/comment.go | 4 +- server/internal/api/posts.go | 4 +- server/internal/api/story.go | 30 +------------ server/internal/api/tags.go | 2 +- server/internal/api/users.go | 2 +- server/internal/{ui_config.go => config.go} | 6 +-- server/internal/server.go | 48 +++++++++------------ server/internal/storage/sql_tables.go | 36 ++++++++-------- server/internal/story/bookmark.go | 4 +- server/internal/story/comment.go | 4 +- server/internal/story/like.go | 10 ++--- server/internal/story/post.go | 16 +++---- server/internal/story/posts.go | 2 +- server/internal/story/story.go | 8 ++-- server/internal/tags/tags.go | 9 ++-- server/internal/user/session.go | 4 +- server/internal/user/users.go | 6 +-- server/pkg/models/comment.go | 2 +- server/pkg/models/id_type.go | 8 ++++ server/pkg/models/post.go | 4 +- server/pkg/models/story.go | 6 --- server/pkg/models/tag.go | 4 +- server/pkg/models/user.go | 20 ++++----- server/pkg/utils/id.go | 4 +- src/components/comments/comment.tsx | 2 +- src/components/comments/reply.tsx | 2 +- src/components/markdown-editor/editor.tsx | 2 +- src/components/posts/bookmark.tsx | 2 +- src/components/posts/simple-post-card.tsx | 3 +- src/components/tags/tags.tsx | 4 +- src/hooks/use-session.ts | 2 +- src/utils/session.ts | 2 +- theme.ts | 1 + 47 files changed, 145 insertions(+), 170 deletions(-) rename server/internal/{ui_config.go => config.go} (93%) create mode 100644 server/pkg/models/id_type.go delete mode 100644 server/pkg/models/story.go diff --git a/config.yaml b/config.yaml index 1099fcbb..60549ecb 100644 --- a/config.yaml +++ b/config.yaml @@ -3,6 +3,7 @@ common: version: 0.1.0 log_level: "info" is_prod: false + app_name: "im.dev" #################################### Server ############################## server: diff --git a/configs/config.ts b/configs/config.ts index bd10d98c..213a90cf 100644 --- a/configs/config.ts +++ b/configs/config.ts @@ -16,7 +16,7 @@ export let config = { } export function initUIConfig() { - requestApi.get("/uiconfig").then((res) => { + requestApi.get("/config").then((res) => { console.log("初始化UI config:", res.data) config = res.data })} \ No newline at end of file diff --git a/layouts/nav/vertical-nav.tsx b/layouts/nav/vertical-nav.tsx index 4cbbd3bc..a540fe28 100644 --- a/layouts/nav/vertical-nav.tsx +++ b/layouts/nav/vertical-nav.tsx @@ -69,7 +69,7 @@ import { getSvgIcon } from "components/svg-icon" {navLinks.map(link => - + {link.icon}{link.title} diff --git a/pages/[username]/[post_id].tsx b/pages/[username]/[post_id].tsx index c8a03ca6..18d050bf 100644 --- a/pages/[username]/[post_id].tsx +++ b/pages/[username]/[post_id].tsx @@ -47,7 +47,7 @@ const PostPage = () => { }, [router]) const getData = async () => { - const res = await requestApi.get(`/post/${id}`) + const res = await requestApi.get(`/story/post/${id}`) setPost(res.data) getComments(res.data.id) diff --git a/pages/[username]/index.tsx b/pages/[username]/index.tsx index f1449e0e..6a78899e 100644 --- a/pages/[username]/index.tsx +++ b/pages/[username]/index.tsx @@ -71,8 +71,11 @@ const UserPage = () => { + {user.about && + <> {user.about} + } {user.location && Location: {user.location} @@ -96,9 +99,9 @@ const UserPage = () => { {user.zhihu && } {user.weibo && } - - + {user.availFor && + I am available for {user.availFor} } diff --git a/pages/admin/tag/[id].tsx b/pages/admin/tag/[id].tsx index 28c0cae2..64850f00 100644 --- a/pages/admin/tag/[id].tsx +++ b/pages/admin/tag/[id].tsx @@ -47,7 +47,7 @@ function PostEditPage() { const publish = async () => { - const res = await requestApi.post(`/admin/tag`, tag) + const res = await requestApi.post(`/tag`, tag) toast({ description: "发布成功", status: "success", diff --git a/pages/admin/tags.tsx b/pages/admin/tags.tsx index 5e496ccd..604a123e 100644 --- a/pages/admin/tags.tsx +++ b/pages/admin/tags.tsx @@ -21,7 +21,7 @@ const PostsPage = () => { const router = useRouter() const toast = useToast() const getTags = () => { - requestApi.get(`/tags`).then((res) => setTags(res.data)).catch(_ => setTags([])) + requestApi.get(`/tag/all`).then((res) => setTags(res.data)).catch(_ => setTags([])) } useEffect(() => { @@ -33,7 +33,7 @@ const PostsPage = () => { } const deleteTag= async (id) => { - await requestApi.delete(`/admin/tag/${id}`) + await requestApi.delete(`/tag/${id}`) getTags() toast({ description: "删除成功", diff --git a/pages/bookmarks.tsx b/pages/bookmarks.tsx index 8f4abcb6..7c3f447f 100644 --- a/pages/bookmarks.tsx +++ b/pages/bookmarks.tsx @@ -43,7 +43,7 @@ import Empty from "components/empty" }, [filter]) const getBookmarkPosts = async() => { - const res = await requestApi.get(`/bookmark/posts`) + const res = await requestApi.get(`/story/bookmark/posts`) setRawPosts(res.data) setPosts(res.data) const ts = [{id:-1,title:'All Tags',icon: 'https://cdn.hashnode.com/res/hashnode/image/upload/v1605105898259/3vuMFM8qM.png?w=200&h=200&fit=crop&crop=entropy&auto=compress&auto=compress'}] diff --git a/pages/editor/post/[id].tsx b/pages/editor/post/[id].tsx index 0e3c0d1d..dd423ba0 100644 --- a/pages/editor/post/[id].tsx +++ b/pages/editor/post/[id].tsx @@ -28,7 +28,7 @@ function PostEditPage() { const toast = useToast() useEffect(() => { if (id && id !== 'new') { - requestApi.get(`/editor/post/${id}`).then(res => setAr(res.data)) + requestApi.get(`/story/post/${id}`).then(res => setAr(res.data)) } }, [id]) @@ -58,7 +58,7 @@ function PostEditPage() { } const publish = async () => { - const res = await requestApi.post(`/editor/post`, ar) + const res = await requestApi.post(`/story/post`, ar) toast({ description: "发布成功", status: "success", diff --git a/pages/editor/posts.tsx b/pages/editor/posts.tsx index bc030a77..1ec9831e 100644 --- a/pages/editor/posts.tsx +++ b/pages/editor/posts.tsx @@ -26,7 +26,7 @@ const PostsPage = () => { const router = useRouter() const toast = useToast() const getPosts = () => { - requestApi.get(`/editor/posts`).then((res) => setPosts(res.data)).catch(_ => setPosts([])) + requestApi.get(`/story/posts/editor`).then((res) => setPosts(res.data)).catch(_ => setPosts([])) } useEffect(() => { @@ -64,7 +64,7 @@ const PostsPage = () => { } const submitPost = async (values, _) => { - await requestApi.post(`/editor/post`, values) + await requestApi.post(`/story/post`, values) onClose() toast({ description: "提交成功", @@ -78,7 +78,7 @@ const PostsPage = () => { const editPost = (post: Post) => { if (post.url.trim() === "") { - router.push(`/editor/post/${post.id}`) + router.push(`/story/post/${post.id}`) } else { setCurrentPost(post) onOpen() @@ -86,7 +86,7 @@ const PostsPage = () => { } const onDeletePost= async (id) => { - await requestApi.delete(`/editor/post/${id}`) + await requestApi.delete(`/storyt/post/${id}`) getPosts() toast({ description: "删除成功", diff --git a/pages/index.tsx b/pages/index.tsx index ffd60fe5..73c9a420 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -24,7 +24,7 @@ const HomePage = () => { const [posts, setPosts] = useState([]) const [filter, setFilter] = useState(PostFilter.Best) const initData = async () => { - const res = await requestApi.get(`/home/posts/${filter}`) + const res = await requestApi.get(`/story/posts/home/${filter}`) setPosts(res.data) } @@ -86,7 +86,7 @@ export const HomeSidebar = () => { const [posts, setPosts] = useState([]) const [filter, setFilter] = useState(PostFilter.Best) const initData = async () => { - const res = await requestApi.get(`/home/posts/${filter}`) + const res = await requestApi.get(`/story/posts/home/${filter}`) setPosts(res.data) } diff --git a/pages/login.tsx b/pages/login.tsx index 5e46ff3a..f4f922b4 100644 --- a/pages/login.tsx +++ b/pages/login.tsx @@ -20,7 +20,7 @@ import { useRouter } from "next/router" const LoginPage = () => { const router = useRouter() const login = async () => { - const res = await requestApi.post("/login") + const res = await requestApi.post("/user/login") saveToken(res.data.token) storage.set('session', res.data) const oldPage = storage.get('current-page') diff --git a/pages/settings/profile.tsx b/pages/settings/profile.tsx index d5a0b34c..77c7ada9 100644 --- a/pages/settings/profile.tsx +++ b/pages/settings/profile.tsx @@ -298,11 +298,11 @@ const UserProfilePage = () => { diff --git a/pages/tags/index.tsx b/pages/tags/index.tsx index 2d1bc701..ae4ffc9d 100644 --- a/pages/tags/index.tsx +++ b/pages/tags/index.tsx @@ -40,7 +40,7 @@ const TagsPage = () => { const [filter, setFilter] = useState(tagsFilter[0]) const [tags, setTags]: [Tag[], any] = useState([]) const getTags = () => { - requestApi.get(`/tags`).then((res) => setTags(res.data)).catch(_ => setTags([])) + requestApi.get(`/tag/all`).then((res) => setTags(res.data)).catch(_ => setTags([])) } useEffect(() => { @@ -81,7 +81,7 @@ const TagsPage = () => { /> { - tagsFilter.map(f => setFilter(f)}> + tagsFilter.map(f => setFilter(f)}> {f.name} ) } @@ -91,7 +91,7 @@ const TagsPage = () => { - {tags.map(t => )} + {tags.map(t => )} diff --git a/server/internal/api/comment.go b/server/internal/api/comment.go index 89861132..d3c27461 100644 --- a/server/internal/api/comment.go +++ b/server/internal/api/comment.go @@ -34,7 +34,7 @@ func SubmitComment(c *gin.Context) { if comment.ID == "" { //add comment user := user.CurrentUser(c) comment.CreatorID = user.ID - comment.ID = utils.GenStoryID(models.StoryComment) + comment.ID = utils.GenID(models.IDTypeComment) err = story.AddComment(comment) } else { // update comment err = story.EditComment(comment) @@ -78,7 +78,7 @@ func GetStoryComments(c *gin.Context) { c.JSON(http.StatusOK, common.RespSuccess(comments)) } -func DeleteComment(c *gin.Context) { +func DeleteStoryComment(c *gin.Context) { id := c.Param("id") //only admin and owner can delete comment comment, err := story.GetComment(id) diff --git a/server/internal/api/posts.go b/server/internal/api/posts.go index ad88c461..f8e12149 100644 --- a/server/internal/api/posts.go +++ b/server/internal/api/posts.go @@ -12,7 +12,7 @@ import ( func GetEditorPosts(c *gin.Context) { user := user.CurrentUser(c) - ars, err := story.UserPosts(user, int64(user.ID)) + ars, err := story.UserPosts(user, user.ID) if err != nil { c.JSON(err.Status, common.RespError(err.Message)) return @@ -22,7 +22,7 @@ func GetEditorPosts(c *gin.Context) { } func GetUserPosts(c *gin.Context) { - userID, _ := strconv.ParseInt(c.Param("userID"), 10, 64) + userID := c.Param("userID") user := user.CurrentUser(c) diff --git a/server/internal/api/story.go b/server/internal/api/story.go index fa68817b..2800a512 100644 --- a/server/internal/api/story.go +++ b/server/internal/api/story.go @@ -47,7 +47,7 @@ func DeletePost(c *gin.Context) { c.JSON(http.StatusOK, common.RespSuccess(nil)) } -func GetPost(c *gin.Context) { +func GetStoryPost(c *gin.Context) { id := c.Param("id") user := user.CurrentUser(c) @@ -95,31 +95,3 @@ func Bookmark(c *gin.Context) { c.JSON(http.StatusOK, common.RespSuccess(nil)) } - -func GetEditorPost(c *gin.Context) { - id := c.Param("id") - if id == "" { - c.JSON(http.StatusBadRequest, common.RespError(e.ParamInvalid)) - return - } - - user := user.CurrentUser(c) - creator, err := story.GetPostCreator(id) - if err != nil { - c.JSON(err.Status, common.RespError(err.Message)) - return - } - - if user.ID != creator { - c.JSON(http.StatusForbidden, common.RespError(e.NoPermission)) - return - } - - ar, err := story.GetPost(id, "") - if err != nil { - c.JSON(err.Status, common.RespError(err.Message)) - return - } - - c.JSON(http.StatusOK, common.RespSuccess(ar)) -} diff --git a/server/internal/api/tags.go b/server/internal/api/tags.go index c872249e..76730ccf 100644 --- a/server/internal/api/tags.go +++ b/server/internal/api/tags.go @@ -14,7 +14,7 @@ import ( func GetTag(c *gin.Context) { name := c.Param("name") - res, err := tags.GetTag(0, name) + res, err := tags.GetTag("", name) if err != nil { c.JSON(err.Status, common.RespError(err.Message)) return diff --git a/server/internal/api/users.go b/server/internal/api/users.go index 953782b6..4417bce8 100644 --- a/server/internal/api/users.go +++ b/server/internal/api/users.go @@ -36,7 +36,7 @@ func GetUserSelf(c *gin.Context) { func GetUser(c *gin.Context) { username := c.Param("username") - userDetail, err := user.GetUserDetail(0, username) + userDetail, err := user.GetUserDetail("", username) if err != nil { c.JSON(err.Status, common.RespError(err.Message)) return diff --git a/server/internal/ui_config.go b/server/internal/config.go similarity index 93% rename from server/internal/ui_config.go rename to server/internal/config.go index 6acf76db..85f324cc 100644 --- a/server/internal/ui_config.go +++ b/server/internal/config.go @@ -8,7 +8,7 @@ import ( "github.com/imdotdev/im.dev/server/pkg/config" ) -type UIConfig struct { +type Config struct { AppName string `json:"appName"` CommonMaxLen int `json:"commonMaxlen"` Posts *PostsConfig `json:"posts"` @@ -28,8 +28,8 @@ type UserConfig struct { } // 在后台页面配置,存储到mysql中 -func GetUIConfig(c *gin.Context) { - conf := &UIConfig{ +func GetConfig(c *gin.Context) { + conf := &Config{ AppName: config.Data.Common.AppName, CommonMaxLen: 255, Posts: &PostsConfig{ diff --git a/server/internal/server.go b/server/internal/server.go index 16a2d653..fc5f3cbd 100644 --- a/server/internal/server.go +++ b/server/internal/server.go @@ -43,45 +43,39 @@ func (s *Server) Start() error { router.Use(Cors()) r := router.Group("/api") - { - r.POST("/login", user.Login) - r.POST("/logout", user.Logout) - r.GET("/uiconfig", GetUIConfig) - - } - - r.GET("/post/:id", api.GetPost) + //story apis + r.GET("/story/post/:id", api.GetStoryPost) r.POST("/story/like/:id", IsLogin(), api.LikeStory) r.GET("/story/comments/:id", api.GetStoryComments) r.POST("/story/comment", IsLogin(), api.SubmitComment) - - r.DELETE("/comment/:id", IsLogin(), api.DeleteComment) - - r.GET("/editor/posts", IsLogin(), api.GetEditorPosts) - r.POST("/editor/post", IsLogin(), api.SubmitPost) - r.DELETE("/editor/post/:id", IsLogin(), api.DeletePost) - r.GET("/editor/post/:id", IsLogin(), api.GetEditorPost) - - r.POST("/admin/tag", IsLogin(), api.SubmitTag) - r.DELETE("/admin/tag/:id", IsLogin(), api.DeleteTag) - - r.GET("/tags", api.GetTags) + r.DELETE("/story/comment/:id", IsLogin(), api.DeleteStoryComment) + r.GET("/story/posts/editor", IsLogin(), api.GetEditorPosts) + r.GET("/story/posts/home/:filter", api.GetHomePosts) + r.POST("/story/post", IsLogin(), api.SubmitPost) + r.DELETE("/story/post/:id", IsLogin(), api.DeletePost) + r.POST("/story/bookmark/:storyID", IsLogin(), api.Bookmark) + r.GET("/story/bookmark/posts", IsLogin(), api.GetBookmarkPosts) + + // tag apis + r.POST("/tag", IsLogin(), api.SubmitTag) + r.DELETE("/tag/:id", IsLogin(), api.DeleteTag) + r.GET("/tag/all", api.GetTags) r.GET("/tag/posts/:id", api.GetTagPosts) r.GET("/tag/info/:name", api.GetTag) - r.GET("/users", api.GetUsers) + // user apis + r.GET("/user/all", api.GetUsers) r.GET("/user/self", IsLogin(), api.GetUserSelf) r.GET("/user/info/:username", api.GetUser) r.POST("/user/update", IsLogin(), api.UpdateUser) r.GET("/user/posts/:userID", api.GetUserPosts) + r.GET("/user/session", IsLogin(), api.GetSession) + r.POST("/user/login", user.Login) + r.POST("/user/logout", user.Logout) - r.GET("/home/posts/:filter", api.GetHomePosts) - - r.GET("/session", IsLogin(), api.GetSession) - - r.POST("/bookmark/:storyID", IsLogin(), api.Bookmark) - r.GET("/bookmark/posts", IsLogin(), api.GetBookmarkPosts) + // other apis + r.GET("/config", GetConfig) err := router.Run(config.Data.Server.Addr) if err != nil { diff --git a/server/internal/storage/sql_tables.go b/server/internal/storage/sql_tables.go index 27241a82..1b669d90 100644 --- a/server/internal/storage/sql_tables.go +++ b/server/internal/storage/sql_tables.go @@ -2,7 +2,7 @@ package storage var sqlTables = map[string]string{ "user": `CREATE TABLE IF NOT EXISTS user ( - id INTEGER PRIMARY KEY AUTOINCREMENT, + id VARCHAR(255) PRIMARY KEY, username VARCHAR(255) NOT NULL UNIQUE, nickname VARCHAR(255) DEFAULT '', avatar VARCHAR(255) DEFAULT '', @@ -23,7 +23,7 @@ var sqlTables = map[string]string{ ON user (email);`, "user_profile": `CREATE TABLE IF NOT EXISTS user_profile ( - id INTEGER PRIMARY KEY, + id VARCHAR(255) PRIMARY KEY, tagline VARCHAR(255), cover VARCHAR(255), @@ -43,7 +43,7 @@ var sqlTables = map[string]string{ );`, "user_skills": `CREATE TABLE IF NOT EXISTS user_skills ( - user_id INTEGER, + user_id VARCHAR(255), skill_id INTEGER ); CREATE INDEX IF NOT EXISTS user_skills_userid @@ -54,13 +54,13 @@ var sqlTables = map[string]string{ "sessions": `CREATE TABLE IF NOT EXISTS sessions ( sid VARCHAR(255) primary key, - user_id INTEGER + user_id VARCHAR(255) ); `, "posts": `CREATE TABLE IF NOT EXISTS posts ( id VARCHAR(255) PRIMARY KEY, - creator INTEGER NOT NULL, + creator VARCHAR(255) NOT NULL, slug VARCHAR(64) NOT NULL, title VARCHAR(255) NOT NULL, md TEXT, @@ -82,21 +82,21 @@ var sqlTables = map[string]string{ ON posts (creator, slug); `, - "like": `CREATE TABLE IF NOT EXISTS like ( - id VARCHAR(255), - user_id INTEGER, + "likes": `CREATE TABLE IF NOT EXISTS likes ( + user_id VARCHAR(255), + story_id VARCHAR(255), created DATETIME NOT NULL ); - CREATE INDEX IF NOT EXISTS like_id - ON like (id); - CREATE INDEX IF NOT EXISTS like_userid - ON like (user_id); + CREATE INDEX IF NOT EXISTS likes_userid + ON likes (user_id); + CREATE INDEX IF NOT EXISTS likes_storyid + ON likes (story_id); `, "tags": `CREATE TABLE IF NOT EXISTS tags ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - creator INTEGER NOT NULL, - title VARCHAR(255) NOT NULL, + id VARCHAR(255) PRIMARY KEY, + creator VARCHAR(255) NOT NULL, + title VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, icon VARCHAR(255), cover VARCHAR(255), @@ -112,7 +112,7 @@ var sqlTables = map[string]string{ `, "tag_post": `CREATE TABLE IF NOT EXISTS tag_post ( - tag_id INTEGER, + tag_id VARCHAR(255), post_id VARCHAR(255) ); CREATE INDEX IF NOT EXISTS tag_post_tagid @@ -124,7 +124,7 @@ var sqlTables = map[string]string{ "comments": `CREATE TABLE IF NOT EXISTS comments ( id VARCHAR(255) PRIMARY KEY, target_id VARCHAR(255), - creator INTEGER, + creator VARCHAR(255), MD TEXT, likes INTEGER DEFAULT 0, created DATETIME NOT NULL, @@ -143,7 +143,7 @@ var sqlTables = map[string]string{ `, "bookmarks": `CREATE TABLE IF NOT EXISTS bookmarks ( - user_id INTEGER, + user_id VARCHAR(255), story_id VARCHAR(255), created DATETIME ); diff --git a/server/internal/story/bookmark.go b/server/internal/story/bookmark.go index 55d482fd..67ef29ca 100644 --- a/server/internal/story/bookmark.go +++ b/server/internal/story/bookmark.go @@ -8,7 +8,7 @@ import ( "github.com/imdotdev/im.dev/server/pkg/e" ) -func Bookmark(userID int64, storyID string) *e.Error { +func Bookmark(userID string, storyID string) *e.Error { storyExist := Exist(storyID) if !storyExist { return e.New(http.StatusNotFound, e.NotFound) @@ -36,7 +36,7 @@ func Bookmark(userID int64, storyID string) *e.Error { return nil } -func Bookmarked(userID int64, storyID string) (bool, error) { +func Bookmarked(userID string, storyID string) (bool, error) { var nid string err := db.Conn.QueryRow("select story_id from bookmarks where user_id=? and story_id=?", userID, storyID).Scan(&nid) if err != nil && err != sql.ErrNoRows { diff --git a/server/internal/story/comment.go b/server/internal/story/comment.go index b3319b7d..76fa9ffa 100644 --- a/server/internal/story/comment.go +++ b/server/internal/story/comment.go @@ -195,9 +195,9 @@ func GetStoryIDByCommentID(cid string) (string, bool, error) { } switch targetID[:1] { - case models.StoryPost: + case models.IDTypePost: return targetID, true, nil - case models.StoryComment: + case models.IDTypeComment: var nid string err := db.Conn.QueryRow("select target_id from comments where id=?", targetID).Scan(&nid) if err != nil { diff --git a/server/internal/story/like.go b/server/internal/story/like.go index 8106114d..b88768a3 100644 --- a/server/internal/story/like.go +++ b/server/internal/story/like.go @@ -10,7 +10,7 @@ import ( "github.com/imdotdev/im.dev/server/pkg/e" ) -func Like(storyID string, userId int64) *e.Error { +func Like(storyID string, userId string) *e.Error { exist := Exist(storyID) if !exist { return e.New(http.StatusNotFound, e.NotFound) @@ -22,14 +22,14 @@ func Like(storyID string, userId int64) *e.Error { if liked { // 已经喜欢过该篇文章,更改为不喜欢 - _, err := db.Conn.Exec("DELETE FROM like WHERE id=? and user_id=?", storyID, userId) + _, err := db.Conn.Exec("DELETE FROM likes WHERE story_id=? and user_id=?", storyID, userId) if err != nil { return e.New(http.StatusInternalServerError, e.Internal) } db.Conn.Exec(fmt.Sprintf("UPDATE %s SET likes=likes-1 WHERE id=?", tbl), storyID) } else { - _, err := db.Conn.Exec("INSERT INTO like (id,user_id,created) VALUES (?,?,?)", storyID, userId, time.Now()) + _, err := db.Conn.Exec("INSERT INTO likes (story_id,user_id,created) VALUES (?,?,?)", storyID, userId, time.Now()) if err != nil { logger.Warn("add like error", "error", err) return e.New(http.StatusInternalServerError, e.Internal) @@ -40,10 +40,10 @@ func Like(storyID string, userId int64) *e.Error { return nil } -func GetLiked(storyID string, userID int64) bool { +func GetLiked(storyID string, userID string) bool { liked := false var nid string - err := db.Conn.QueryRow("SELECT id FROM like WHERE id=? and user_id=?", storyID, userID).Scan(&nid) + err := db.Conn.QueryRow("SELECT story_id FROM likes WHERE story_id=? and user_id=?", storyID, userID).Scan(&nid) if err != nil && err != sql.ErrNoRows { logger.Warn("query story like error", "error", err) return false diff --git a/server/internal/story/post.go b/server/internal/story/post.go index c7081284..02dd745f 100644 --- a/server/internal/story/post.go +++ b/server/internal/story/post.go @@ -70,7 +70,7 @@ func SubmitPost(c *gin.Context) (map[string]string, *e.Error) { setSlug(user.ID, post) if post.ID == "" { - post.ID = utils.GenStoryID(models.StoryPost) + post.ID = utils.GenID(models.IDTypePost) //create _, err := db.Conn.Exec("INSERT INTO posts (id,creator,slug, title, md, url, cover, brief,status, created, updated) VALUES(?,?,?,?,?,?,?,?,?,?,?)", post.ID, user.ID, post.Slug, post.Title, md, post.URL, post.Cover, post.Brief, models.StatusPublished, now, now) @@ -148,7 +148,7 @@ func GetPost(id string, slug string) (*models.Post, *e.Error) { err = ar.Creator.Query() // get tags - t := make([]int64, 0) + t := make([]string, 0) rows, err := db.Conn.Query("SELECT tag_id FROM tag_post WHERE post_id=?", ar.ID) if err != nil && err != sql.ErrNoRows { return nil, e.New(http.StatusInternalServerError, e.Internal) @@ -156,7 +156,7 @@ func GetPost(id string, slug string) (*models.Post, *e.Error) { ar.RawTags = make([]*models.Tag, 0) for rows.Next() { - var tag int64 + var tag string err = rows.Scan(&tag) t = append(t, tag) @@ -177,15 +177,15 @@ func GetPost(id string, slug string) (*models.Post, *e.Error) { return ar, nil } -func GetPostCreator(id string) (int64, *e.Error) { - var uid int64 +func GetPostCreator(id string) (string, *e.Error) { + var uid string err := db.Conn.QueryRow("SELECT creator FROM posts WHERE id=?", id).Scan(&uid) if err != nil { if err == sql.ErrNoRows { - return 0, e.New(http.StatusNotFound, e.NotFound) + return "", e.New(http.StatusNotFound, e.NotFound) } logger.Warn("get post creator error", "error", err) - return 0, e.New(http.StatusInternalServerError, e.Internal) + return "", e.New(http.StatusInternalServerError, e.Internal) } return uid, nil @@ -210,7 +210,7 @@ func postExist(id string) bool { // 1. 长度不能超过127 // 2. 每次title更新,都要重新生成slug // 3. 单个用户下的slug不能重复,如果已经存在,需要加上-1这种字符 -func setSlug(creator int64, post *models.Post) error { +func setSlug(creator string, post *models.Post) error { slug := utils.Slugify(post.Title) if len(slug) > 100 { slug = slug[:100] diff --git a/server/internal/story/posts.go b/server/internal/story/posts.go index 02087e61..981e1e5f 100644 --- a/server/internal/story/posts.go +++ b/server/internal/story/posts.go @@ -27,7 +27,7 @@ func HomePosts(user *models.User, filter string) (models.Posts, *e.Error) { return posts, nil } -func UserPosts(user *models.User, uid int64) (models.Posts, *e.Error) { +func UserPosts(user *models.User, uid string) (models.Posts, *e.Error) { rows, err := db.Conn.Query("select id,slug,title,url,cover,brief,likes,views,creator,created,updated from posts where creator=?", uid) if err != nil && err != sql.ErrNoRows { logger.Warn("get user posts error", "error", err) diff --git a/server/internal/story/story.go b/server/internal/story/story.go index 32c9e6eb..f94e3107 100644 --- a/server/internal/story/story.go +++ b/server/internal/story/story.go @@ -9,9 +9,9 @@ var logger = log.RootLogger.New("logger", "story") func Exist(id string) bool { switch id[:1] { - case models.StoryPost: + case models.IDTypePost: return postExist(id) - case models.StoryComment: + case models.IDTypeComment: return commentExist(id) default: return false @@ -20,9 +20,9 @@ func Exist(id string) bool { func getStorySqlTable(id string) string { switch id[:1] { - case models.StoryPost: + case models.IDTypePost: return "posts" - case models.StoryComment: + case models.IDTypeComment: return "comments" default: return "unknown" diff --git a/server/internal/tags/tags.go b/server/internal/tags/tags.go index beb5658e..9ad47331 100644 --- a/server/internal/tags/tags.go +++ b/server/internal/tags/tags.go @@ -42,10 +42,11 @@ func SubmitTag(tag *models.Tag) *e.Error { md := utils.Compress(tag.Md) - if tag.ID == 0 { + if tag.ID == "" { + tag.ID = utils.GenID(models.IDTypeTag) //create - _, err := db.Conn.Exec("INSERT INTO tags (creator,name, title, md, icon, cover, created, updated) VALUES(?,?,?,?,?,?,?,?)", - tag.Creator, tag.Name, tag.Title, md, tag.Icon, tag.Cover, now, now) + _, err := db.Conn.Exec("INSERT INTO tags (id,creator,name, title, md, icon, cover, created, updated) VALUES(?,?,?,?,?,?,?,?,?)", + tag.ID, tag.Creator, tag.Name, tag.Title, md, tag.Icon, tag.Cover, now, now) if err != nil { if e.IsErrUniqueConstraint(err) { return e.New(http.StatusConflict, "同样的Tag name已存在") @@ -111,7 +112,7 @@ func DeleteTag(id int64) *e.Error { return nil } -func GetTag(id int64, name string) (*models.Tag, *e.Error) { +func GetTag(id string, name string) (*models.Tag, *e.Error) { tag := &models.Tag{} var rawmd []byte err := db.Conn.QueryRow("SELECT id,creator,title,name,icon,cover,created,updated,md from tags where id=? or name=?", id, name).Scan( diff --git a/server/internal/user/session.go b/server/internal/user/session.go index d7f6d0cb..616ffc9b 100644 --- a/server/internal/user/session.go +++ b/server/internal/user/session.go @@ -24,7 +24,7 @@ type Session struct { func Login(c *gin.Context) { user := &models.User{} - err := user.Query(0, config.Data.User.SuperAdminUsername, "") + err := user.Query("", config.Data.User.SuperAdminUsername, "") if err != nil { if err == sql.ErrNoRows { c.String(http.StatusNotFound, "") @@ -132,7 +132,7 @@ func GetSession(c *gin.Context) *Session { } func loadSession(sid string) *Session { - var userid int64 + var userid string q := `SELECT user_id FROM sessions WHERE sid=?` err := db.Conn.QueryRow(q, sid).Scan(&userid) if err != nil { diff --git a/server/internal/user/users.go b/server/internal/user/users.go index 5ba04c06..5941e0fe 100644 --- a/server/internal/user/users.go +++ b/server/internal/user/users.go @@ -32,7 +32,7 @@ func GetUsers(q string) ([]*models.User, *e.Error) { return users, nil } -func GetUserDetail(id int64, username string) (*models.User, *e.Error) { +func GetUserDetail(id string, username string) (*models.User, *e.Error) { user := &models.User{} err := user.Query(id, username, "") if err != nil { @@ -54,14 +54,14 @@ func GetUserDetail(id int64, username string) (*models.User, *e.Error) { } // get user skills - user.Skills = make([]int64, 0) + user.Skills = make([]string, 0) user.RawSkills = make([]*models.Tag, 0) rows, err := db.Conn.Query("SELECT skill_id from user_skills WHERE user_id=?", user.ID) if err != nil && err != sql.ErrNoRows { logger.Warn("query user skills error", "error", err) } for rows.Next() { - var skill int64 + var skill string rows.Scan(&skill) user.Skills = append(user.Skills, skill) diff --git a/server/pkg/models/comment.go b/server/pkg/models/comment.go index 4ea66bd8..623b858b 100644 --- a/server/pkg/models/comment.go +++ b/server/pkg/models/comment.go @@ -5,7 +5,7 @@ import "time" type Comment struct { ID string `json:"id"` TargetID string `json:"targetID"` // 被评论的文章、书籍等ID - CreatorID int64 `json:"creatorID"` + CreatorID string `json:"creatorID"` Creator *UserSimple `json:"creator"` Md string `json:"md"` Likes int `json:"likes"` diff --git a/server/pkg/models/id_type.go b/server/pkg/models/id_type.go new file mode 100644 index 00000000..cdbfb994 --- /dev/null +++ b/server/pkg/models/id_type.go @@ -0,0 +1,8 @@ +package models + +const ( + IDTypePost = "1" + IDTypeComment = "2" + IDTypeUser = "3" + IDTypeTag = "4" +) diff --git a/server/pkg/models/post.go b/server/pkg/models/post.go index 88e8bb5a..98530e9a 100644 --- a/server/pkg/models/post.go +++ b/server/pkg/models/post.go @@ -11,14 +11,14 @@ const ( type Post struct { ID string `json:"id"` Creator *UserSimple `json:"creator"` - CreatorID int64 `json:"creatorId"` + CreatorID string `json:"creatorId"` Title string `json:"title"` Slug string `json:"slug"` Md string `json:"md"` URL string `json:"url"` Cover string `json:"cover"` Brief string `json:"brief"` - Tags []int64 `json:"tags"` + Tags []string `json:"tags"` RawTags []*Tag `json:"rawTags"` Likes int `json:"likes"` Liked bool `json:"liked"` diff --git a/server/pkg/models/story.go b/server/pkg/models/story.go deleted file mode 100644 index 1556693b..00000000 --- a/server/pkg/models/story.go +++ /dev/null @@ -1,6 +0,0 @@ -package models - -const ( - StoryPost = "1" - StoryComment = "2" -) diff --git a/server/pkg/models/tag.go b/server/pkg/models/tag.go index dbd392d5..6ef82c67 100644 --- a/server/pkg/models/tag.go +++ b/server/pkg/models/tag.go @@ -3,8 +3,8 @@ package models import "time" type Tag struct { - ID int64 `json:"id"` - Creator int64 `json:"creator,omitempty"` + ID string `json:"id"` + Creator string `json:"creator,omitempty"` Title string `json:"title"` Name string `json:"name,omitempty"` Md string `json:"md,omitempty"` diff --git a/server/pkg/models/user.go b/server/pkg/models/user.go index 04cfe82e..a578e12c 100644 --- a/server/pkg/models/user.go +++ b/server/pkg/models/user.go @@ -7,20 +7,20 @@ import ( ) type User struct { - ID int64 `json:"id"` + ID string `json:"id"` Username string `json:"username"` Nickname string `json:"nickname"` Avatar string `json:"avatar"` Email string `json:"email"` Role RoleType `json:"role"` - Tagline string `json:"tagline"` - Cover string `json:"cover"` - Location string `json:"location"` - AvailFor string `json:"availFor"` - About string `json:"about"` - RawSkills []*Tag `json:"rawSkills"` - Skills []int64 `json:"skills"` + Tagline string `json:"tagline"` + Cover string `json:"cover"` + Location string `json:"location"` + AvailFor string `json:"availFor"` + About string `json:"about"` + RawSkills []*Tag `json:"rawSkills"` + Skills []string `json:"skills"` Website string `json:"website"` Twitter string `json:"twitter"` @@ -34,7 +34,7 @@ type User struct { Created time.Time `json:"created"` } -func (user *User) Query(id int64, username string, email string) error { +func (user *User) Query(id string, username string, email string) error { err := db.Conn.QueryRow(`SELECT id,username,role,nickname,email,avatar,last_seen_at,created FROM user WHERE id=? or username=? or email=?`, id, username, email).Scan(&user.ID, &user.Username, &user.Role, &user.Nickname, &user.Email, &user.Avatar, &user.LastSeenAt, &user.Created) @@ -46,7 +46,7 @@ func (user *User) Query(id int64, username string, email string) error { } type UserSimple struct { - ID int64 `json:"id"` + ID string `json:"id"` Username string `json:"username"` Nickname string `json:"nickname"` Avatar string `json:"avatar"` diff --git a/server/pkg/utils/id.go b/server/pkg/utils/id.go index 6557f6a7..ecbd3b66 100644 --- a/server/pkg/utils/id.go +++ b/server/pkg/utils/id.go @@ -2,7 +2,7 @@ package utils import "github.com/lithammer/shortuuid/v3" -func GenStoryID(storyType string) string { +func GenID(idType string) string { u := shortuuid.New() - return storyType + u + return idType + u } diff --git a/src/components/comments/comment.tsx b/src/components/comments/comment.tsx index 9efcb953..cc5c64f3 100644 --- a/src/components/comments/comment.tsx +++ b/src/components/comments/comment.tsx @@ -36,7 +36,7 @@ export const CommentCard = (props: Props) => { } const deleteComment = async id => { - await requestApi.delete(`/comment/${id}`) + await requestApi.delete(`/story/comment/${id}`) onChange() } diff --git a/src/components/comments/reply.tsx b/src/components/comments/reply.tsx index 7fba8e9f..9ad32740 100644 --- a/src/components/comments/reply.tsx +++ b/src/components/comments/reply.tsx @@ -37,7 +37,7 @@ export const Reply = (props: Props) => { } const deleteReply = async id => { - await requestApi.delete(`/comment/${id}`) + await requestApi.delete(`/story/comment/${id}`) onChange() } diff --git a/src/components/markdown-editor/editor.tsx b/src/components/markdown-editor/editor.tsx index feac5c5c..e9d19f44 100644 --- a/src/components/markdown-editor/editor.tsx +++ b/src/components/markdown-editor/editor.tsx @@ -42,7 +42,7 @@ export function MarkdownEditor(props: Props) { useEffect(() => { if (at !== '') { - requestApi.get(`/users?query=${at.trim()}`).then(res => setAtUsers(res.data)) + requestApi.get(`/user/all?query=${at.trim()}`).then(res => setAtUsers(res.data)) } },[at]) diff --git a/src/components/posts/bookmark.tsx b/src/components/posts/bookmark.tsx index 96c22020..7d5ab199 100644 --- a/src/components/posts/bookmark.tsx +++ b/src/components/posts/bookmark.tsx @@ -15,7 +15,7 @@ const Bookmark = (props: Props) => { const [bookmarked,setBookmarked] = useState(props.bookmarked) const bookmark = async () => { - await requestApi.post(`/bookmark/${storyID}`) + await requestApi.post(`/story/bookmark/${storyID}`) setBookmarked(!bookmarked) } diff --git a/src/components/posts/simple-post-card.tsx b/src/components/posts/simple-post-card.tsx index 241a1adb..86db0cba 100644 --- a/src/components/posts/simple-post-card.tsx +++ b/src/components/posts/simple-post-card.tsx @@ -6,6 +6,7 @@ import Link from "next/link" import UnicornLike from "./like" import { FaHeart, FaRegBookmark, FaRegComment, FaRegHeart } from "react-icons/fa" import SvgButton from "components/svg-button" +import Bookmark from "./bookmark" interface Props { post: Post @@ -40,7 +41,7 @@ export const SimplePostCard = (props: Props) => { - + ) diff --git a/src/components/tags/tags.tsx b/src/components/tags/tags.tsx index 30a264da..5bc905f6 100644 --- a/src/components/tags/tags.tsx +++ b/src/components/tags/tags.tsx @@ -18,7 +18,7 @@ export const Tags = (props: Props) => { const [tags, setTags]: [Tag[], any] = useState([]) useEffect(() => { - requestApi.get('/tags').then(res => { + requestApi.get('/tag/all').then(res => { setOptions(res.data) const t = [] props.tags?.forEach(id => { @@ -60,7 +60,7 @@ export const Tags = (props: Props) => { {tags.length > 0 && { tags.map(tag => - + {tag.title} removeTag(tag)} /> ) diff --git a/src/hooks/use-session.ts b/src/hooks/use-session.ts index d7532b69..44cea46a 100644 --- a/src/hooks/use-session.ts +++ b/src/hooks/use-session.ts @@ -11,7 +11,7 @@ function useSession(): Session{ if (sess) { setSession(sess) // 页面重新进入时,跟服务器端进行信息同步 - requestApi.get(`/session`).then(res => { + requestApi.get(`/user/session`).then(res => { setSession(res.data) }) } diff --git a/src/utils/session.ts b/src/utils/session.ts index 9e8132e3..66e6662a 100644 --- a/src/utils/session.ts +++ b/src/utils/session.ts @@ -3,7 +3,7 @@ import { requestApi } from "./axios/request" import events from "./events" export const logout = async () => { - await requestApi.post("/logout") + await requestApi.post("/user/logout") removeToken() events.emit('set-session', null) } diff --git a/theme.ts b/theme.ts index 5569de20..7e13a505 100644 --- a/theme.ts +++ b/theme.ts @@ -44,6 +44,7 @@ const customTheme = extendTheme({ }, body: { background: mode("white","gray.800" )(props), + minHeight: '100vh', color: mode("gray.700", "whiteAlpha.900")(props), ".deleted": { color: "#ff8383 !important",