优化用户管理页

This commit is contained in:
Stev_Wang
2026-01-05 11:02:03 +08:00
parent 36934dbb7e
commit 0ec73cca94
5 changed files with 72 additions and 38 deletions

View File

@@ -1,4 +1,4 @@
# 开发环境变量 # 开发环境变量
# API 基础地址 # API 基础地址(使用代理,设置为空字符串)
VITE_API_BASE_URL=http://localhost:3000 VITE_API_BASE_URL=

View File

@@ -54,8 +54,6 @@ const route = useRoute()
const router = useRouter() const router = useRouter()
const adminStore = useAdminStore() const adminStore = useAdminStore()
console.log('AdminLayout - adminStore.userInfo:', adminStore.userInfo)
const activeKey = ref(String(route.name)) const activeKey = ref(String(route.name))
const menuOptions = [ const menuOptions = [

View File

@@ -30,13 +30,9 @@ export const useAdminStore = defineStore('admin', () => {
const login = async (username: string, password: string) => { const login = async (username: string, password: string) => {
try { try {
const data = await loginApi(username, password) const data = await loginApi(username, password)
console.log('登录API返回的数据:', data)
if (data.success && data.data) { if (data.success && data.data) {
console.log('设置token:', data.data.token)
console.log('设置用户信息:', data.data.user)
setToken(data.data.token) setToken(data.data.token)
setUserInfo(data.data.user) setUserInfo(data.data.user)
console.log('登录后userInfo:', userInfo.value)
return { success: true, message: data.message || '登录成功' } return { success: true, message: data.message || '登录成功' }
} }
return { success: false, message: data.message || '登录失败' } return { success: false, message: data.message || '登录失败' }

View File

@@ -1,9 +1,16 @@
import axios from 'axios' import axios, { type AxiosInstance, type AxiosResponse } from 'axios'
import type { ApiResponse } from '@/types/api'
const request = axios.create({ const request = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL, baseURL: import.meta.env.VITE_API_BASE_URL || '',
timeout: 10000 timeout: 10000
}) }) as AxiosInstance & {
<T = any>(config: any): Promise<ApiResponse<T>>
get<T = any>(url: string, config?: any): Promise<ApiResponse<T>>
post<T = any>(url: string, data?: any, config?: any): Promise<ApiResponse<T>>
put<T = any>(url: string, data?: any, config?: any): Promise<ApiResponse<T>>
delete<T = any>(url: string, config?: any): Promise<ApiResponse<T>>
}
request.interceptors.request.use( request.interceptors.request.use(
(config) => { (config) => {
@@ -26,11 +33,10 @@ request.interceptors.request.use(
) )
request.interceptors.response.use( request.interceptors.response.use(
(response) => { (response: AxiosResponse<ApiResponse>): any => {
return response.data return response.data
}, },
(error) => { (error) => {
console.error('请求错误:', error)
return Promise.reject(error) return Promise.reject(error)
} }
) )

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="user-management-container"> <div class="user-management-container">
<n-card title="用户管理"> <!-- 搜索区域 -->
<!-- 搜索表单 --> <n-card title="搜索用户" class="search-card">
<n-form inline :model="searchForm" label-placement="left" label-width="auto"> <n-form inline :model="searchForm" label-placement="left" label-width="auto">
<n-grid :cols="24" :x-gap="12"> <n-grid :cols="24" :x-gap="12">
<n-gi :span="6"> <n-gi :span="6">
@@ -37,7 +37,10 @@
</n-gi> </n-gi>
</n-grid> </n-grid>
</n-form> </n-form>
</n-card>
<!-- 用户列表区域 -->
<n-card title="用户列表" class="table-card">
<!-- 操作按钮 --> <!-- 操作按钮 -->
<n-space class="action-buttons" justify="space-between"> <n-space class="action-buttons" justify="space-between">
<n-space> <n-space>
@@ -65,6 +68,7 @@
:row-key="(row: any) => row.id" :row-key="(row: any) => row.id"
class="user-table" class="user-table"
/> />
</n-card>
<!-- 新建/编辑用户对话框 --> <!-- 新建/编辑用户对话框 -->
<UserFormModal <UserFormModal
@@ -74,7 +78,6 @@
:roles="roleList" :roles="roleList"
@success="handleUserFormSuccess" @success="handleUserFormSuccess"
/> />
</n-card>
</div> </div>
</template> </template>
@@ -82,7 +85,8 @@
import { ref, reactive, onMounted, h } from 'vue' import { ref, reactive, onMounted, h } from 'vue'
import { NCard, NForm, NFormItem, NInput, NSelect, NButton, NSpace, NGrid, NGi, NDataTable, useMessage, useDialog } from 'naive-ui' import { NCard, NForm, NFormItem, NInput, NSelect, NButton, NSpace, NGrid, NGi, NDataTable, useMessage, useDialog } from 'naive-ui'
import { RiAddLine, RiUploadLine, RiEditLine, RiDeleteBinLine, RiLockLine, RiLockUnlockLine } from '@remixicon/vue' import { RiAddLine, RiUploadLine, RiEditLine, RiDeleteBinLine, RiLockLine, RiLockUnlockLine } from '@remixicon/vue'
import axios from 'axios' import request from '@/utils/request'
import type { ApiResponse } from '@/types/api'
import UserFormModal from './components/UserFormModal.vue' import UserFormModal from './components/UserFormModal.vue'
// 消息提示 // 消息提示
@@ -147,8 +151,18 @@ const columns = [
}, row.status === 1 ? '启用' : '禁用') }, row.status === 1 ? '启用' : '禁用')
} }
}, },
{ title: '创建时间', key: 'createdAt', width: 180 }, {
{ title: '更新时间', key: 'updatedAt', width: 180 }, title: '创建时间',
key: 'createdAt',
width: 180,
render: (row: any) => formatDate(row.createdAt)
},
{
title: '更新时间',
key: 'updatedAt',
width: 180,
render: (row: any) => formatDate(row.updatedAt)
},
{ {
title: '操作', title: '操作',
key: 'actions', key: 'actions',
@@ -181,11 +195,23 @@ const showUserFormModal = ref(false)
const userFormMode = ref<'create' | 'edit'>('create') const userFormMode = ref<'create' | 'edit'>('create')
const currentUser = ref<any>(null) const currentUser = ref<any>(null)
// 格式化时间函数
const formatDate = (dateString: string) => {
if (!dateString) return ''
const date = new Date(dateString)
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')
return `${year}-${month}-${day} ${hours}:${minutes}`
}
// 获取用户列表 // 获取用户列表
const fetchUserList = async () => { const fetchUserList = async () => {
loading.value = true loading.value = true
try { try {
const response = await axios.get('/api/admin/users', { const response = await request.get('/api/admin/users', {
params: { params: {
username: searchForm.username || undefined, username: searchForm.username || undefined,
roleId: searchForm.roleId || undefined, roleId: searchForm.roleId || undefined,
@@ -193,11 +219,11 @@ const fetchUserList = async () => {
page: pagination.page, page: pagination.page,
pageSize: pagination.pageSize pageSize: pagination.pageSize
} }
}) }) as ApiResponse<{ list: any[]; total: number }>
if (response.data.success) { if (response.success && response.data) {
userList.value = response.data.data.list userList.value = response.data.list
pagination.itemCount = response.data.data.total pagination.itemCount = response.data.total
} }
} catch (error) { } catch (error) {
message.error('获取用户列表失败') message.error('获取用户列表失败')
@@ -209,10 +235,10 @@ const fetchUserList = async () => {
// 获取角色列表 // 获取角色列表
const fetchRoleList = async () => { const fetchRoleList = async () => {
try { try {
const response = await axios.get('/api/admin/roles/list') const response = await request.get('/api/admin/roles/list') as ApiResponse<any[]>
if (response.data.success) { if (response.success && response.data) {
roleList.value = response.data.data roleList.value = response.data
roleOptions.value = response.data.data.map((role: any) => ({ roleOptions.value = response.data.map((role: any) => ({
label: role.roleName, label: role.roleName,
value: role.id value: role.id
})) }))
@@ -261,7 +287,7 @@ const handleToggleStatus = (row: any) => {
negativeText: '取消', negativeText: '取消',
onPositiveClick: async () => { onPositiveClick: async () => {
try { try {
await axios.put(`/api/admin/users/${row.id}`, { await request.put(`/api/admin/users/${row.id}`, {
roleId: row.roleId, roleId: row.roleId,
status: newStatus status: newStatus
}) })
@@ -283,7 +309,7 @@ const handleDelete = (row: any) => {
negativeText: '取消', negativeText: '取消',
onPositiveClick: async () => { onPositiveClick: async () => {
try { try {
await axios.delete(`/api/admin/users/${row.id}`) await request.delete(`/api/admin/users/${row.id}`)
message.success('删除成功') message.success('删除成功')
fetchUserList() fetchUserList()
} catch (error: any) { } catch (error: any) {
@@ -316,6 +342,14 @@ onMounted(() => {
padding: 20px; padding: 20px;
} }
.search-card {
margin-bottom: 16px;
}
.table-card {
margin-bottom: 16px;
}
.action-buttons { .action-buttons {
margin: 16px 0; margin: 16px 0;
} }