fix:将侧边栏兼容移动端

This commit is contained in:
2026-01-20 17:54:45 +08:00
parent 0b57581799
commit e3e70114fb
18 changed files with 3059 additions and 316 deletions
+340 -52
View File
@@ -4,35 +4,42 @@
<el-card class="main-container" shadow="never">
<!-- 搜索和操作栏 -->
<div class="filter-section">
<div class="filter-content">
<el-form :inline="true" :model="queryParams" class="search-form">
<el-form-item label="关键字">
<el-input v-model="queryParams.key" placeholder="请输入用户名/邮箱" clearable style="width: 200px" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery">
<el-icon><Search /></el-icon>查询
</el-button>
<el-button @click="resetQuery">重置</el-button>
<el-button type="success" @click="fetchUserList">
<el-icon><Refresh /></el-icon>刷新
</el-button>
</el-form-item>
<el-form-item label="用户ID">
<el-input
v-model="jumpUserId"
placeholder="输入用户ID跳转"
clearable
style="width: 150px"
@keyup.enter="handleJumpToUser"
/>
</el-form-item>
<el-form-item>
<el-button type="warning" @click="handleJumpToUser">
<el-icon><Position /></el-icon>跳转
</el-button>
</el-form-item>
</el-form>
<!-- 第一行搜索区域 -->
<div class="filter-row search-row">
<div class="search-group">
<span class="search-label">关键字</span>
<el-input
v-model="queryParams.key"
placeholder="请输入用户名/邮箱"
clearable
class="search-input"
/>
</div>
<div class="search-group">
<span class="search-label">用户ID</span>
<el-input
v-model="jumpUserId"
placeholder="输入ID跳转"
clearable
class="search-input-small"
@keyup.enter="handleJumpToUser"
/>
</div>
<div class="search-buttons">
<el-button type="primary" @click="handleQuery">
<el-icon><Search /></el-icon><span class="btn-text">查询</span>
</el-button>
<el-button @click="resetQuery">重置</el-button>
<el-button type="success" @click="fetchUserList">
<el-icon><Refresh /></el-icon><span class="btn-text">刷新</span>
</el-button>
<el-button type="warning" @click="handleJumpToUser">
<el-icon><Position /></el-icon><span class="btn-text">跳转</span>
</el-button>
</div>
</div>
<!-- 第二行操作栏 -->
<div class="filter-row action-row">
<div class="action-bar">
<el-button type="primary" @click="handleAdd">
<el-icon><Plus /></el-icon>新增用户
@@ -70,12 +77,69 @@
<div class="skeleton-cell skeleton-action"></div>
</div>
</div>
<!-- 数据表格 -->
<!-- 移动端卡片列表 -->
<div v-else class="mobile-card-list">
<div v-for="row in userList" :key="row.UserId" class="user-card">
<div class="card-header">
<el-checkbox v-model="row.selected" @change="handleCardSelect(row)" />
<el-avatar :size="48" :src="row.avatarUrl || ''" class="card-avatar" />
<div class="card-user-info">
<div class="card-username">{{ row.UserName }}</div>
<div class="card-email">{{ row.Email || '未设置邮箱' }}</div>
</div>
<el-tag :type="row.IsDeleted ? 'danger' : 'success'" size="small">
{{ row.IsDeleted ? '已删除' : '正常' }}
</el-tag>
</div>
<div class="card-body">
<div class="card-info-row">
<span class="card-label">用户ID:</span>
<span class="card-value">{{ row.UserId }}</span>
</div>
<div class="card-info-row">
<span class="card-label">手机号:</span>
<span class="card-value">{{ row.Phone || '未设置' }}</span>
</div>
<div class="card-info-row">
<span class="card-label">用户组:</span>
<span class="card-value">{{ row.UserGroup?.Name || '默认用户组' }}</span>
</div>
<div class="card-info-row">
<span class="card-label">实名:</span>
<span class="card-value">{{ row.RealName?.Name || '未实名' }}</span>
</div>
<div class="card-info-row">
<span class="card-label">注册时间:</span>
<span class="card-value">{{ formatDate(row.CreatedAt) }}</span>
</div>
</div>
<div class="card-footer">
<el-button type="primary" size="small" @click="handleUserDetail(row)">详情</el-button>
<el-dropdown trigger="click" @command="(command) => handleCommand(command, row)">
<el-button size="small">更多<el-icon><ArrowDown /></el-icon></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="edit">编辑用户</el-dropdown-item>
<el-dropdown-item command="avatar">修改头像</el-dropdown-item>
<el-dropdown-item command="password">修改密码</el-dropdown-item>
<el-dropdown-item command="group">修改用户组</el-dropdown-item>
<el-dropdown-item command="realname">实名信息</el-dropdown-item>
<el-dropdown-item command="balance">余额管理</el-dropdown-item>
<el-dropdown-item command="delete" divided>删除用户</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</div>
<!-- 数据表格PC端 -->
<el-table
v-else
v-if="!loading"
:data="userList"
@selection-change="handleSelectionChange"
style="width: 100%"
class="desktop-table"
:header-cell-style="{ background: '#fafafa', color: '#333', fontWeight: 600 }"
>
<el-table-column type="selection" width="55" />
@@ -969,52 +1033,276 @@ onMounted(() => {
background: #fafbfc;
}
.filter-content {
.filter-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 20px;
gap: 20px;
padding: 12px 20px;
gap: 16px;
flex-wrap: wrap;
}
.search-form {
margin: 0;
flex: 1;
.filter-row:not(:last-child) {
border-bottom: 1px solid #ebeef5;
}
.search-row {
padding: 16px 20px;
}
.action-row {
padding: 12px 20px;
background: #fff;
}
.search-group {
display: flex;
align-items: center;
gap: 12px;
min-width: 400px;
gap: 8px;
}
.search-form :deep(.el-form-item) {
margin-bottom: 0;
}
.search-form :deep(.el-form-item__label) {
margin-right: 8px;
.search-label {
font-size: 14px;
color: #606266;
white-space: nowrap;
flex-shrink: 0;
}
.search-input {
width: 200px;
}
.search-input-small {
width: 140px;
}
.search-buttons {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.btn-text {
margin-left: 4px;
}
.action-bar {
display: flex;
gap: 12px;
flex-wrap: wrap;
}
/* 移动端卡片列表样式 */
.mobile-card-list {
display: none;
padding: 16px;
gap: 16px;
}
.user-card {
background: #fff;
border: 1px solid #e1e8ed;
padding: 16px;
margin-bottom: 12px;
}
.card-header {
display: flex;
align-items: center;
gap: 12px;
padding-bottom: 12px;
border-bottom: 1px solid #f0f2f5;
}
.card-avatar {
flex-shrink: 0;
}
@media (max-width: 768px) {
.filter-content {
.card-user-info {
flex: 1;
min-width: 0;
}
.card-username {
font-size: 16px;
font-weight: 600;
color: #2c3e50;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.card-email {
font-size: 12px;
color: #909399;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.card-body {
padding: 12px 0;
}
.card-info-row {
display: flex;
justify-content: space-between;
padding: 6px 0;
font-size: 13px;
}
.card-label {
color: #909399;
flex-shrink: 0;
}
.card-value {
color: #2c3e50;
text-align: right;
word-break: break-all;
}
.card-footer {
display: flex;
justify-content: flex-end;
gap: 8px;
padding-top: 12px;
border-top: 1px solid #f0f2f5;
}
/* PC端表格显示 */
.desktop-table {
display: table;
width: 100%;
}
/* 平板适配 */
@media (max-width: 1024px) {
.search-row {
flex-direction: column;
align-items: stretch;
gap: 12px;
}
.search-form {
min-width: 100%;
.search-group {
width: 100%;
}
.search-input,
.search-input-small {
flex: 1;
width: auto !important;
}
.search-buttons {
width: 100%;
justify-content: flex-start;
}
}
/* 移动端适配 */
@media (max-width: 768px) {
.filter-row {
padding: 12px 16px;
}
.search-row {
padding: 12px 16px;
gap: 10px;
}
.action-row {
padding: 10px 16px;
}
.search-group {
flex-direction: column;
align-items: stretch;
gap: 6px;
}
.search-label {
font-size: 13px;
}
.search-input,
.search-input-small {
width: 100% !important;
}
.search-buttons {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
width: 100%;
}
.search-buttons .el-button {
margin: 0;
width: 100%;
}
.btn-text {
display: none;
}
.action-bar {
width: 100%;
justify-content: flex-end;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
}
.action-bar .el-button {
margin: 0;
width: 100%;
}
/* 移动端显示卡片,隐藏表格 */
.mobile-card-list {
display: block;
}
.desktop-table {
display: none !important;
}
/* 分页移动端样式 */
.pagination {
flex-wrap: wrap;
justify-content: center;
gap: 8px;
padding: 12px 16px;
}
.pagination :deep(.el-pagination__sizes),
.pagination :deep(.el-pagination__jump) {
display: none;
}
}
/* 超小屏幕适配 */
@media (max-width: 480px) {
.filter-row {
padding: 10px 12px;
}
.search-buttons {
grid-template-columns: repeat(4, 1fr);
}
.search-buttons .el-button {
padding: 8px 0;
font-size: 12px;
}
.action-bar {
grid-template-columns: 1fr 1fr;
}
.action-bar .el-button {
font-size: 13px;
padding: 8px 12px;
}
}