diff --git a/demo/frontend/src/views/MemberManagement.vue b/demo/frontend/src/views/MemberManagement.vue index 31e918d..6d59ab1 100644 --- a/demo/frontend/src/views/MemberManagement.vue +++ b/demo/frontend/src/views/MemberManagement.vue @@ -85,53 +85,63 @@
- - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + 用户ID用户名会员等级剩余资源点到期时间编辑删除
+ + {{ member.id }}{{ member.username }} + + {{ member.level }} + + {{ member.points.toLocaleString() }}{{ member.expiryDate }} + + + +
- +
@@ -188,8 +198,56 @@ const goToSettings = () => { } // 表格操作 -const handleSelectionChange = (selection) => { - selectedMembers.value = selection +const isAllSelected = computed(() => { + return memberList.value.length > 0 && selectedMembers.value.length === memberList.value.length +}) + +const totalPages = computed(() => { + return Math.ceil(totalMembers.value / pageSize.value) +}) + +const visiblePages = computed(() => { + const pages = [] + const start = Math.max(1, currentPage.value - 2) + const end = Math.min(totalPages.value, start + 4) + + for (let i = start; i <= end; i++) { + pages.push(i) + } + return pages +}) + +const toggleAllSelection = () => { + if (isAllSelected.value) { + selectedMembers.value = [] + } else { + selectedMembers.value = [...memberList.value] + } +} + +const toggleMemberSelection = (member) => { + const index = selectedMembers.value.findIndex(m => m.id === member.id) + if (index > -1) { + selectedMembers.value.splice(index, 1) + } else { + selectedMembers.value.push(member) + } +} + +const prevPage = () => { + if (currentPage.value > 1) { + currentPage.value-- + } +} + +const nextPage = () => { + if (currentPage.value < totalPages.value) { + currentPage.value++ + } +} + +const goToPage = (page) => { + currentPage.value = page } const editMember = (member) => { @@ -456,13 +514,92 @@ onMounted(() => { .table-container { background: white; - border-radius: 12px; + border-radius: 8px; overflow: hidden; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + margin-bottom: 24px; } .member-table { width: 100%; + border-collapse: collapse; + font-size: 14px; +} + +.member-table thead { + background: #f8fafc; +} + +.member-table th { + padding: 12px 16px; + text-align: left; + font-weight: 600; + color: #374151; + border-bottom: 1px solid #e5e7eb; +} + +.member-table td { + padding: 12px 16px; + border-bottom: 1px solid #f3f4f6; + color: #374151; +} + +.table-row:hover { + background: #f9fafb; +} + +.checkbox-col { + width: 50px; + text-align: center; +} + +.checkbox-col input[type="checkbox"] { + width: 16px; + height: 16px; + cursor: pointer; +} + +.level-tag { + display: inline-block; + padding: 4px 12px; + border-radius: 4px; + font-size: 12px; + font-weight: 500; + color: white; +} + +.level-tag.professional { + background: #ec4899; +} + +.level-tag.standard { + background: #3b82f6; +} + +.action-btn { + background: none; + border: none; + cursor: pointer; + font-size: 14px; + padding: 4px 8px; + border-radius: 4px; + transition: all 0.2s ease; +} + +.edit-btn { + color: #3b82f6; +} + +.edit-btn:hover { + background: #eff6ff; +} + +.delete-btn { + color: #dc2626; +} + +.delete-btn:hover { + background: #fef2f2; } .pagination-container { @@ -471,6 +608,39 @@ onMounted(() => { margin-top: 24px; } +.pagination { + display: flex; + align-items: center; + gap: 8px; +} + +.page-btn { + padding: 8px 12px; + border: 1px solid #d1d5db; + background: white; + color: #374151; + cursor: pointer; + border-radius: 4px; + font-size: 14px; + transition: all 0.2s ease; +} + +.page-btn:hover:not(:disabled) { + background: #f3f4f6; + border-color: #9ca3af; +} + +.page-btn.active { + background: #3b82f6; + color: white; + border-color: #3b82f6; +} + +.page-btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + /* 响应式设计 */ @media (max-width: 1024px) { .member-management {