diff --git a/pages/admin/report.tsx b/pages/admin/report.tsx index f04f5395..7e19fa70 100644 --- a/pages/admin/report.tsx +++ b/pages/admin/report.tsx @@ -1,4 +1,4 @@ -import { Box, useToast } from "@chakra-ui/react" +import { Box, Button, chakra, Flex, Heading, HStack, IconButton, Image, Table, Tbody, Td, Text, Th, Thead, Tr, useToast, VStack } from "@chakra-ui/react" import Card from "components/card" import Sidebar from "layouts/sidebar/sidebar" @@ -6,28 +6,66 @@ import React, { useEffect, useState } from "react" import { adminLinks } from "src/data/links" import { requestApi } from "utils/axios/request" import PageContainer1 from "layouts/page-container1" - +import { getSvgIcon } from "components/svg-icon" +import { getUserName } from "utils/user" +import { IDType } from "src/types/id" +import moment from 'moment' +import { useRouter } from "next/router" const PostsPage = () => { - const [reports, setReports]= useState([]) + const [reports, setReports] = useState([]) + const router = useRouter() const toast = useToast() - const getConfig = async () => { + const getReports = async () => { const res = await requestApi.get(`/admin/reports`) console.log(res.data) setReports(res.data) } useEffect(() => { - getConfig() + getReports() }, []) + const displayContent = type => { + switch (type) { + case IDType.Post: + return "文章" + case IDType.Comment: + return "评论" + default: + break; + } + } + + const deleteReport = async id => { + await requestApi.delete(`/admin/report/${id}`) + getReports() + } + return ( <> - + + Report列表 + + + { + reports.map(r => + + + + {getUserName(r.reporter)} + 于{moment(r.created).fromNow()},提交了关于 {displayContent(r.type)} 的报告 : {r.content} + + + + + + ) + } diff --git a/pages/r/comment/[id].tsx b/pages/r/comment/[id].tsx new file mode 100644 index 00000000..f70c9e6d --- /dev/null +++ b/pages/r/comment/[id].tsx @@ -0,0 +1,49 @@ +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" + +const CommentPage = () => { + const router = useRouter() + const session = useSession() + const [comment,setComment]:[Comment,any] = useState(null) + useEffect(() => { + if (router.query.id) { + initData() + } + }, [router.query.id]) + + const initData = async () => { + const res = await requestApi.get(`/story/comment/${router.query.id}`) + res.data.replies = [] + setComment(res.data) + console.log(res.data) + } + + + return ( + <> + {comment && session && } + + ) +} + +export default CommentPage + diff --git a/server/internal/admin/report.go b/server/internal/admin/report.go index b57d89ae..5f42d305 100644 --- a/server/internal/admin/report.go +++ b/server/internal/admin/report.go @@ -2,6 +2,7 @@ package admin import ( "database/sql" + "fmt" "net/http" "sort" "time" @@ -18,8 +19,8 @@ const ( ) func AddReport(targetID string, content string, reporter string) *e.Error { - _, err := db.Conn.Exec("INSERT INTO report (target_id,type,reporter,status,created) VALUES (?,?,?,?,?)", - targetID, models.GetIDType(targetID), reporter, StatusUndealed, time.Now()) + _, err := db.Conn.Exec("INSERT INTO report (target_id,type,content,reporter,status,created) VALUES (?,?,?,?,?,?)", + targetID, models.GetIDType(targetID), content, reporter, StatusUndealed, time.Now()) if err != nil { if e.IsErrUniqueConstraint(err) { @@ -34,7 +35,7 @@ func AddReport(targetID string, content string, reporter string) *e.Error { func GetReports(page int) ([]*models.Report, *e.Error) { reports := make(models.Reports, 0) - rows, err := db.Conn.Query("SELECT id,target_id,reporter,status,created FROM report") + rows, err := db.Conn.Query("SELECT id,type,content,target_id,reporter,status,created FROM report") if err != nil && err != sql.ErrNoRows { logger.Warn("get reports error", "error", err) return nil, e.New(http.StatusInternalServerError, e.Internal) @@ -49,7 +50,7 @@ func GetReports(page int) ([]*models.Report, *e.Error) { Reporter: &models.UserSimple{}, } var uid string - err := rows.Scan(&r.ID, &r.TargetID, &uid, &r.Status, &r.Created) + err := rows.Scan(&r.ID, &r.Type, &r.Content, &r.TargetID, &uid, &r.Status, &r.Created) if err != nil { logger.Warn("scan report error", "error", err) continue @@ -57,6 +58,13 @@ func GetReports(page int) ([]*models.Report, *e.Error) { r.Reporter.ID = uid r.Reporter.Query() + + switch r.Type { + case models.IDTypePost: + r.URL = fmt.Sprintf("/%s/%s", r.Reporter.Username, r.TargetID) + case models.IDTypeComment: + r.URL = fmt.Sprintf("/r/comment/%s", r.TargetID) + } reports = append(reports, r) } @@ -64,3 +72,13 @@ func GetReports(page int) ([]*models.Report, *e.Error) { return reports, nil } + +func DeleteReport(id string) *e.Error { + _, err := db.Conn.Exec("DELETE FROM report WHERE id=?", id) + if err != nil { + logger.Warn("delete report error", "error", err) + return e.New(http.StatusInternalServerError, e.Internal) + } + + return nil +} diff --git a/server/internal/api/admin.go b/server/internal/api/admin.go index 0bfa4ac2..7dfe6d8e 100644 --- a/server/internal/api/admin.go +++ b/server/internal/api/admin.go @@ -102,3 +102,20 @@ func GetReports(c *gin.Context) { c.JSON(http.StatusOK, common.RespSuccess(res)) } + +func DeleteReport(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.DeleteReport(id) + if err != nil { + c.JSON(err.Status, common.RespError(err.Message)) + return + } + + c.JSON(http.StatusOK, common.RespSuccess(nil)) +} diff --git a/server/internal/api/comment.go b/server/internal/api/comment.go index 02e27e6f..ca95d8b6 100644 --- a/server/internal/api/comment.go +++ b/server/internal/api/comment.go @@ -85,6 +85,22 @@ func GetStoryComments(c *gin.Context) { c.JSON(http.StatusOK, common.RespSuccess(comments)) } +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 + } + + comment.Creator = &models.UserSimple{ + ID: comment.CreatorID, + } + comment.Creator.Query() + + c.JSON(http.StatusOK, common.RespSuccess(comment)) +} + func DeleteStoryComment(c *gin.Context) { id := c.Param("id") //only admin and owner can delete comment diff --git a/server/internal/server.go b/server/internal/server.go index 9b743054..c479ae27 100644 --- a/server/internal/server.go +++ b/server/internal/server.go @@ -70,6 +70,7 @@ func (s *Server) Start() error { r.GET("/story/post/:id", api.GetStory) r.GET("/story/id/:type", IsLogin(), InvasionCheck(), api.GenStoryID) r.GET("/story/comments/:id", api.GetStoryComments) + r.GET("/story/comment/:id", api.GetStoryComment) r.POST("/story/comment", IsLogin(), api.SubmitComment) r.DELETE("/story/comment/:id", IsLogin(), api.DeleteStoryComment) @@ -152,6 +153,7 @@ func (s *Server) Start() error { r.GET("/admin/user/all", IsLogin(), api.AdminGetUsers) r.GET("/admin/config", IsLogin(), api.AdminConfig) r.GET("/admin/reports", IsLogin(), api.GetReports) + r.DELETE("/admin/report/:id", IsLogin(), api.DeleteReport) // notification apis r.GET("/notifications/list/:type", IsLogin(), api.GetNotifications) r.GET("/notifications/unread", IsLogin(), api.GetUnread) diff --git a/server/internal/storage/sql_tables.go b/server/internal/storage/sql_tables.go index ff17c3ab..0f6343b9 100644 --- a/server/internal/storage/sql_tables.go +++ b/server/internal/storage/sql_tables.go @@ -290,6 +290,7 @@ var sqlTables = map[string]string{ id INTEGER PRIMARY KEY AUTOINCREMENT, target_id VARCHAR(255), type VARCHAR(1) NOT NULL, + content VARCHAR(255), reporter VARCHAR(255) NOT NULL, status tinyint NOT NULL, created DATETIME NOT NULL diff --git a/server/internal/story/comment.go b/server/internal/story/comment.go index 74c74032..0fbc5ebb 100644 --- a/server/internal/story/comment.go +++ b/server/internal/story/comment.go @@ -131,6 +131,9 @@ func GetComment(id string) (*models.Comment, *e.Error) { &c.ID, &c.TargetID, &c.CreatorID, &rawMd, &c.Created, &c.Updated, ) if err != nil { + if err == sql.ErrNoRows { + return nil, e.New(http.StatusNotFound, "评论不存在") + } logger.Warn("get comment error", "error", err) return nil, e.New(http.StatusInternalServerError, e.Internal) } diff --git a/server/pkg/models/report.go b/server/pkg/models/report.go index 471c22e4..aa509191 100644 --- a/server/pkg/models/report.go +++ b/server/pkg/models/report.go @@ -3,11 +3,14 @@ package models import "time" type Report struct { - ID int `json:"id"` - TargetID string `json:"target_id"` - Reporter *UserSimple - Status int `json:"status"` - Created time.Time `json:"created"` + ID int `json:"id"` + Type string `json:"type"` + Content string `json:"content"` + TargetID string `json:"target_id"` + Reporter *UserSimple `json:"reporter"` + Status int `json:"status"` + Created time.Time `json:"created"` + URL string `json:"url"` } type Reports []*Report