abstract tags module

pull/50/head
sunface 4 years ago
parent a7833a50c0
commit 956adfb8eb

@ -1,10 +1,10 @@
import { Box, chakra, Divider, Flex, Heading, HStack, IconButton, Image, storageKey, VStack } from "@chakra-ui/react"
import Comments from "components/comments/comments"
import Container from "components/container"
import LikeButton from "components/posts/unicorn-like"
import LikeButton from "components/story/unicorn-like"
import { MarkdownRender } from "components/markdown-editor/render"
import PostAuthor from "components/posts/post-author"
import TagTextCard from "components/posts/tag-text-card"
import PostAuthor from "components/story/post-author"
import TagTextCard from "components/story/tag-text-card"
import SEO from "components/seo"
import siteConfig from "configs/site-config"
import useSession from "hooks/use-session"
@ -21,10 +21,10 @@ import { Comment } from "src/types/comments"
import { Post } from "src/types/posts"
import { Tag } from "src/types/tag"
import { requestApi } from "utils/axios/request"
import UnicornLike from "components/posts/unicorn-like"
import UnicornLike from "components/story/unicorn-like"
import SvgButton from "components/svg-button"
import Bookmark from "components/posts/bookmark"
import PostSidebar from "components/posts/post-sidebar"
import Bookmark from "components/story/bookmark"
import PostSidebar from "components/story/post-sidebar"
const PostPage = () => {
const router = useRouter()

@ -16,9 +16,9 @@ import { User } from "src/types/session"
import { requestApi } from "utils/axios/request"
import moment from 'moment'
import { Post } from "src/types/posts"
import PostCard from "components/posts/post-card"
import PostCard from "components/story/post-card"
import userCustomTheme from "theme/user-custom"
import Posts from "components/posts/posts"
import Posts from "components/story/posts"
import Link from "next/link"
import Empty from "components/empty"
import Count from "components/count"
@ -111,12 +111,12 @@ const UserPage = () => {
<Wrap mt="4" p="1">
{
user.rawSkills.map(skill =>
<Link href={`${ReserveUrls.Tags}/${skill.name}`}>
<Link key={skill.id} href={`${ReserveUrls.Tags}/${skill.name}`}>
<HStack spacing="1" mr="4" mb="2" cursor="pointer">
<Avatar src={skill.icon} size="sm" />
<Text>{skill.title}</Text>
</HStack>
</Link>)
</Link>)
}
</Wrap>
</Card>}

