feat: 完成TikTok短剧管理后台基础功能开发

本次提交搭建了完整的后台管理系统,包含:
1.  登录认证与权限校验体系
2.  工作台、短剧、用户、角色、人员、日志等全业务模块
3.  响应式布局与通用样式组件
4.  菜单动态过滤与路由权限控制
5.  移除了README中冗余的权限管理菜单项
This commit is contained in:
2026-07-01 15:24:13 +08:00
parent 6722752d5e
commit 51e26025c6
27 changed files with 1364 additions and 1282 deletions

28
src/Dashboard/index.css Normal file
View File

@@ -0,0 +1,28 @@
.page-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 16px;
margin-bottom: 16px;
}
.metric-card .label {
color: #86909c;
margin-bottom: 8px;
}
.metric-card .value {
font-size: 28px;
font-weight: 700;
}
@media (max-width: 900px) {
.page-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (max-width: 640px) {
.page-grid {
grid-template-columns: 1fr;
}
}

40
src/Dashboard/index.tsx Normal file
View File

@@ -0,0 +1,40 @@
import { Card } from '@arco-design/web-react';
import type { AdminProfile, AppUser, Drama, RequestLog } from '../api/types';
import { usePageData } from '../hooks/usePageData';
import { hasPermissions } from '../utils/permission';
import { NoAccessPage } from '../components/NoAccessPage';
import { RequestLogTable } from '../components/RequestLogTable';
import './index.css';
function MetricCard({ label, value }: { label: string; value: number | string }) {
return <Card className="metric-card"><div className="label">{label}</div><div className="value">{value}</div></Card>;
}
function DashboardPage({ profile }: { profile: AdminProfile | null }) {
const canReadDramas = hasPermissions(profile, ['drama:read']);
const canReadUsers = hasPermissions(profile, ['user:read']);
const canReadLogs = hasPermissions(profile, ['log:read']);
const dramas = usePageData<Drama>('/api/admin/v1/dramas', canReadDramas);
const users = usePageData<AppUser>('/api/admin/v1/users', canReadUsers);
const logs = usePageData<RequestLog>('/api/admin/v1/logs/requests', canReadLogs);
const hasAnyDataModule = canReadDramas || canReadUsers || canReadLogs;
return (
<>
<div className="page-grid">
{canReadDramas && <MetricCard label="短剧管理" value={dramas.data.pagination.total} />}
{canReadUsers && <MetricCard label="用户管理" value={users.data.pagination.total} />}
{canReadLogs && <MetricCard label="请求日志" value={logs.data.pagination.total} />}
<MetricCard label="接口状态" value="运行中" />
</div>
{canReadLogs ? (
<Card className="section-card" title="最近请求">
<RequestLogTable data={logs.data.list.slice(0, 8)} loading={logs.loading} />
</Card>
) : null}
{!hasAnyDataModule ? <NoAccessPage /> : null}
</>
);
}
export default DashboardPage;