| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944 |
- <template>
- <div class="users-management">
- <div class="page-header">
- <h2>用户管理</h2>
- <p>管理系统用户和角色分配</p>
- </div>
- <!-- 操作栏 -->
- <div class="toolbar">
- <div class="toolbar-left">
- <el-button type="primary" @click="showCreateDialog = true">
- <el-icon><Plus /></el-icon>
- 创建用户
- </el-button>
- <!--<el-button
- type="danger"
- :disabled="selectedUsers.length === 0"
- @click="batchDelete"
- >
- <el-icon><Delete /></el-icon>
- 批量删除
- </el-button> -->
- </div>
- <div class="toolbar-right">
- <el-input
- v-model="searchKeyword"
- placeholder="搜索用户名、邮箱、姓名..."
- style="width: 300px"
- @input="handleSearch"
- >
- <template #prefix>
- <el-icon><Search /></el-icon>
- </template>
- </el-input>
- </div>
- </div>
- <!-- 用户列表 -->
- <div class="table-container">
- <el-table
- v-loading="loading"
- :data="users"
- style="width: 100%"
- @selection-change="handleSelectionChange"
- :scroll-x="true"
- >
- <el-table-column type="selection" width="55" />
- <el-table-column prop="username" label="用户信息" min-width="160" fixed="left">
- <template #default="{ row }">
- <div class="user-info">
- <el-avatar :size="28" :src="row.avatar_url">
- {{ row.username.charAt(0).toUpperCase() }}
- </el-avatar>
- <div class="user-details">
- <div class="username">{{ row.username }}</div>
- <div class="real-name" v-if="row.real_name">{{ row.real_name }}</div>
- </div>
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="email" label="邮箱" min-width="200" show-overflow-tooltip />
- <el-table-column prop="phone" label="手机号" min-width="130" />
- <el-table-column prop="roles" label="角色" min-width="140">
- <template #default="{ row }">
- <div class="roles-container">
- <el-tag
- v-if="row.roles"
- size="small"
- style="margin-right: 4px; margin-bottom: 2px;"
- >
- {{ row.roles }}
- </el-tag>
- <el-tag v-else size="small" type="info">未分配</el-tag>
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="is_superuser" label="管理员" width="80" align="center">
- <template #default="{ row }">
- <el-tag :type="row.is_superuser ? 'danger' : 'info'" size="small">
- {{ row.is_superuser ? '是' : '否' }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="is_active" label="状态" width="80" align="center">
- <template #default="{ row }">
- <el-switch
- v-model="row.is_active"
- @change="handleStatusChange(row)"
- size="small"
- />
- </template>
- </el-table-column>
- <el-table-column prop="last_login_at" label="最后登录" min-width="140">
- <template #default="{ row }">
- <div class="time-info">
- {{ formatDateTime(row.last_login_at) }}
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="created_by" label="创建人" min-width="100">
- <template #default="{ row }">
- <div class="user-info-simple">
- {{ row.created_by_name || '-' }}
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="created_time" label="创建时间" min-width="140">
- <template #default="{ row }">
- <div class="time-info">
- {{ formatDateTime(row.created_time) }}
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="updated_by" label="修改人" min-width="100">
- <template #default="{ row }">
- <div class="user-info-simple">
- {{ row.updated_by_name || '-' }}
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="updated_time" label="修改时间" min-width="140">
- <template #default="{ row }">
- <div class="time-info">
- {{ formatDateTime(row.updated_time) }}
- </div>
- </template>
- </el-table-column>
- <el-table-column label="操作" width="280" fixed="right">
- <template #default="{ row }">
- <div class="action-buttons">
- <el-button type="primary" size="small" @click="editUser(row)">
- 编辑
- </el-button>
- <el-button type="success" size="small" @click="assignRoles(row)">
- 分配角色
- </el-button>
- <el-button
- type="danger"
- size="small"
- @click="deleteUser(row)"
- :disabled="row.is_superuser || isCurrentUser(row.id)"
- >
- 删除
- </el-button>
- </div>
- </template>
- </el-table-column>
- </el-table>
- </div>
- <!-- 分页 -->
- <div class="pagination">
- <el-pagination
- v-model:current-page="currentPage"
- v-model:page-size="pageSize"
- :page-sizes="[10, 20, 50, 100]"
- :total="total"
- layout="total, sizes, prev, pager, next, jumper"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- />
- </div>
- <!-- 创建/编辑用户对话框 -->
- <el-dialog
- v-model="showCreateDialog"
- :title="editingUser ? '编辑用户' : '创建用户'"
- width="660px"
- @close="resetForm"
- >
- <el-form
- ref="userFormRef"
- :model="userForm"
- :rules="userRules"
- label-width="88px"
- >
- <el-row :gutter="18">
- <el-col :span="12">
- <el-form-item label="用户名" prop="username">
- <el-input
- v-model="userForm.username"
- placeholder="请输入用户名"
- :disabled="!!editingUser"
- size="default"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="邮箱" prop="email">
- <el-input
- v-model="userForm.email"
- placeholder="请输入邮箱"
- size="default"
- />
- </el-form-item>
- </el-col>
- </el-row>
-
- <el-row :gutter="18">
- <el-col :span="12">
- <el-form-item label="密码" :prop="editingUser ? '' : 'password'">
- <el-input
- v-model="userForm.password"
- type="password"
- :placeholder="editingUser ? '留空则不修改密码' : '请输入密码'"
- show-password
- size="default"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="手机号" prop="phone">
- <el-input
- v-model="userForm.phone"
- placeholder="请输入手机号"
- size="default"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="18">
- <el-col :span="12">
- <el-form-item label="真实姓名" prop="real_name">
- <el-input
- v-model="userForm.real_name"
- placeholder="请输入真实姓名"
- size="default"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="公司" prop="company">
- <el-input
- v-model="userForm.company"
- placeholder="请输入公司名称"
- size="default"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="18">
- <el-col :span="12">
- <el-form-item label="部门" prop="department">
- <el-input
- v-model="userForm.department"
- placeholder="请输入部门"
- size="default"
- />
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="角色" prop="role_ids">
- <el-select
- v-model="userForm.role_ids"
- multiple
- placeholder="请选择角色"
- style="width: 100%"
- size="default"
- >
- <el-option
- v-for="role in allRoles"
- :key="role.id"
- :label="role.name"
- :value="role.id"
- />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="18">
- <el-col :span="12">
- <el-form-item label="管理员">
- <el-switch v-model="userForm.is_superuser" size="default" />
- <span style="margin-left: 8px; font-size: 12px; color: #666;">
- 拥有系统所有权限
- </span>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item label="启用状态">
- <el-switch v-model="userForm.is_active" size="default" />
- <span style="margin-left: 8px; font-size: 12px; color: #666;">
- 用户是否可以登录
- </span>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <el-button @click="showCreateDialog = false">取消</el-button>
- <el-button type="primary" @click="saveUser" :loading="saving">
- {{ editingUser ? '更新' : '创建' }}
- </el-button>
- </template>
- </el-dialog>
- <!-- 角色分配对话框 -->
- <el-dialog
- v-model="showRoleDialog"
- title="分配角色"
- width="550px"
- >
- <div v-if="currentUser">
- <h4>为用户 "{{ currentUser.username }}" 分配角色</h4>
- <el-checkbox-group v-model="selectedRoleIds">
- <el-checkbox
- v-for="role in allRoles"
- :key="role.id"
- :label="role.id"
- :value="role.id"
- >
- {{ role.name }}
- <el-tag v-if="role.is_system" type="info" size="small" style="margin-left: 8px;">
- 系统角色
- </el-tag>
- </el-checkbox>
- </el-checkbox-group>
- </div>
- <template #footer>
- <el-button @click="showRoleDialog = false">取消</el-button>
- <el-button type="primary" @click="saveUserRoles" :loading="savingRoles">
- 保存
- </el-button>
- </template>
- </el-dialog>
- </div>
- </template>
- <script setup lang="ts">
- import { ref, reactive, onMounted } from 'vue'
- import { ElMessage, ElMessageBox } from 'element-plus'
- import { Plus, Search, Delete } from '@element-plus/icons-vue'
- import { useAuthStore } from '@/stores/auth'
- import request from '@/api/request'
- const authStore = useAuthStore()
- // 响应式数据
- const loading = ref(false)
- const saving = ref(false)
- const savingRoles = ref(false)
- const users = ref<any[]>([])
- const allRoles = ref<any[]>([])
- const selectedUsers = ref<any[]>([])
- const searchKeyword = ref('')
- const currentPage = ref(1)
- const pageSize = ref(20)
- const total = ref(0)
- // 对话框状态
- const showCreateDialog = ref(false)
- const showRoleDialog = ref(false)
- const editingUser = ref<any>(null)
- const currentUser = ref<any>(null)
- const selectedRoleIds = ref<string[]>([])
- // 表单数据
- const userForm = reactive({
- username: '',
- email: '',
- password: '',
- phone: '',
- real_name: '',
- company: '',
- department: '',
- role_ids: [] as string[],
- is_superuser: false,
- is_active: true
- })
- // 表单验证规则
- const userRules = {
- username: [
- { required: true, message: '请输入用户名', trigger: 'blur' },
- { min: 3, max: 20, message: '用户名长度在 3 到 20 个字符', trigger: 'blur' }
- ],
- email: [
- { required: true, message: '请输入邮箱', trigger: 'blur' },
- { type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
- ],
- password: [
- { required: true, message: '请输入密码', trigger: 'blur' },
- { min: 6, message: '密码长度不能少于6位', trigger: 'blur' }
- ],
- real_name: [
- { required: true, message: '请输入真实姓名', trigger: 'blur' }
- ]
- }
- // 引用
- const userFormRef = ref()
- // 判断是否为当前用户
- const isCurrentUser = (userId: string) => {
- return userId === authStore.user?.id
- }
- // 加载用户列表
- const loadUsers = async () => {
- loading.value = true
- try {
- const result = await request.get('/api/v1/system/admin/users', {
- params: {
- page: currentPage.value,
- page_size: pageSize.value,
- keyword: searchKeyword.value || undefined
- }
- })
-
- if (result.code === '000000' || result.code === 0) {
- users.value = result.data.items
- total.value = result.data.total
- } else {
- throw new Error(result.message)
- }
- } catch (error) {
- console.error('加载用户列表失败:', error)
- ElMessage.error('加载用户列表失败')
- } finally {
- loading.value = false
- }
- }
- // 加载所有角色
- const loadRoles = async () => {
- try {
- const result = await request.get('/api/v1/system/roles/all')
-
- if (result.code === '000000' || result.code === 0) {
- allRoles.value = result.data
- }
- } catch (error) {
- console.error('加载角色列表失败:', error)
- }
- }
- // 搜索处理
- const handleSearch = () => {
- currentPage.value = 1
- loadUsers()
- }
- // 分页处理
- const handleSizeChange = (size: number) => {
- pageSize.value = size
- currentPage.value = 1
- loadUsers()
- }
- const handleCurrentChange = (page: number) => {
- currentPage.value = page
- loadUsers()
- }
- // 选择处理
- const handleSelectionChange = (selection: any[]) => {
- selectedUsers.value = selection
- }
- // 状态切换
- const handleStatusChange = async (user: any) => {
- try {
- await request.put(`/api/v1/system/admin/users/${user.id}`, {
- is_active: user.is_active
- })
- ElMessage.success('用户状态更新成功')
- } catch (error) {
- console.error('更新用户状态失败:', error)
- ElMessage.error('更新用户状态失败')
- // 恢复原状态
- user.is_active = !user.is_active
- }
- }
- // 编辑用户
- const editUser = async (user: any) => {
- editingUser.value = user
-
- try {
- // 获取用户详情(包含角色信息)
- const result = await request.get(`/api/v1/system/admin/users/${user.id}`)
-
- if (result.code === '000000' || result.code === 0) {
- const userDetail = result.data
- Object.assign(userForm, {
- username: userDetail.username,
- email: userDetail.email,
- password: '',
- phone: userDetail.phone || '',
- real_name: userDetail.real_name || '',
- company: userDetail.company || '',
- department: userDetail.department || '',
- role_ids: userDetail.role_ids || [],
- is_superuser: userDetail.is_superuser,
- is_active: userDetail.is_active
- })
- } else {
- throw new Error(result.message)
- }
- } catch (error) {
- console.error('获取用户详情失败:', error)
- ElMessage.error('获取用户详情失败')
- // 如果获取详情失败,使用列表中的基本信息
- Object.assign(userForm, {
- username: user.username,
- email: user.email,
- password: '',
- phone: user.phone || '',
- real_name: user.real_name || '',
- company: user.company || '',
- department: user.department || '',
- role_ids: [],
- is_superuser: user.is_superuser,
- is_active: user.is_active
- })
- }
-
- showCreateDialog.value = true
- }
- // 删除用户
- const deleteUser = async (user: any) => {
- try {
- await ElMessageBox.confirm(
- `确定要删除用户 "${user.username}" 吗?此操作不可恢复。`,
- '确认删除',
- {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }
- )
-
- await request.delete(`/api/v1/system/admin/users/${user.id}`)
- ElMessage.success('用户删除成功')
- loadUsers()
- } catch (error: any) {
- if (error.response?.data?.message) {
- ElMessage.error(error.response.data.message)
- } else if (error !== 'cancel') {
- ElMessage.error('删除用户失败')
- }
- }
- }
- // 批量删除
- const batchDelete = async () => {
- try {
- await ElMessageBox.confirm(
- `确定要删除选中的 ${selectedUsers.value.length} 个用户吗?此操作不可恢复。`,
- '确认批量删除',
- {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }
- )
-
- // 逐个删除(可以优化为批量API)
- for (const user of selectedUsers.value) {
- await request.delete(`/api/v1/system/admin/users/${user.id}`)
- }
-
- ElMessage.success('批量删除成功')
- loadUsers()
- } catch (error) {
- if (error !== 'cancel') {
- ElMessage.error('批量删除失败')
- }
- }
- }
- // 分配角色
- const assignRoles = async (user: any) => {
- currentUser.value = user
-
- try {
- // 获取用户详情(包含角色信息)
- const result = await request.get(`/api/v1/system/admin/users/${user.id}`)
-
- if (result.code === '000000' || result.code === 0) {
- const userDetail = result.data
- selectedRoleIds.value = userDetail.role_ids || []
- } else {
- throw new Error(result.message)
- }
- } catch (error) {
- console.error('获取用户角色失败:', error)
- ElMessage.error('获取用户角色失败')
- selectedRoleIds.value = []
- }
-
- showRoleDialog.value = true
- }
- // 保存用户
- const saveUser = async () => {
- try {
- await userFormRef.value.validate()
-
- saving.value = true
-
- if (editingUser.value) {
- // 更新用户
- const updateData: any = {
- email: userForm.email,
- phone: userForm.phone || null, // 确保空字符串转为null
- real_name: userForm.real_name,
- company: userForm.company || null,
- department: userForm.department || null,
- role_ids: userForm.role_ids,
- is_superuser: userForm.is_superuser,
- is_active: userForm.is_active
- }
-
- // 如果填写了密码,则更新密码
- if (userForm.password && userForm.password.trim()) {
- updateData.password = userForm.password
- }
-
- await request.put(`/api/v1/system/admin/users/${editingUser.value.id}`, updateData)
- ElMessage.success('用户更新成功')
- } else {
- // 创建用户
- const createData = {
- ...userForm,
- phone: userForm.phone || null, // 确保空字符串转为null
- company: userForm.company || null,
- department: userForm.department || null
- }
-
- await request.post('/api/v1/system/admin/users', createData)
- ElMessage.success('用户创建成功')
- }
-
- showCreateDialog.value = false
- loadUsers()
- } catch (error: any) {
- console.error('保存用户失败:', error)
- if (error.response?.data?.message) {
- ElMessage.error(error.response.data.message)
- } else {
- ElMessage.error('保存用户失败')
- }
- } finally {
- saving.value = false
- }
- }
- // 保存用户角色
- const saveUserRoles = async () => {
- try {
- savingRoles.value = true
-
- await request.put(`/api/v1/system/admin/users/${currentUser.value.id}`, {
- role_ids: selectedRoleIds.value
- })
-
- ElMessage.success('角色分配成功')
- showRoleDialog.value = false
- loadUsers()
- } catch (error) {
- console.error('保存用户角色失败:', error)
- ElMessage.error('保存用户角色失败')
- } finally {
- savingRoles.value = false
- }
- }
- // 重置表单
- const resetForm = () => {
- editingUser.value = null
- Object.assign(userForm, {
- username: '',
- email: '',
- password: '',
- phone: '',
- real_name: '',
- company: '',
- department: '',
- role_ids: [],
- is_superuser: false,
- is_active: true
- })
- userFormRef.value?.clearValidate()
- }
- // 格式化日期时间
- const formatDateTime = (dateTime: string) => {
- if (!dateTime) return '-'
- const date = new Date(dateTime)
-
- // 格式化为 YYYY-MM-DD HH:mm:ss
- const year = date.getFullYear()
- const month = String(date.getMonth() + 1).padStart(2, '0')
- const day = String(date.getDate()).padStart(2, '0')
- const hours = String(date.getHours()).padStart(2, '0')
- const minutes = String(date.getMinutes()).padStart(2, '0')
- const seconds = String(date.getSeconds()).padStart(2, '0')
-
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
- }
- // 组件挂载
- onMounted(() => {
- loadUsers()
- loadRoles()
- })
- </script>
- <style scoped>
- .users-management {
- padding: 20px;
- }
- .page-header {
- margin-bottom: 20px;
- }
- .page-header h2 {
- margin: 0 0 8px 0;
- color: #333;
- }
- .page-header p {
- margin: 0;
- color: #666;
- font-size: 14px;
- }
- .toolbar {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
- padding: 16px;
- background: #fff;
- border-radius: 8px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- }
- .toolbar-left {
- display: flex;
- gap: 12px;
- }
- .toolbar-right {
- display: flex;
- gap: 12px;
- align-items: center;
- }
- .table-container {
- overflow-x: auto;
- background: #fff;
- border-radius: 8px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- min-width: 1200px; /* 设置最小宽度确保表格不会过度压缩 */
- }
- .user-info {
- display: flex;
- align-items: center;
- gap: 8px;
- min-width: 120px; /* 确保用户信息列有足够宽度 */
- }
- .user-info-simple {
- font-size: 12px;
- color: #666;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .user-details {
- display: flex;
- flex-direction: column;
- min-width: 0; /* 允许文本截断 */
- flex: 1;
- }
- .username {
- font-weight: 500;
- color: #333;
- font-size: 13px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- max-width: 100px; /* 限制用户名最大宽度 */
- }
- .real-name {
- font-size: 11px;
- color: #666;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- max-width: 100px; /* 限制真实姓名最大宽度 */
- }
- .roles-container {
- display: flex;
- flex-wrap: wrap;
- gap: 2px;
- align-items: center;
- min-width: 80px; /* 确保角色列有最小宽度 */
- }
- .time-info {
- font-size: 12px;
- color: #666;
- white-space: nowrap;
- }
- .action-buttons {
- display: flex;
- gap: 6px;
- align-items: center;
- justify-content: flex-start; /* 左对齐操作按钮 */
- flex-wrap: nowrap; /* 不允许换行 */
- }
- .pagination {
- margin-top: 20px;
- display: flex;
- justify-content: center;
- }
- :deep(.el-table) {
- background: #fff;
- border-radius: 8px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
- }
- :deep(.el-table .el-table__cell) {
- padding: 8px 0;
- }
- :deep(.el-dialog__body) {
- padding: 22px; /* 增加对话框内边距 10% */
- }
- :deep(.el-checkbox-group) {
- display: flex;
- flex-direction: column;
- gap: 12px;
- }
- :deep(.el-checkbox) {
- margin-right: 0;
- }
- /* 响应式设计 */
- @media (max-width: 1400px) {
- .table-container {
- min-width: 1300px; /* 增加最小宽度以适应更多列 */
- }
-
- .username, .real-name {
- max-width: 80px;
- }
- }
- @media (max-width: 1200px) {
- .table-container {
- min-width: 1200px; /* 增加最小宽度 */
- }
-
- .username, .real-name {
- max-width: 70px;
- }
-
- .toolbar {
- flex-direction: column;
- gap: 12px;
- align-items: stretch;
- }
-
- .toolbar-left, .toolbar-right {
- justify-content: center;
- }
-
- /* 中等屏幕下操作按钮调整 */
- .action-buttons {
- gap: 4px; /* 减少间距 */
- }
-
- .action-buttons .el-button {
- font-size: 12px;
- padding: 4px 8px;
- }
- }
- @media (max-width: 1000px) {
- .table-container {
- min-width: 1000px;
- }
-
- /* 小屏幕下操作按钮垂直排列 */
- .action-buttons {
- flex-direction: column;
- gap: 2px;
- flex-wrap: nowrap;
- }
-
- .action-buttons .el-button {
- font-size: 11px;
- padding: 2px 6px;
- min-width: 70px;
- }
- }
- @media (max-width: 768px) {
- .users-management {
- padding: 10px;
- }
-
- .table-container {
- min-width: 900px;
- }
-
- .toolbar {
- padding: 12px;
- }
-
- .toolbar-left {
- flex-wrap: wrap;
- gap: 8px;
- }
-
- .pagination {
- margin-top: 15px;
- }
-
- :deep(.el-pagination) {
- justify-content: center;
- flex-wrap: wrap;
- }
- }
- </style>
|