@ -21,7 +21,7 @@ import {
import { requestApi } from "utils/axios/request"
import TagCard from 'src/components/tags/tag-card'
import { Post } from "src/types/posts"
import Posts from "components/posts/posts"
import Posts from "components/story/posts"
import { find } from "lodash"
import userCustomTheme from "theme/user-custom"
import Empty from "components/empty"

@ -9,7 +9,7 @@ import { requestApi } from "utils/axios/request"
import { useDisclosure } from "@chakra-ui/react"
import { Field, Form, Formik } from "formik"
import { config } from "configs/config"
import TextPostCard from "components/posts/text-post-card"
import TextPostCard from "components/story/text-post-card"
import { Post } from "src/types/posts"
import { FaExternalLinkAlt, FaRegEdit } from "react-icons/fa"
import { useRouter } from "next/router"

@ -9,9 +9,9 @@ import {
Divider
} from "@chakra-ui/react"
import Card from "components/card"
import PostCard from "components/posts/post-card"
import Posts from "components/posts/posts"
import SimplePostCard from "components/posts/simple-post-card"
import PostCard from "components/story/post-card"
import Posts from "components/story/posts"
import SimplePostCard from "components/story/simple-post-card"
import SEO from "components/seo"
import { getSvgIcon } from "components/svg-icon"
import siteConfig from "configs/site-config"

@ -3,7 +3,7 @@ import Card from "components/card"
import Container from "components/container"
import Empty from "components/empty"
import { MarkdownRender } from "components/markdown-editor/render"
import Posts from "components/posts/posts"
import Posts from "components/story/posts"
import SEO from "components/seo"
import siteConfig from "configs/site-config"
import useSession from "hooks/use-session"

@ -2,7 +2,6 @@ package api
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/imdotdev/im.dev/server/internal/story"
@ -36,7 +35,7 @@ func GetUserPosts(c *gin.Context) {
}
func GetTagPosts(c *gin.Context) {
tagID, _ := strconv.ParseInt(c.Param("id"), 10, 64)
tagID := c.Param("id")
user := user.CurrentUser(c)
posts, err := story.TagPosts(user, tagID)
if err != nil {

@ -42,16 +42,6 @@ var sqlTables = map[string]string{
updated DATETIME
);`,
"user_skills": `CREATE TABLE IF NOT EXISTS user_skills (
user_id VARCHAR(255),
skill_id INTEGER
);
CREATE INDEX IF NOT EXISTS user_skills_userid
ON user_skills (user_id);
CREATE INDEX IF NOT EXISTS user_skills_skillid
ON user_skills (skill_id);
`,
"sessions": `CREATE TABLE IF NOT EXISTS sessions (
sid VARCHAR(255) primary key,
user_id VARCHAR(255)
@ -78,13 +68,11 @@ var sqlTables = map[string]string{
ON posts (creator);
CREATE INDEX IF NOT EXISTS posts_created
ON posts (created);
CREATE UNIQUE INDEX IF NOT EXISTS posts_creator_slug
ON posts (creator, slug);
`,
"likes": `CREATE TABLE IF NOT EXISTS likes (
user_id VARCHAR(255),
story_id VARCHAR(255),
user_id VARCHAR(255),
created DATETIME NOT NULL
);
CREATE INDEX IF NOT EXISTS likes_userid
@ -93,6 +81,29 @@ var sqlTables = map[string]string{
ON likes (story_id);
`,
"likes_count": `CREATE TABLE IF NOT EXISTS likes_count (
story_id VARCHAR(255) PRIMARY KEY,
count INTEGER
);
`,
"follows": `CREATE TABLE IF NOT EXISTS follows (
user_id VARCHAR(255),
target_id VARCHAR(255),
created DATETIME NOT NULL
);
CREATE INDEX IF NOT EXISTS follows_userid
ON follows (user_id);
CREATE INDEX IF NOT EXISTS follows_targetid
ON follows (target_id);
`,
"follows_count": `CREATE TABLE IF NOT EXISTS follows_count (
target_id VARCHAR(255) PRIMARY KEY,
count INTEGER
);
`,
"tags": `CREATE TABLE IF NOT EXISTS tags (
id VARCHAR(255) PRIMARY KEY,
creator VARCHAR(255) NOT NULL,
@ -111,14 +122,14 @@ var sqlTables = map[string]string{
ON tags (created);
`,
"tag_post": `CREATE TABLE IF NOT EXISTS tag_post (
"tags_using": `CREATE TABLE IF NOT EXISTS tags_using (
tag_id VARCHAR(255),
post_id VARCHAR(255)
target_id VARCHAR(255)
);
CREATE INDEX IF NOT EXISTS tag_post_tagid
ON tag_post (tag_id);
CREATE INDEX IF NOT EXISTS tag_post_postid
ON tag_post (post_id);
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);
`,
"comments": `CREATE TABLE IF NOT EXISTS comments (

@ -94,16 +94,10 @@ func SubmitPost(c *gin.Context) (map[string]string, *e.Error) {
}
//update tags
_, err = db.Conn.Exec("DELETE FROM tag_post WHERE post_id=?", post.ID)
err = tags.UpdateTargetTags(post.ID, post.Tags)
if err != nil {
logger.Warn("delete post tags error", "error", err)
}
for _, tag := range post.Tags {
_, err = db.Conn.Exec("INSERT INTO tag_post (tag_id,post_id) VALUES (?,?)", tag, post.ID)
if err != nil {
logger.Warn("add post tag error", "error", err)
}
logger.Warn("upate tags error", "error", err)
return nil, e.New(http.StatusInternalServerError, e.Internal)
}
return map[string]string{
@ -120,7 +114,7 @@ func DeletePost(id string) *e.Error {
}
// delete tags
_, err = db.Conn.Exec("DELETE FROM tag_post WHERE post_id=?", id)
err = tags.DeleteTargetTags(id)
if err != nil {
logger.Warn("delete post tags error", "error", err)
}
@ -148,24 +142,12 @@ func GetPost(id string, slug string) (*models.Post, *e.Error) {
err = ar.Creator.Query()
// get tags
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 {
t, rawTags, err := tags.GetTargetTags(ar.ID)
if err != nil {
return nil, e.New(http.StatusInternalServerError, e.Internal)
}
ar.RawTags = make([]*models.Tag, 0)
for rows.Next() {
var tag string
err = rows.Scan(&tag)
t = append(t, tag)
rawTag, err := tags.GetTag(tag, "")
if err == nil {
ar.RawTags = append(ar.RawTags, rawTag)
}
}
ar.Tags = t
ar.RawTags = rawTags
// add views count
_, err = db.Conn.Exec("UPDATE posts SET views=? WHERE id=?", ar.Views+1, ar.ID)

@ -40,25 +40,18 @@ func UserPosts(user *models.User, uid string) (models.Posts, *e.Error) {
return posts, nil
}
func TagPosts(user *models.User, tagID int64) (models.Posts, *e.Error) {
func TagPosts(user *models.User, tagID string) (models.Posts, *e.Error) {
// get post ids
rows, err := db.Conn.Query("select post_id from tag_post where tag_id=?", tagID)
postIDs, err := tags.GetTargetIDs(tagID)
if err != nil {
logger.Warn("get user posts error", "error", err)
return nil, e.New(http.StatusInternalServerError, e.Internal)
}
postIDs := make([]string, 0)
for rows.Next() {
var id string
rows.Scan(&id)
postIDs = append(postIDs, id)
}
ids := strings.Join(postIDs, "','")
q := fmt.Sprintf("select id,slug,title,url,cover,brief,likes,views,creator,created,updated from posts where id in ('%s')", ids)
rows, err = db.Conn.Query(q)
rows, err := db.Conn.Query(q)
if err != nil && err != sql.ErrNoRows {
logger.Warn("get user posts error", "error", err)
return nil, e.New(http.StatusInternalServerError, e.Internal)
@ -97,13 +90,13 @@ func BookmarkPosts(user *models.User, filter string) (models.Posts, *e.Error) {
posts := getPosts(user, rows)
for _, post := range posts {
ts, err := tags.GetStoryTags(post.ID)
_, rawTags, err := tags.GetTargetTags(post.ID)
if err != nil {
logger.Warn("get story tags error", "error", err)
continue
}
post.RawTags = ts
post.RawTags = rawTags
}
sort.Sort(posts)

@ -94,7 +94,7 @@ func GetTags() (models.Tags, *e.Error) {
tag.SetCover()
tags = append(tags, tag)
db.Conn.QueryRow("SELECT count(*) FROM tag_post WHERE tag_id=?", tag.ID).Scan(&tag.PostCount)
db.Conn.QueryRow("SELECT count(*) FROM tags_using WHERE tag_id=?", tag.ID).Scan(&tag.PostCount)
}
sort.Sort(tags)
@ -129,16 +129,16 @@ func GetTag(id string, name string) (*models.Tag, *e.Error) {
md, _ := utils.Uncompress(rawmd)
tag.Md = string(md)
db.Conn.QueryRow("SELECT count(*) FROM tag_post WHERE tag_id=?", tag.ID).Scan(&tag.PostCount)
db.Conn.QueryRow("SELECT count(*) FROM tags_using WHERE tag_id=?", tag.ID).Scan(&tag.PostCount)
tag.SetCover()
return tag, nil
}
func GetSimpleTag(id int64, name string) (*models.Tag, *e.Error) {
func GetSimpleTag(id string, name string) (*models.Tag, *e.Error) {
tag := &models.Tag{}
err := db.Conn.QueryRow("SELECT id,title,icon from tags where id=? or name=?", id, name).Scan(
&tag.ID, &tag.Title, &tag.Icon,
err := db.Conn.QueryRow("SELECT id,name,title,icon from tags where id=? or name=?", id, name).Scan(
&tag.ID, &tag.Name, &tag.Title, &tag.Icon,
)
if err != nil {
if err == sql.ErrNoRows {
@ -151,16 +151,16 @@ func GetSimpleTag(id int64, name string) (*models.Tag, *e.Error) {
return tag, nil
}
func GetStoryTags(storyID string) ([]*models.Tag, error) {
ids := make([]int64, 0)
rows, err := db.Conn.Query("SELECT tag_id FROM tag_post WHERE post_id=?", storyID)
func GetTargetTags(targetID string) ([]string, []*models.Tag, error) {
ids := make([]string, 0)
rows, err := db.Conn.Query("SELECT tag_id FROM tags_using WHERE target_id=?", targetID)
if err != nil {
return nil, err
return nil, nil, err
}
rawTags := make([]*models.Tag, 0)
for rows.Next() {
var id int64
var id string
err = rows.Scan(&id)
ids = append(ids, id)
@ -170,5 +170,46 @@ func GetStoryTags(storyID string) ([]*models.Tag, error) {
}
}
return rawTags, nil
return ids, rawTags, nil
}
func UpdateTargetTags(targetID string, tags []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_id) VALUES (?,?)", tag, targetID)
if err != nil {
logger.Warn("add post tag error", "error", err)
}
}
return nil
}
func DeleteTargetTags(targetID string) error {
_, err := db.Conn.Exec("DELETE FROM tags_using WHERE target_id=?", targetID)
if err != nil {
return err
}
return nil
}
func GetTargetIDs(tagID string) ([]string, error) {
rows, err := db.Conn.Query("select target_id from tags_using where tag_id=?", tagID)
if err != nil {
return nil, err
}
ids := make([]string, 0)
for rows.Next() {
var id string
rows.Scan(&id)
ids = append(ids, id)
}
return ids, nil
}

@ -54,24 +54,13 @@ func GetUserDetail(id string, username string) (*models.User, *e.Error) {
}
// get user skills
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 string
rows.Scan(&skill)
user.Skills = append(user.Skills, skill)
rawTag, err := tags.GetTag(skill, "")
if err != nil {
logger.Warn("get tag error", "error", err)
continue
}
user.RawSkills = append(user.RawSkills, rawTag)
skills, rawSkills, err := tags.GetTargetTags(user.ID)
if err != nil {
logger.Warn("get user skills error", "error", err)
return nil, e.New(http.StatusInternalServerError, e.Internal)
}
user.RawSkills = rawSkills
user.Skills = skills
return user, nil
}
@ -108,16 +97,10 @@ func UpdateUser(u *models.User) *e.Error {
}
//update user skills
_, err = db.Conn.Exec("DELETE FROM user_skills WHERE user_id=?", u.ID)
err = tags.UpdateTargetTags(u.ID, u.Skills)
if err != nil {
logger.Warn("delete user skills error", "error", err)
}
for _, skill := range u.Skills {
_, err = db.Conn.Exec("INSERT INTO user_skills (user_id,skill_id) VALUES (?,?)", u.ID, skill)
if err != nil {
logger.Warn("add user skill error", "error", err)
}
logger.Warn("upate tags error", "error", err)
return e.New(http.StatusInternalServerError, e.Internal)
}
return nil

@ -5,7 +5,7 @@ import Card from "components/card"
import { getUserName } from "utils/user"
import moment from 'moment'
import { MarkdownRender } from "components/markdown-editor/render"
import Like from "components/posts/like"
import Like from "components/story/like"
import { FaRegEdit, FaRegFlag, FaRegTrashAlt, FaReply, FaTrash } from "react-icons/fa"
import { User } from "src/types/session"
import CommentEditor from "./editor"

@ -5,7 +5,7 @@ import Card from "components/card"
import { getUserName } from "utils/user"
import moment from 'moment'
import { MarkdownRender } from "components/markdown-editor/render"
import Like from "components/posts/like"
import Like from "components/story/like"
import { FaRegEdit, FaRegFlag, FaRegTrashAlt, FaReply, FaTrash } from "react-icons/fa"
import { User } from "src/types/session"
import CommentEditor from "./editor"

@ -3,7 +3,7 @@ import { Box, Popover, PopoverTrigger, Button, PopoverContent, PopoverBody, Inpu
import { Tag } from "src/types/tag"
import { requestApi } from "utils/axios/request"
import { cloneDeep, findIndex } from "lodash"
import TagCard from 'src/components/posts/tag-list-card'
import TagCard from 'components/story/tag-list-card'
import { config } from "configs/config"
interface Props {
options: Tag[]

Loading…
Cancel
Save