优化会员管理页面样式 - 使用原生表格替代Element Plus表格,实现更简洁的设计
This commit is contained in:
@@ -85,53 +85,63 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-container">
|
<div class="table-container">
|
||||||
<el-table
|
<table class="member-table">
|
||||||
:data="memberList"
|
<thead>
|
||||||
@selection-change="handleSelectionChange"
|
<tr>
|
||||||
class="member-table">
|
<th class="checkbox-col">
|
||||||
<el-table-column type="selection" width="55" />
|
<input type="checkbox" @change="toggleAllSelection" :checked="isAllSelected" />
|
||||||
<el-table-column prop="id" label="用户ID" width="100" />
|
</th>
|
||||||
<el-table-column prop="username" label="用户名" width="120" />
|
<th>用户ID</th>
|
||||||
<el-table-column prop="level" label="会员等级" width="120">
|
<th>用户名</th>
|
||||||
<template #default="{ row }">
|
<th>会员等级</th>
|
||||||
<el-tag :type="row.level === '专业会员' ? 'danger' : 'primary'" size="small">
|
<th>剩余资源点</th>
|
||||||
{{ row.level }}
|
<th>到期时间</th>
|
||||||
</el-tag>
|
<th>编辑</th>
|
||||||
</template>
|
<th>删除</th>
|
||||||
</el-table-column>
|
</tr>
|
||||||
<el-table-column prop="points" label="剩余资源点" width="140">
|
</thead>
|
||||||
<template #default="{ row }">
|
<tbody>
|
||||||
{{ row.points.toLocaleString() }}
|
<tr v-for="member in memberList" :key="member.id" class="table-row">
|
||||||
</template>
|
<td class="checkbox-col">
|
||||||
</el-table-column>
|
<input
|
||||||
<el-table-column prop="expiryDate" label="到期时间" width="120" />
|
type="checkbox"
|
||||||
<el-table-column label="编辑" width="80">
|
:checked="selectedMembers.some(m => m.id === member.id)"
|
||||||
<template #default="{ row }">
|
@change="toggleMemberSelection(member)" />
|
||||||
<el-button type="primary" text size="small" @click="editMember(row)">
|
</td>
|
||||||
编辑
|
<td>{{ member.id }}</td>
|
||||||
</el-button>
|
<td>{{ member.username }}</td>
|
||||||
</template>
|
<td>
|
||||||
</el-table-column>
|
<span class="level-tag" :class="member.level === '专业会员' ? 'professional' : 'standard'">
|
||||||
<el-table-column label="删除" width="80">
|
{{ member.level }}
|
||||||
<template #default="{ row }">
|
</span>
|
||||||
<el-button type="danger" text size="small" @click="deleteMember(row)">
|
</td>
|
||||||
删除
|
<td>{{ member.points.toLocaleString() }}</td>
|
||||||
</el-button>
|
<td>{{ member.expiryDate }}</td>
|
||||||
</template>
|
<td>
|
||||||
</el-table-column>
|
<button class="action-btn edit-btn" @click="editMember(member)">编辑</button>
|
||||||
</el-table>
|
</td>
|
||||||
|
<td>
|
||||||
|
<button class="action-btn delete-btn" @click="deleteMember(member)">删除</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<div class="pagination-container">
|
<div class="pagination-container">
|
||||||
<el-pagination
|
<div class="pagination">
|
||||||
v-model:current-page="currentPage"
|
<button class="page-btn" @click="prevPage" :disabled="currentPage === 1">‹</button>
|
||||||
:page-size="pageSize"
|
<button
|
||||||
:total="totalMembers"
|
v-for="page in visiblePages"
|
||||||
layout="prev, pager, next"
|
:key="page"
|
||||||
:pager-count="5"
|
class="page-btn"
|
||||||
@current-change="handlePageChange"
|
:class="{ active: page === currentPage }"
|
||||||
/>
|
@click="goToPage(page)">
|
||||||
|
{{ page }}
|
||||||
|
</button>
|
||||||
|
<button class="page-btn" @click="nextPage" :disabled="currentPage === totalPages">›</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
@@ -188,8 +198,56 @@ const goToSettings = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 表格操作
|
// 表格操作
|
||||||
const handleSelectionChange = (selection) => {
|
const isAllSelected = computed(() => {
|
||||||
selectedMembers.value = selection
|
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) => {
|
const editMember = (member) => {
|
||||||
@@ -456,13 +514,92 @@ onMounted(() => {
|
|||||||
|
|
||||||
.table-container {
|
.table-container {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 12px;
|
border-radius: 8px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||||
|
margin-bottom: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.member-table {
|
.member-table {
|
||||||
width: 100%;
|
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 {
|
.pagination-container {
|
||||||
@@ -471,6 +608,39 @@ onMounted(() => {
|
|||||||
margin-top: 24px;
|
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) {
|
@media (max-width: 1024px) {
|
||||||
.member-management {
|
.member-management {
|
||||||
|
|||||||
Reference in New Issue
Block a user