From 6a290f0ba0caa453674ad89adb88129fdda26b12 Mon Sep 17 00:00:00 2001 From: sunface Date: Fri, 26 Mar 2021 14:47:54 +0800 Subject: [PATCH] update --- pages/[username]/index.tsx | 2 +- server/internal/api/posts.go | 20 ++++++++++++--- server/internal/api/tag.go | 11 ++++++++ server/internal/storage/sql_tables.go | 5 ++++ server/internal/story/post.go | 2 +- server/internal/story/posts.go | 37 ++++++++++++++++++++++++--- server/internal/tags/tags.go | 12 ++++++--- server/internal/user/user.go | 2 +- src/components/story/stories.tsx | 12 +++++++++ 9 files changed, 91 insertions(+), 12 deletions(-) diff --git a/pages/[username]/index.tsx b/pages/[username]/index.tsx index 42b5961f..9c716117 100644 --- a/pages/[username]/index.tsx +++ b/pages/[username]/index.tsx @@ -185,7 +185,7 @@ const UserPage = () => { } - Joined: + {user.type === IDType.User ? "Joined" : "Created"}: {moment(user.created).fromNow()} diff --git a/server/internal/api/posts.go b/server/internal/api/posts.go index 93562114..d73f37b3 100644 --- a/server/internal/api/posts.go +++ b/server/internal/api/posts.go @@ -31,21 +31,35 @@ func GetEditorPosts(c *gin.Context) { } func GetOrgPosts(c *gin.Context) { - orgID := c.Param("id") tp := c.Query("type") if tp != models.IDTypeUndefined && !models.ValidStoryIDType(tp) { c.JSON(http.StatusBadRequest, common.RespError(e.ParamInvalid)) return } + filter := c.Query("filter") + page, _ := strconv.ParseInt(c.Query("page"), 10, 64) + perPage, _ := strconv.ParseInt(c.Query("per_page"), 10, 64) + + orgID := c.Param("id") + user := user.CurrentUser(c) - ars, err := story.OrgPosts(tp, user, orgID) + + var posts []*models.Story + var err *e.Error + + if filter == "" { + posts, err = story.OrgPosts(tp, user, orgID, page, perPage) + } else { + posts, err = story.OrgTagPosts(user, filter, orgID, page, perPage) + } + if err != nil { c.JSON(err.Status, common.RespError(err.Message)) return } - c.JSON(http.StatusOK, common.RespSuccess(ars)) + c.JSON(http.StatusOK, common.RespSuccess(posts)) } func GetEditorDrafts(c *gin.Context) { diff --git a/server/internal/api/tag.go b/server/internal/api/tag.go index 997f2d73..69007e72 100644 --- a/server/internal/api/tag.go +++ b/server/internal/api/tag.go @@ -105,3 +105,14 @@ func GetUserTags(c *gin.Context) { c.JSON(http.StatusOK, common.RespSuccess(res)) } + +func GetOrgTags(c *gin.Context) { + userID := c.Param("userID") + res, err := tags.GetUserTags(userID) + if err != nil { + c.JSON(err.Status, common.RespError(err.Message)) + return + } + + c.JSON(http.StatusOK, common.RespSuccess(res)) +} diff --git a/server/internal/storage/sql_tables.go b/server/internal/storage/sql_tables.go index b61cf10b..a278a065 100644 --- a/server/internal/storage/sql_tables.go +++ b/server/internal/storage/sql_tables.go @@ -156,12 +156,17 @@ var sqlTables = map[string]string{ target_type VARCHAR(1), target_id VARCHAR(255), target_creator VARCHAR(255), + target_owner VARCHAR(255), target_created DATETIME ); CREATE INDEX IF NOT EXISTS tags_using_tagid ON tags_using (tag_id); CREATE INDEX IF NOT EXISTS tags_using_targetid ON tags_using (target_id); + CREATE INDEX IF NOT EXISTS tags_using_creator + ON tags_using (target_creator); + CREATE INDEX IF NOT EXISTS tags_using_owner + ON tags_using (target_owner); CREATE INDEX IF NOT EXISTS tags_using_idtype ON tags_using (tag_id,target_type); `, diff --git a/server/internal/story/post.go b/server/internal/story/post.go index e050ebbb..70f70952 100644 --- a/server/internal/story/post.go +++ b/server/internal/story/post.go @@ -133,7 +133,7 @@ func SubmitStory(c *gin.Context) (map[string]string, *e.Error) { //update tags top.RemoveTagTop(post.ID) - err = tags.UpdateTargetTags(user.ID, post.ID, post.Tags, post.Created) + err = tags.UpdateTargetTags(user.ID, post.ID, post.Tags, post.Created, post.OwnerID) if err != nil { logger.Warn("upate tags error", "error", err) return nil, e.New(http.StatusInternalServerError, e.Internal) diff --git a/server/internal/story/posts.go b/server/internal/story/posts.go index 735aa685..1f02f7d3 100644 --- a/server/internal/story/posts.go +++ b/server/internal/story/posts.go @@ -93,13 +93,22 @@ func UserTagPosts(user *models.User, tid string, uid string, page int64, perPage return posts, nil } -func OrgPosts(tp string, user *models.User, orgID string) (models.Stories, *e.Error) { +func OrgPosts(tp string, user *models.User, orgID string, page int64, perPage int64) (models.Stories, *e.Error) { var rows *sql.Rows var err error + if tp == models.IDTypeUndefined { - rows, err = db.Conn.Query(PostQueryPrefix+"where owner=? and status=?", orgID, models.StatusPublished) + if perPage == 0 { + rows, err = db.Conn.Query(PostQueryPrefix+"where owner=? and status=?", orgID, models.StatusPublished) + } else { + rows, err = db.Conn.Query(PostQueryPrefix+"where owner=? and status=? ORDER BY created DESC LIMIT ?,?", orgID, models.StatusPublished, (page-1)*perPage, perPage) + } } else { - rows, err = db.Conn.Query(PostQueryPrefix+"where owner=? and type=? and status=?", orgID, tp, models.StatusPublished) + if perPage == 0 { + rows, err = db.Conn.Query(PostQueryPrefix+"where owner=? and type=? and status=?", orgID, tp, models.StatusPublished) + } else { + rows, err = db.Conn.Query(PostQueryPrefix+"where owner=? and type=? and status=? ORDER BY created DESC LIMIT ?,? ", orgID, tp, models.StatusPublished, (page-1)*perPage, perPage) + } } if err != nil && err != sql.ErrNoRows { @@ -127,6 +136,28 @@ func OrgPosts(tp string, user *models.User, orgID string) (models.Stories, *e.Er return newPosts, nil } +func OrgTagPosts(user *models.User, tid string, orgID string, page int64, perPage int64) (models.Stories, *e.Error) { + ids := make([]string, 0) + rows, err := db.Conn.Query("SELECT target_id FROM tags_using WHERE tag_id=? and target_owner=? ORDER BY target_created DESC LIMIT ?,?", tid, orgID, (page-1)*perPage, perPage) + if err != nil { + logger.Warn("get user posts error", "error", err) + return nil, e.New(http.StatusInternalServerError, e.Internal) + } + + for rows.Next() { + var id string + rows.Scan(&id) + ids = append(ids, id) + } + + posts, err1 := GetPostsByIDs(user, ids) + if err1 != nil { + return nil, err1 + } + + return posts, nil +} + func UserDrafts(user *models.User, uid string) (models.Stories, *e.Error) { rows, err := db.Conn.Query(PostQueryPrefix+"where creator=? and status=?", uid, models.StatusDraft) if err != nil && err != sql.ErrNoRows { diff --git a/server/internal/tags/tags.go b/server/internal/tags/tags.go index 3a384187..a3d0dcaa 100644 --- a/server/internal/tags/tags.go +++ b/server/internal/tags/tags.go @@ -117,14 +117,14 @@ func GetTag(id string, name string) (*models.Tag, *e.Error) { return tag, nil } -func UpdateTargetTags(targetCreator string, targetID string, tags []string, targetCreated time.Time) error { +func UpdateTargetTags(targetCreator string, targetID string, tags []string, targetCreated time.Time, targetOwner string) error { _, err := db.Conn.Exec("DELETE FROM tags_using WHERE target_id=?", targetID) if err != nil { return err } for _, tag := range tags { - _, err = db.Conn.Exec("INSERT INTO tags_using (tag_id,target_type,target_id,target_creator,target_created) VALUES (?,?,?,?,?)", tag, models.GetIDType(targetID), targetID, targetCreator, targetCreated) + _, err = db.Conn.Exec("INSERT INTO tags_using (tag_id,target_type,target_id,target_creator,target_created,target_owner) VALUES (?,?,?,?,?,?)", tag, models.GetIDType(targetID), targetID, targetCreator, targetCreated, targetOwner) if err != nil { logger.Warn("add post tag error", "error", err) } @@ -166,8 +166,14 @@ func GetTargetIDs(tagID string) ([]string, error) { func GetUserTags(userID string) ([]*models.Tag, *e.Error) { tagsMap := make(map[string]*models.Tag) + var rows *sql.Rows + var err error - rows, err := db.Conn.Query("SELECT tag_id from tags_using where target_creator=?", userID) + if models.GetIDType(userID) == models.IDTypeUser { + rows, err = db.Conn.Query("SELECT tag_id from tags_using where target_creator=?", userID) + } else { + rows, err = db.Conn.Query("SELECT tag_id from tags_using where target_owner=?", userID) + } if err != nil { logger.Warn("get tag error", "error", err) return nil, e.New(http.StatusInternalServerError, e.Internal) diff --git a/server/internal/user/user.go b/server/internal/user/user.go index b186ad58..ccf3a91f 100644 --- a/server/internal/user/user.go +++ b/server/internal/user/user.go @@ -124,7 +124,7 @@ func UpdateUser(u *models.User) *e.Error { } //update user skills - err = tags.UpdateTargetTags("", u.ID, u.Skills, u.Created) + err = tags.UpdateTargetTags("", u.ID, u.Skills, u.Created, "") if err != nil { logger.Warn("upate tags error", "error", err) return e.New(http.StatusInternalServerError, e.Internal) diff --git a/src/components/story/stories.tsx b/src/components/story/stories.tsx index 4fc75b61..8671b5b3 100644 --- a/src/components/story/stories.tsx +++ b/src/components/story/stories.tsx @@ -44,6 +44,18 @@ export const Stroies = (props: Props) => { }, [filter]) function fetchMoreListItems() { + if (page === 1 && posts.length === 0) { + // 走到这里面说明视图逻辑出问题了,你可以这样触发 + // 进入tag或者个人页面,然后把文章拉到第二页 + // 此时点击tag,会瞬间同时加载第一页和第二页的文章 + // 因为第一页的文章还没加载完毕,没有更新posts,第二页的文章就会覆盖掉第一页的数据 + // 这样第一页的数据就丢失了 + + // 走到该函数意味着已经是第二页的加载逻辑了,在此时posts不应该为空 + //@ts-ignore + setIsFetching(false) + return + } if (noMore) { //@ts-ignore setIsFetching(false)