import React, { useCallback, useEffect, useState } from 'react';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import Paper from '@mui/material/Paper';
import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import Button from '@mui/material/Button';
import Chip from '@mui/material/Chip';
import IconButton from '@mui/material/IconButton';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import RefreshIcon from '@mui/icons-material/Refresh';
import CheckIcon from '@mui/icons-material/Check';
import CloseIcon from '@mui/icons-material/Close';
import DeleteIcon from '@mui/icons-material/Delete';
import { listPendingComments, listAllComments, approveComment, rejectComment, deleteComment } from '../../api/blog.js';
import { showSnack } from '../snack.jsx';
const PAGE_SIZE = 20;
/** 时间格式化:yyyy-mm-dd hh:mm */
function fmtTime(t) {
if (!t) return '';
return String(t).replace('T', ' ').slice(0, 16);
}
/** 内容截断(单行预览):换行折叠 + 超长省略 */
function clip(content, max = 60) {
const s = String(content || '').replace(/\s+/g, ' ').trim();
return s.length > max ? s.slice(0, max) + '…' : s;
}
/** 状态 chip */
function StatusChip({ status }) {
if (status === 'approved') return ;
if (status === 'rejected') return ;
return ;
}
/** 评论管理:待审核队列 + 全部评论分页列表(status=all) */
export default function CommentManage() {
const [tab, setTab] = useState(0);
const [pending, setPending] = useState([]);
const [busy, setBusy] = useState(false);
// 全部评论(分页)
const [allList, setAllList] = useState([]);
const [allPage, setAllPage] = useState(1);
const [allTotal, setAllTotal] = useState(0);
const [allTotalPages, setAllTotalPages] = useState(0);
const [allLoading, setAllLoading] = useState(false);
const load = useCallback(() => {
setBusy(true);
listPendingComments()
.then((list) => setPending(list || []))
.catch((e) => showSnack(e.message, 'error'))
.finally(() => setBusy(false));
}, []);
useEffect(() => { load(); }, [load]);
const loadAll = useCallback((page) => {
setAllLoading(true);
listAllComments({ status: 'all', page, pageSize: PAGE_SIZE })
.then((res) => {
setAllList((res && res.list) || []);
setAllTotal(res ? res.total || 0 : 0);
setAllTotalPages(res ? res.totalPages || 0 : 0);
setAllPage(page);
})
.catch((e) => showSnack(e.message, 'error'))
.finally(() => setAllLoading(false));
}, []);
useEffect(() => {
if (tab === 1) loadAll(1);
}, [tab, loadAll]);
const act = async (id, fn, okMsg) => {
setBusy(true);
try {
await fn(id);
setPending((list) => list.filter((c) => c.id !== id));
showSnack(okMsg);
} catch (e) {
showSnack(e.message, 'error');
}
setBusy(false);
};
const actAll = async (id, fn, okMsg, reloadPage = allPage) => {
setBusy(true);
try {
await fn(id);
showSnack(okMsg);
// 同步待审核徽标 + 刷新当前页;若删除后本页空且非第一页则回退一页
setPending((list) => list.filter((c) => c.id !== id));
const remaining = allList.filter((c) => c.id !== id).length;
loadAll(remaining === 0 && reloadPage > 1 ? reloadPage - 1 : reloadPage);
} catch (e) {
showSnack(e.message, 'error');
}
setBusy(false);
};
const totalPages = Math.max(1, allTotalPages);
return (
评论管理
(tab === 0 ? load() : loadAll(allPage))} title="刷新" disabled={busy || allLoading}>
setTab(v)}>
{tab === 0 ? (
pending.length === 0 ? (
暂无待审核评论
开启「评论审核模式」后,新评论会先进这里等待审核
) : (
{pending.map((c) => (
{c.author_name || '匿名'}
{fmtTime(c.created_at)}
{c.content}
}
disabled={busy}
onClick={() => act(c.id, approveComment, '已通过审核')}
>通过
}
disabled={busy}
onClick={() => act(c.id, rejectComment, '已拒绝')}
>拒绝
))}
)
) : (
<>
作者
文章
内容
状态
时间
操作
{allLoading && allList.length === 0 ? (
加载中...
) : allList.length === 0 ? (
暂无评论
) : allList.map((c) => (
{c.author_name || '匿名'}
{c.post_title || `#${c.post_id}`}
{clip(c.content)}
{fmtTime(c.created_at)}
{c.status === 'pending' && (
<>
} disabled={busy} onClick={() => actAll(c.id, approveComment, '已通过审核')}>通过
} disabled={busy} onClick={() => actAll(c.id, rejectComment, '已拒绝')}>拒绝
>
)}
actAll(c.id, deleteComment, '已删除')}>
))}
第 {allPage} / {totalPages} 页 · 共 {allTotal} 条
>
)}
);
}