优化会员管理页面样式 - 使用原生表格替代Element Plus表格,实现更简洁的设计

This commit is contained in:
AIGC Developer
2025-10-22 09:40:33 +08:00
parent 4b7604f20c
commit 9f167aa20f

View File

@@ -85,53 +85,63 @@
</div>
<div class="table-container">
<el-table
:data="memberList"
@selection-change="handleSelectionChange"
class="member-table">
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="用户ID" width="100" />
<el-table-column prop="username" label="用户名" width="120" />
<el-table-column prop="level" label="会员等级" width="120">
<template #default="{ row }">
<el-tag :type="row.level === '专业会员' ? 'danger' : 'primary'" size="small">
{{ row.level }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="points" label="剩余资源点" width="140">
<template #default="{ row }">
{{ row.points.toLocaleString() }}
</template>
</el-table-column>
<el-table-column prop="expiryDate" label="到期时间" width="120" />
<el-table-column label="编辑" width="80">
<template #default="{ row }">
<el-button type="primary" text size="small" @click="editMember(row)">
编辑
</el-button>
</template>
</el-table-column>
<el-table-column label="删除" width="80">
<template #default="{ row }">
<el-button type="danger" text size="small" @click="deleteMember(row)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<table class="member-table">
<thead>
<tr>
<th class="checkbox-col">
<input type="checkbox" @change="toggleAllSelection" :checked="isAllSelected" />
</th>
<th>用户ID</th>
<th>用户名</th>
<th>会员等级</th>
<th>剩余资源点</th>
<th>到期时间</th>
<th>编辑</th>
<th>删除</th>
</tr>
</thead>
<tbody>
<tr v-for="member in memberList" :key="member.id" class="table-row">
<td class="checkbox-col">
<input
type="checkbox"
:checked="selectedMembers.some(m => m.id === member.id)"
@change="toggleMemberSelection(member)" />
</td>
<td>{{ member.id }}</td>
<td>{{ member.username }}</td>
<td>
<span class="level-tag" :class="member.level === '专业会员' ? 'professional' : 'standard'">
{{ member.level }}
</span>
</td>
<td>{{ member.points.toLocaleString() }}</td>
<td>{{ member.expiryDate }}</td>
<td>
<button class="action-btn edit-btn" @click="editMember(member)">编辑</button>
</td>
<td>
<button class="action-btn delete-btn" @click="deleteMember(member)">删除</button>
</td>
</tr>
</tbody>
</table>
</div>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination
v-model:current-page="currentPage"
:page-size="pageSize"
:total="totalMembers"
layout="prev, pager, next"
:pager-count="5"
@current-change="handlePageChange"
/>
<div class="pagination">
<button class="page-btn" @click="prevPage" :disabled="currentPage === 1"></button>
<button
v-for="page in visiblePages"
:key="page"
class="page-btn"
:class="{ active: page === currentPage }"
@click="goToPage(page)">
{{ page }}
</button>
<button class="page-btn" @click="nextPage" :disabled="currentPage === totalPages"></button>
</div>
</div>
</section>
</main>
@@ -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 {