From 94172ab78261665b2d6e677cdc191844d10506ef Mon Sep 17 00:00:00 2001 From: anghunk Date: Tue, 20 Jan 2026 21:30:03 +0800 Subject: [PATCH] =?UTF-8?q?feat(admin):=20=E5=A2=9E=E5=BC=BA=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E5=8A=9F=E8=83=BD=E5=B9=B6=E6=B7=BB=E5=8A=A0=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E7=AB=AF=E5=93=8D=E5=BA=94=E5=BC=8F=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在评论管理页面添加完整的分页控件,包括页码跳转和省略号显示 - 实现移动端侧边栏菜单和操作按钮的响应式布局 - 添加移动端菜单切换和操作下拉菜单功能 - 更新文档配置和快速开始页面结构 --- cwd-comments-admin/src/views/CommentsView.vue | 129 ++++++++- cwd-comments-admin/src/views/LayoutView.vue | 253 ++++++++++++++++-- docs/.vitepress/config.mjs | 4 +- docs/guide/getting-started.md | 2 + 4 files changed, 363 insertions(+), 25 deletions(-) diff --git a/cwd-comments-admin/src/views/CommentsView.vue b/cwd-comments-admin/src/views/CommentsView.vue index 8695790..86428e0 100644 --- a/cwd-comments-admin/src/views/CommentsView.vue +++ b/cwd-comments-admin/src/views/CommentsView.vue @@ -100,9 +100,49 @@ > 上一页 - {{ pagination.page }} / {{ pagination.total }} + 1 + + + ... + + + + ... + + +
+ 跳转到 + + + +
@@ -130,6 +183,7 @@ const pagination = ref<{ page: number; total: number }>({ page: 1, total: 1 }); const loading = ref(false); const error = ref(""); const statusFilter = ref(""); +const jumpPageInput = ref(""); const filteredComments = computed(() => { if (!statusFilter.value) { @@ -138,6 +192,29 @@ const filteredComments = computed(() => { return comments.value.filter((item) => item.status === statusFilter.value); }); +const visiblePages = computed(() => { + const total = pagination.value.total; + const current = pagination.value.page; + const maxVisible = 5; + if (total <= maxVisible) { + return Array.from({ length: total }, (_, index) => index + 1); + } + let start = current - Math.floor(maxVisible / 2); + let end = current + Math.floor(maxVisible / 2); + if (start < 1) { + start = 1; + end = maxVisible; + } else if (end > total) { + end = total; + start = total - maxVisible + 1; + } + const pages: number[] = []; + for (let i = start; i <= end; i += 1) { + pages.push(i); + } + return pages; +}); + function formatDate(value: number) { const d = new Date(value); if (Number.isNaN(d.getTime())) { @@ -181,6 +258,19 @@ async function goPage(page: number) { await loadComments(page); } +function handleJumpPage() { + const value = Number(jumpPageInput.value); + if (!Number.isFinite(value)) { + return; + } + const page = Math.floor(value); + if (page < 1 || page > pagination.value.total) { + return; + } + jumpPageInput.value = ""; + loadComments(page); +} + async function changeStatus(item: CommentItem, status: string) { try { await updateCommentStatus(item.id, status); @@ -269,12 +359,12 @@ onMounted(() => { border: 1px solid #d0d7de; border-radius: 6px; overflow: hidden; + overflow-x: auto; } .table-header { display: flex; background-color: #f6f8fa; - border-bottom: 1px solid #d0d7de; } .table-row { @@ -347,6 +437,8 @@ onMounted(() => { font-weight: 500; color: #57606a; align-items: center; + background-color: #f6f8fa; + border-bottom: 1px solid #d0d7de; } .cell-id { @@ -474,7 +566,7 @@ onMounted(() => { } .pagination { - margin-top: 20px; + margin-top: 30px; display: flex; align-items: center; gap: 8px; @@ -494,8 +586,33 @@ onMounted(() => { cursor: not-allowed; } -.pagination-info { - font-size: 13px; +.pagination-button-active { + background-color: #0969da; + color: #ffffff; + border-color: #0969da; +} + +.pagination-ellipsis { + padding: 0 2px; + font-size: 12px; color: #57606a; } + +.pagination-jump { + display: flex; + align-items: center; + gap: 4px; + font-size: 12px; + color: #57606a; +} + +.pagination-input { + width: 60px; + height: 24px; + box-sizing: border-box; + padding: 2px 4px; + border-radius: 4px; + border: 1px solid #d0d7de; + font-size: 12px; +} diff --git a/cwd-comments-admin/src/views/LayoutView.vue b/cwd-comments-admin/src/views/LayoutView.vue index 20ae48e..297dd41 100644 --- a/cwd-comments-admin/src/views/LayoutView.vue +++ b/cwd-comments-admin/src/views/LayoutView.vue @@ -1,27 +1,61 @@ @@ -104,6 +182,13 @@ function handleLogout() { font-weight: 600; } +.layout-actions-wrapper { + display: flex; + align-items: center; + gap: 8px; + position: relative; +} + .layout-actions { display: flex; gap: 8px; @@ -124,6 +209,22 @@ function handleLogout() { background-color: #32383f; } +.layout-actions-toggle { + display: none; + align-items: center; + justify-content: center; + padding: 6px; + border-radius: 4px; + border: 1px solid #57606a; + background-color: #24292f; + color: #ffffff; + cursor: pointer; +} + +.layout-actions-dropdown { + display: none; +} + .layout-body { display: flex; flex: 1; @@ -160,7 +261,125 @@ function handleLogout() { .layout-content { flex: 1; - padding: 16px 20px; + padding: 16px 20px 40px; overflow: auto; } + +.layout-menu-toggle { + display: none; + align-items: center; + justify-content: center; + padding: 6px 10px; + border-radius: 4px; + border: 1px solid #57606a; + background-color: #24292f; + color: #ffffff; + cursor: pointer; + font-size: 13px; +} + +.layout-sider-mask { + display: none; +} + +@media (max-width: 768px) { + .layout { + height: 100vh; + } + + .layout-header { + padding: 0 12px; + gap: 8px; + } + + .layout-title { + font-size: 16px; + } + + .layout-body { + position: relative; + } + + .layout-menu-toggle { + display: inline-flex; + } + + .layout-sider { + position: fixed; + top: 56px; + left: 0; + bottom: 0; + width: 220px; + max-width: 80%; + border-right: 1px solid #d0d7de; + transform: translateX(-100%); + transition: transform 0.2s ease-out; + z-index: 1000; + } + + .layout-sider-mobile-open { + transform: translateX(0); + } + + .layout-sider-mask { + position: fixed; + top: 56px; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.3); + z-index: 900; + display: block; + } + + .layout-content { + padding: 12px; + } + + .layout-actions { + display: none; + } + + .layout-actions-toggle { + display: inline-flex; + } + + .layout-actions-dropdown { + position: fixed; + top: 56px; + right: 12px; + background-color: #ffffff; + border: 1px solid #d0d7de; + border-radius: 6px; + box-shadow: 0 8px 24px rgba(140, 149, 159, 0.3); + padding: 6px 0; + min-width: 160px; + z-index: 1100; + display: flex; + flex-direction: column; + } + + .layout-actions-item { + padding: 8px 14px; + font-size: 13px; + background: none; + border: none; + text-align: left; + cursor: pointer; + color: #24292f; + width: 100%; + } + + .layout-actions-item:hover { + background-color: #f6f8fa; + } + + .layout-actions-item-danger { + color: #d1242f; + } + + .layout-actions-item-danger:hover { + background-color: #ffebe9; + } +} diff --git a/docs/.vitepress/config.mjs b/docs/.vitepress/config.mjs index 7c60129..7c4b9ca 100644 --- a/docs/.vitepress/config.mjs +++ b/docs/.vitepress/config.mjs @@ -26,9 +26,9 @@ export default defineConfig({ sidebar: [ { - text: '配置', + text: '快速开始', items: [ - { text: '快速开始', link: '/guide/getting-started' }, + { text: '项目介绍', link: '/guide/getting-started' }, { text: '后端配置', link: '/guide/backend-config' }, { text: '前端配置', link: '/guide/frontend-config' }, ], diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md index 9abb3c5..66e4fa6 100644 --- a/docs/guide/getting-started.md +++ b/docs/guide/getting-started.md @@ -7,6 +7,8 @@ Cloudflare Worker 版本基于 Cloudflare Workers + D1 + KV 实现,无需服 [文档地址](https://cwd-comments-docs.zishu.me) +![](https://github.com/user-attachments/assets/6ac091d8-e349-4d40-9d68-485817f63236) + ## 特性 - ⚡️ **极速响应**:基于 Cloudflare 全球边缘网络