pull/52/head
sunface 4 years ago
parent 00bc3406c7
commit 17f627846e

@ -0,0 +1,38 @@
import { Box, useToast } from "@chakra-ui/react"
import Card from "components/card"
import Sidebar from "layouts/sidebar/sidebar"
import React, { useEffect, useState } from "react"
import { adminLinks } from "src/data/links"
import { requestApi } from "utils/axios/request"
import PageContainer1 from "layouts/page-container1"
const PostsPage = () => {
const [reports, setReports]= useState([])
const toast = useToast()
const getConfig = async () => {
const res = await requestApi.get(`/admin/reports`)
console.log(res.data)
setReports(res.data)
}
useEffect(() => {
getConfig()
}, [])
return (
<>
<PageContainer1>
<Box display="flex">
<Sidebar routes={adminLinks} title="管理员" />
<Card ml="4" p="6" width="100%">
</Card>
</Box>
</PageContainer1>
</>
)
}
export default PostsPage

@ -1,7 +1,9 @@
package admin
import (
"database/sql"
"net/http"
"sort"
"time"
"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
@ -20,9 +22,45 @@ func AddReport(targetID string, content string, reporter string) *e.Error {
targetID, models.GetIDType(targetID), reporter, StatusUndealed, time.Now())
if err != nil {
if e.IsErrUniqueConstraint(err) {
return e.New(http.StatusConflict, "已提交过report请勿重复提交")
}
logger.Warn("add report error", "error", err)
return e.New(http.StatusInternalServerError, e.Internal)
}
return nil
}
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")
if err != nil && err != sql.ErrNoRows {
logger.Warn("get reports error", "error", err)
return nil, e.New(http.StatusInternalServerError, e.Internal)
}
if err == sql.ErrNoRows {
return reports, nil
}
for rows.Next() {
r := &models.Report{
Reporter: &models.UserSimple{},
}
var uid string
err := rows.Scan(&r.ID, &r.TargetID, &uid, &r.Status, &r.Created)
if err != nil {
logger.Warn("scan report error", "error", err)
continue
}
r.Reporter.ID = uid
r.Reporter.Query()
reports = append(reports, r)
}
sort.Sort(reports)
return reports, nil
}

