fix: 优化后台工单工作区布局

This commit is contained in:
2026-09-05 02:57:38 +08:00
parent 8e890d9a96
commit e7bb30b4bd
3 changed files with 80 additions and 9 deletions
+1 -1
View File
@@ -304,7 +304,7 @@ export default function AdminLayout() {
)}
</Box>
<Box component="main" sx={{ flexGrow: 1, p: { xs: 2, md: 3 }, minWidth: 0 }}>
<Box component="main" sx={{ flex: '1 1 auto', width: { xs: '100%', md: 'calc(100vw - 240px)' }, maxWidth: { xs: '100%', md: 'calc(100vw - 240px)' }, boxSizing: 'border-box', p: { xs: 2, md: 3 }, minWidth: 0, overflowX: 'hidden' }}>
{/* AppBar 占位:桌面 64 / 移动 56 + 搜索行 48 */}
<Box sx={{ height: isMobile ? 104 : 64 }} />
<Outlet />
+8 -8
View File
@@ -146,13 +146,13 @@ export default function TicketManage() {
], [stats, total]);
return (
<Box component="main" aria-labelledby="ticket-page-title">
<Box component="main" className="ticket-workspace" aria-labelledby="ticket-page-title">
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ mb: 2 }}>
<Box><Typography id="ticket-page-title" variant="h5" component="h1">工单管理</Typography><Typography variant="body2" color="text.secondary">集中处理论坛和站内问题反馈</Typography></Box>
<IconButton aria-label="刷新工单" title="刷新" onClick={refresh} disabled={loading || saving}><RefreshIcon /></IconButton>
</Stack>
<Stack direction="row" spacing={1.25} useFlexGap flexWrap="wrap" sx={{ mb: 2 }}>
<Stack className="ticket-stats" direction="row" spacing={1.25} useFlexGap flexWrap="wrap" sx={{ mb: 2 }}>
{statItems.map(([label, value, tone]) => <StatCard key={label} label={label} value={value} tone={tone} />)}
</Stack>
@@ -167,8 +167,8 @@ export default function TicketManage() {
</Paper>
{error && <Alert severity="error" role="alert" action={<Button color="inherit" size="small" onClick={loadList}>重试</Button>} sx={{ mb: 2 }}>{error}</Alert>}
<Grid container spacing={2} alignItems="stretch">
<Grid item xs={12} lg={5} sx={{ minWidth: 0 }}>
<Box className="ticket-work-area">
<Box className="ticket-list-pane">
<Paper variant="outlined" sx={{ height: '100%', overflow: 'hidden' }}>
<Box sx={{ p: 1.5, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}><Typography variant="subtitle1" fontWeight={700}>最近工单</Typography><Typography variant="caption" color="text.secondary"> {total} </Typography></Box>
<Divider />
@@ -179,9 +179,9 @@ export default function TicketManage() {
)}
<Stack direction="row" alignItems="center" justifyContent="center" spacing={1} sx={{ p: 1.25 }}><IconButton aria-label="上一页" size="small" disabled={page <= 1 || loading} onClick={() => setPage(page - 1)}><NavigateBeforeIcon /></IconButton><Typography variant="caption"> {page} / {totalPages} </Typography><IconButton aria-label="下一页" size="small" disabled={page >= totalPages || loading} onClick={() => setPage(page + 1)}><NavigateNextIcon /></IconButton></Stack>
</Paper>
</Grid>
</Box>
<Grid item xs={12} lg={7} sx={{ minWidth: 0 }}>
<Box className="ticket-detail-pane">
<Paper variant="outlined" sx={{ p: { xs: 2, md: 2.5 }, minHeight: 420 }}>
{!selectedId ? <Box sx={{ py: 10, textAlign: 'center' }}><Typography variant="h6" color="text.secondary">选择一个工单开始处理</Typography><Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>工单详情回复和状态操作会显示在这里</Typography></Box> : detailLoading ? <Box role="status" aria-label="正在加载工单详情" sx={{ py: 10, textAlign: 'center' }}><CircularProgress /></Box> : selectedTicket ? (
<Stack spacing={2}>
@@ -194,8 +194,8 @@ export default function TicketManage() {
</Stack>
) : <Alert severity="error">工单详情不存在或加载失败</Alert>}
</Paper>
</Grid>
</Grid>
</Box>
</Box>
</Box>
);
}
+71
View File
@@ -32,6 +32,77 @@ body {
[data-theme="dark"] ::-webkit-scrollbar-thumb { background: #49454f; }
[data-theme="dark"] ::-webkit-scrollbar-thumb:hover { background: #938f99; }
/* 工单工作区:占满 AdminLayout 内容区,桌面保持列表/详情主次比例。 */
.ticket-workspace {
width: 100%;
max-width: none;
min-width: 0;
min-height: calc(100vh - 112px);
}
.ticket-workspace .ticket-stats {
width: 100%;
}
.ticket-work-area {
display: grid;
grid-template-columns: minmax(280px, 0.55fr) minmax(0, 1fr);
gap: 16px;
width: 100%;
min-width: 0;
min-height: calc(100vh - 280px);
align-items: stretch;
}
.ticket-list-pane,
.ticket-detail-pane {
min-width: 0;
width: 100%;
}
.ticket-list-pane > .MuiPaper-root,
.ticket-detail-pane > .MuiPaper-root {
width: 100%;
min-width: 0;
box-sizing: border-box;
}
.ticket-list-pane > .MuiPaper-root {
min-height: calc(100vh - 280px);
}
.ticket-detail-pane > .MuiPaper-root {
min-height: calc(100vh - 280px);
}
@media (max-width: 1199px) and (min-width: 700px) {
.ticket-work-area {
grid-template-columns: minmax(250px, 0.62fr) minmax(0, 1fr);
gap: 14px;
}
}
@media (max-width: 699px) {
.ticket-workspace {
min-height: 0;
}
.ticket-work-area {
grid-template-columns: minmax(0, 1fr);
min-height: 0;
gap: 16px;
}
.ticket-list-pane > .MuiPaper-root,
.ticket-detail-pane > .MuiPaper-root {
min-height: 0;
}
.ticket-detail-pane > .MuiPaper-root {
min-height: 480px;
}
}
/* 减弱动效偏好 */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {