add story forbidden

pull/52/head
sunface 4 years ago
parent 1540c7dd62
commit f5ca3e25ea

@ -1,4 +1,4 @@
import { Box, Button, chakra, Divider, Flex, Heading, HStack, Image, Radio, RadioGroup, Stack, Text} from "@chakra-ui/react"
import { Box, Button, chakra, Divider, Flex, Heading, HStack, Image, Radio, RadioGroup, Stack, Tag, Text, Tooltip} from "@chakra-ui/react"
import Comments from "components/comments/comments"
import { MarkdownRender } from "components/markdown-editor/render"
import { StoryAuthor } from "components/story/story-author"
@ -9,7 +9,7 @@ import PostNav from "layouts/nav/post-nav"
import PageContainer from "layouts/page-container"
import { useRouter } from "next/router"
import React, { useEffect, useState } from "react"
import { Story } from "src/types/story"
import { Story, StoryStatus } from "src/types/story"
import { requestApi } from "utils/axios/request"
import StorySidebar from "components/story/story-sidebar"
import Series from "components/story/series"
@ -63,7 +63,11 @@ const PostPage = () => {
<Box width={["100%", "100%", "75%", "75%"]} height="fit-content" pl={[0, 0, "0%", "10%"]}>
<Image src={post.cover} />
<Box px="2">
<Heading size="lg" my="6" lineHeight="1.5">{post.title}</Heading>
<HStack>
<Heading size="lg" my="6" lineHeight="1.5">{post.title}</Heading>
{post.status === StoryStatus.Forbidden && <Tooltip label="因为文章内容问题,你的文章已经被禁用,如需恢复,请修改内容后,去创作中心申请恢复"><Tag colorScheme="red"></Tag></Tooltip>}
</HStack>
<Divider my="4" />
<Flex width="100%" justifyContent="space-between" display="flex" alignItems="start" layerStyle="textSecondary" cursor="pointer" onClick={() => setReport(true)}>

@ -61,7 +61,7 @@ const PostsPage = () => {
</HStack>
<HStack >
<Button size="sm" onClick={() => router.push(r.url)}></Button>
<Button size="sm" onClick={() => window.open(r.url)}></Button>
<Button colorScheme="orange" size="sm" onClick={() => deleteReport(r.id)}>Report</Button>
</HStack>
</Flex>)

@ -1,24 +1,10 @@
import { Box, Button, Flex, Heading, HStack, Image, Text, VStack } from "@chakra-ui/react"
import Card from "components/card"
import Empty from "components/empty"
import { MarkdownRender } from "components/markdown-editor/render"
import Stories from "components/story/stories"
import SEO from "components/seo"
import siteConfig from "configs/site-config"
import useSession from "hooks/use-session"
import PageContainer1 from "layouts/page-container1"
import { useRouter } from "next/router"
import React, { useEffect, useState } from "react"
import { ReserveUrls } from "src/data/reserve-urls"
import { Story } from "src/types/story"
import { Tag } from "src/types/tag"
import { requestApi } from "utils/axios/request"
import { isAdmin } from "utils/role"
import Follow from "components/interaction/follow"
import Count from "components/count"
import StoryFilters from "components/story/story-filter"
import CommentCard from "components/comments/comment"
import { Comment } from "src/types/comments"
import { Box, Button } from "@chakra-ui/react"
const CommentPage = () => {
const router = useRouter()
@ -37,11 +23,16 @@ const CommentPage = () => {
console.log(res.data)
}
const gotoPost = async () => {
const res = await requestApi.get(`/story/byCommentID/${comment.id}`)
router.push(res.data + '#comments')
}
return (
<>
<Box p="4">
<Button mb="2" onClick={() => gotoPost()}></Button>
{comment && session && <CommentCard user={session.user} comment={comment} onChange={null}/>}
</>
</Box>
)
}

@ -25,3 +25,27 @@ func GetUsers() ([]*models.User, *e.Error) {
return users, nil
}
func ForbiddenStory(id string) *e.Error {
var status int
err := db.Conn.QueryRow("SELECT status FROM story WHERE id=?", id).Scan(&status)
if err != nil {
logger.Warn("get story status error", "error", err)
return e.New(http.StatusInternalServerError, e.Internal)
}
var newStatus int
if status != models.StatusForbidden {
newStatus = models.StatusForbidden
} else {
newStatus = models.StatusDraft
}
_, err = db.Conn.Exec("UPDATE story SET status=? WHERE id=?", newStatus, id)
if err != nil {
logger.Warn("update story status error", "error", err)
return e.New(http.StatusInternalServerError, e.Internal)
}
return nil
}

@ -119,3 +119,20 @@ func DeleteReport(c *gin.Context) {
c.JSON(http.StatusOK, common.RespSuccess(nil))
}
func ForbiddenStory(c *gin.Context) {
id := c.Param("id")
currentUser := user.CurrentUser(c)
if !currentUser.Role.IsAdmin() {
c.JSON(http.StatusForbidden, common.RespError(e.NoPermission))
return
}
err := admin.ForbiddenStory(id)
if err != nil {
c.JSON(err.Status, common.RespError(err.Message))
return
}
c.JSON(http.StatusOK, common.RespSuccess(nil))
}

@ -1,6 +1,7 @@
package api
import (
"fmt"
"net/http"
"strings"
@ -89,6 +90,7 @@ func GetStoryComment(c *gin.Context) {
id := c.Param("id")
comment, err := story.GetComment(id)
if err != nil {
c.JSON(err.Status, common.RespError(err.Message))
return
}
@ -133,3 +135,23 @@ func DeleteStoryComment(c *gin.Context) {
c.JSON(http.StatusOK, common.RespSuccess(nil))
}
func GetStoryIDByCommentID(c *gin.Context) {
cid := c.Param("cid")
id, _, err := story.GetStoryIDByCommentID(cid)
if err != nil {
c.JSON(http.StatusInternalServerError, common.RespError(e.Internal))
return
}
creatorID, err1 := story.GetPostCreator(id)
if err1 != nil {
c.JSON(err1.Status, common.RespError(err1.Message))
return
}
creator := &models.UserSimple{ID: creatorID}
creator.Query()
c.JSON(http.StatusOK, common.RespSuccess(fmt.Sprintf("/%s/%s", creator.Username, id)))
}

@ -73,6 +73,7 @@ func (s *Server) Start() error {
r.GET("/story/comment/:id", api.GetStoryComment)
r.POST("/story/comment", IsLogin(), api.SubmitComment)
r.DELETE("/story/comment/:id", IsLogin(), api.DeleteStoryComment)
r.GET("/story/byCommentID/:cid", api.GetStoryIDByCommentID)
r.GET("/story/posts/editor", IsLogin(), api.GetEditorPosts)
r.GET("/story/posts/org/:id", IsLogin(), api.GetOrgPosts)
@ -91,7 +92,7 @@ func (s *Server) Start() error {
r.DELETE("/story/post/:id", IsLogin(), api.DeletePost)
r.POST("/story/bookmark/:storyID", IsLogin(), api.Bookmark)
r.GET("/story/bookmark/posts", IsLogin(), api.GetBookmarkPosts)
r.POST("/story/forbidden/:id", IsLogin(), api.ForbiddenStory)
// tag apis
r.POST("/tag", IsLogin(), api.SubmitTag)
r.DELETE("/tag/:id", IsLogin(), api.DeleteTag)

@ -10,6 +10,7 @@ const (
StatusDraft = 1
StatusPublished = 2
StatusHidden = 3
StatusForbidden = 4
)
type Story struct {

@ -0,0 +1,37 @@
import { chakra, HStack, IconButton, Image, Tooltip, useColorMode, useColorModeValue } from "@chakra-ui/react";
import SvgButton from "components/svg-button";
import { useState } from "react";
import { FaBan, FaHeart, FaRegHeart } from "react-icons/fa";
import { Story, StoryStatus } from "src/types/story";
import { requestApi } from "utils/axios/request";
interface Props {
story: Story
}
const Forbidden = (props: Props) => {
const { story } = props
const [status,setStatus] = useState(story.status)
const forbiddenStory = async () => {
await requestApi.post(`/story/forbidden/${story.id}`)
if (status != StoryStatus.Forbidden) {
setStatus(StoryStatus.Forbidden)
} else {
setStatus(StoryStatus.Draft)
}
}
return (
<IconButton
aria-label="a icon button"
variant="ghost"
_focus={null}
layerStyle="textSecondary"
onClick={forbiddenStory}
icon={<FaBan fontSize="1.4rem" color={status === StoryStatus.Forbidden ? 'red' : null} />}
/>
)
}
export default Forbidden

@ -1,6 +1,6 @@
import React from "react"
import { Box, BoxProps, useColorModeValue, VStack } from "@chakra-ui/react"
import { Story } from "src/types/story"
import { Box, BoxProps, IconButton, useColorModeValue, VStack } from "@chakra-ui/react"
import { Story, StoryStatus } from "src/types/story"
import useSession from "hooks/use-session"
import Like from "../interaction/like"
import Bookmark from "./bookmark"
@ -8,6 +8,11 @@ import SvgButton from "components/svg-button"
import { useRouter } from "next/router"
import { ReserveUrls } from "src/data/reserve-urls"
import { IDType } from "src/types/id"
import { isAdmin } from "utils/role"
import { getSvgIcon } from "components/svg-icon"
import { FaBan } from "react-icons/fa"
import { requestApi } from "utils/axios/request"
import Forbidden from "./forbidden"
interface Props {
story: Story
@ -29,6 +34,9 @@ export const StorySidebar = (props: Props) => {
return ''
}
return (
<VStack alignItems="left" pos="fixed" display={{ base: "none", md: 'flex' }} width={["100%", "100%", "15%", "15%"]}>
<Box>
@ -61,6 +69,10 @@ export const StorySidebar = (props: Props) => {
icon="edit"
/>
</Box>}
{isAdmin(session?.user.role) && <Box mt="4">
<Forbidden story={story} />
</Box>}
</Box>
</VStack>
)

@ -5,7 +5,8 @@ import { Tag } from './tag';
export enum StoryStatus {
Draft = 1,
Published = 2,
Hiddent = 3
Hidden = 3 ,
Forbidden = 4
}
export interface Story {

Loading…
Cancel
Save