@ -2,7 +2,6 @@ package api
import (
"encoding/json"
"fmt"
"net/http"
"github.com/asaskevich/govalidator"
@ -77,7 +76,6 @@ type ReportReq struct {
func SubmitReport(c *gin.Context) {
req := &ReportReq{}
c.Bind(&req)
fmt.Println(*req)
u := user.CurrentUser(c)
err := admin.AddReport(req.TargetID, req.Content, u.ID)
@ -88,3 +86,19 @@ func SubmitReport(c *gin.Context) {
c.JSON(http.StatusOK, common.RespSuccess(nil))
}
func GetReports(c *gin.Context) {
currentUser := user.CurrentUser(c)
if !currentUser.Role.IsAdmin() {
c.JSON(http.StatusForbidden, common.RespError(e.NoPermission))
return
}
res, err := admin.GetReports(1)
if err != nil {
c.JSON(err.Status, common.RespError(err.Message))
return
}
c.JSON(http.StatusOK, common.RespSuccess(res))
}

@ -151,6 +151,7 @@ func (s *Server) Start() error {
r.POST("/admin/user", IsLogin(), api.AdminSubmitUser)
r.GET("/admin/user/all", IsLogin(), api.AdminGetUsers)
r.GET("/admin/config", IsLogin(), api.AdminConfig)
r.GET("/admin/reports", IsLogin(), api.GetReports)
// notification apis
r.GET("/notifications/list/:type", IsLogin(), api.GetNotifications)
r.GET("/notifications/unread", IsLogin(), api.GetUnread)
@ -166,6 +167,7 @@ func (s *Server) Start() error {
r.POST("/sidebar", IsLogin(), SubmitSidebar)
r.POST("/report", IsLogin(), api.SubmitReport)
err := router.Run(config.Data.Server.Addr)
if err != nil {
logger.Crit("start backend server error", "error", err)

@ -287,6 +287,7 @@ var sqlTables = map[string]string{
created DATETIME
);`,
"report": `CREATE TABLE IF NOT EXISTS report (
id INTEGER PRIMARY KEY AUTOINCREMENT,
target_id VARCHAR(255),
type VARCHAR(1) NOT NULL,
reporter VARCHAR(255) NOT NULL,

@ -0,0 +1,19 @@
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"`
}
type Reports []*Report
func (t Reports) Len() int { return len(t) }
func (t Reports) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
func (t Reports) Less(i, j int) bool {
return t[i].Created.Unix() > t[j].Created.Unix()
}

@ -12,6 +12,7 @@ import CommentEditor from "./editor"
import { requestApi } from "utils/axios/request"
import Reply from "./reply"
import Link from "next/link"
import Report from "components/report"
interface Props {
user: User
@ -21,6 +22,7 @@ interface Props {
export const CommentCard = (props: Props) => {
const { comment, user, onChange} = props
const [editorVisible, setEditorVisible] = useState(false)
const [report,setReport] = useState(false)
const [replyVisible,setReplyVisible] = useState(false)
const [reply,setReply] = useState('')
@ -87,11 +89,13 @@ export const CommentCard = (props: Props) => {
<MenuList>
{user && <MenuItem onClick={() => setEditorVisible(true)}><FaRegEdit /><chakra.span ml="2">Edit</chakra.span></MenuItem>}
{user && <MenuItem onClick={() => deleteComment(comment.id)}><FaRegTrashAlt /><chakra.span ml="2">Delete</chakra.span></MenuItem>}
<MenuItem><FaRegFlag /><chakra.span ml="2">Report</chakra.span></MenuItem>
<MenuItem onClick={() => setReport(true)}><FaRegFlag /><chakra.span ml="2">Report</chakra.span></MenuItem>
</MenuList>
</Menu>
</HStack>
</Flex>
{report && <Report targetID={comment.id} onClose={() => setReport(false)}/>}
{replyVisible && <Box pl="16" pr="2"><CommentEditor menu={false} user={user} md={reply} onSubmit={md => {submitReply(md)}} onCancel={() => setReplyVisible(false)} /></Box>}

@ -11,6 +11,7 @@ import { User } from "src/types/user"
import CommentEditor from "./editor"
import { requestApi } from "utils/axios/request"
import Link from "next/link"
import Report from "components/report"
interface Props {
user: User
@ -21,7 +22,8 @@ interface Props {
export const Reply = (props: Props) => {
const { comment, user,onChange,parent} = props
const [editorVisible, setEditorVisible] = useState(false)
const [report,setReport] = useState(false)
const [replyVisible,setReplyVisible] = useState(false)
const [reply,setReply] = useState('')
const submitReply = async (md) => {
@ -102,11 +104,13 @@ export const Reply = (props: Props) => {
<MenuList>
{user && <MenuItem onClick={() => setEditorVisible(true)}><FaRegEdit /><chakra.span ml="2">Edit</chakra.span></MenuItem>}
{user && <MenuItem onClick={() => deleteReply(comment.id)}><FaRegTrashAlt /><chakra.span ml="2">Delete</chakra.span></MenuItem>}
<MenuItem><FaRegFlag /><chakra.span ml="2">Report</chakra.span></MenuItem>
<MenuItem onClick={()=> setReport(true)}><FaRegFlag /><chakra.span ml="2">Report</chakra.span></MenuItem>
</MenuList>
</Menu>
</HStack>
</Flex>
{report && <Report targetID={comment.id} onClose={() => setReport(false)}/>}
{replyVisible &&
<Box pl="16" pr="2">

@ -1,6 +1,6 @@
import { getSvgIcon } from 'components/svg-icon'
import React from 'react'
import { FaFileAlt, FaScroll, FaBookOpen, FaTags, FaUserCircle, FaRegFile, FaUser, FaRegUser, FaUserFriends, FaElementor } from 'react-icons/fa'
import { FaFileAlt, FaScroll, FaBookOpen, FaTags, FaUserCircle, FaRegFile, FaUser, FaRegUser, FaUserFriends, FaElementor, FaBug } from 'react-icons/fa'
import { Route } from 'src/types/route'
import { SearchFilter } from 'src/types/search'
import { ReserveUrls } from './reserve-urls'
@ -93,6 +93,12 @@ export const adminLinks: Route[] = [{
icon: <FaElementor />,
disabled: false
},
{
title: 'Report处理',
path: `${ReserveUrls.Admin}/report`,
icon: <FaBug />,
disabled: false
},
]

Loading…
Cancel
Save