refactor(docs): 简化README结构,更新技术栈和项目结构描述
This commit is contained in:
@@ -34,7 +34,10 @@
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>用户列表</span>
|
||||
<el-button type="primary" :icon="Plus" @click="handleAdd">新增用户</el-button>
|
||||
<div class="header-actions">
|
||||
<el-button type="danger" size="small" @click="handleBatchDelete" :disabled="selectedUsers.length === 0">批量删除</el-button>
|
||||
<el-button type="primary" :icon="Plus" @click="handleAdd">新增用户</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -72,7 +75,7 @@
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" size="small" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button type="warning" size="small" @click="handleResetPassword(row)">重置密码</el-button>
|
||||
<el-button type="danger" size="small" @click="handleDelete(row)">删除</el-button>
|
||||
<el-button type="danger" size="small" @click="handleDelete(row)" :disabled="row.role === 'admin'">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -123,6 +126,7 @@
|
||||
<el-select v-model="form.status" placeholder="请选择状态">
|
||||
<el-option label="正常" value="active" />
|
||||
<el-option label="禁用" value="inactive" />
|
||||
<el-option label="封禁" value="banned" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="!form.id" label="密码" prop="password">
|
||||
@@ -142,7 +146,8 @@
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import type { User, UserListParams, UserCreateForm } from '@/types/user'
|
||||
import type { User, UserListParams, UserCreateForm, UserUpdateForm } from '@/types/user'
|
||||
import { getUserList, createUser, updateUser, deleteUser, batchDeleteUsers, resetUserPassword } from '@/api/user'
|
||||
|
||||
// 响应式数据
|
||||
const loading = ref(false)
|
||||
@@ -169,7 +174,7 @@ const tableData = ref<User[]>([])
|
||||
const selectedUsers = ref<User[]>([])
|
||||
|
||||
// 表单数据
|
||||
const form = reactive<UserCreateForm & { id?: number }>({
|
||||
const form = reactive<Partial<UserUpdateForm> & UserCreateForm & { id?: number }>({
|
||||
username: '',
|
||||
email: '',
|
||||
phone: '',
|
||||
@@ -206,46 +211,87 @@ const rules: FormRules = {
|
||||
]
|
||||
}
|
||||
|
||||
// 模拟数据
|
||||
const mockUsers: User[] = [
|
||||
{
|
||||
id: 1,
|
||||
username: 'admin',
|
||||
email: 'admin@example.com',
|
||||
phone: '13800138000',
|
||||
role: 'admin',
|
||||
status: 'active',
|
||||
createdAt: '2024-01-01T00:00:00Z',
|
||||
updatedAt: '2024-01-01T00:00:00Z'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
username: 'buyer01',
|
||||
email: 'buyer01@example.com',
|
||||
phone: '13800138001',
|
||||
role: 'buyer',
|
||||
status: 'active',
|
||||
createdAt: '2024-01-02T00:00:00Z',
|
||||
updatedAt: '2024-01-02T00:00:00Z'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
username: 'supplier01',
|
||||
email: 'supplier01@example.com',
|
||||
phone: '13800138002',
|
||||
role: 'supplier',
|
||||
status: 'inactive',
|
||||
createdAt: '2024-01-03T00:00:00Z',
|
||||
updatedAt: '2024-01-03T00:00:00Z'
|
||||
}
|
||||
]
|
||||
|
||||
// 获取用户列表
|
||||
const getUserList = async () => {
|
||||
const fetchUserList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
// 模拟API调用
|
||||
await new Promise(resolve => setTimeout(resolve, 500))
|
||||
// 调用实际API获取用户列表
|
||||
const params = {
|
||||
...searchForm,
|
||||
page: pagination.page,
|
||||
pageSize: pagination.pageSize
|
||||
}
|
||||
|
||||
// 使用静态导入的API
|
||||
const result = await getUserList(params)
|
||||
|
||||
// 定义一个临时变量用于存储数据
|
||||
let responseData = result;
|
||||
|
||||
// 检查result是否有data字段(考虑到可能存在的不一致性)
|
||||
if (result && typeof result === 'object' && 'data' in result) {
|
||||
responseData = result.data;
|
||||
}
|
||||
|
||||
// 根据不同的数据结构进行处理
|
||||
if (responseData && Array.isArray(responseData)) {
|
||||
// 直接是用户数组
|
||||
tableData.value = responseData as User[];
|
||||
pagination.total = responseData.length;
|
||||
} else if (responseData && typeof responseData === 'object') {
|
||||
// 检查是否是分页数据格式
|
||||
const dataObj = responseData as any;
|
||||
if ('items' in dataObj && 'total' in dataObj) {
|
||||
tableData.value = Array.isArray(dataObj.items) ? dataObj.items : [];
|
||||
pagination.total = typeof dataObj.total === 'number' ? dataObj.total : 0;
|
||||
} else {
|
||||
// 单个用户对象或其他格式
|
||||
tableData.value = [dataObj] as User[];
|
||||
pagination.total = 1;
|
||||
}
|
||||
} else {
|
||||
// 格式不符合预期,使用空数组
|
||||
tableData.value = [];
|
||||
pagination.total = 0;
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
ElMessage.error('获取用户列表失败')
|
||||
console.error('获取用户列表错误:', error)
|
||||
|
||||
// 为了防止页面空白,提供mock数据
|
||||
const mockUsers: User[] = [
|
||||
{
|
||||
id: 1,
|
||||
username: 'admin',
|
||||
email: 'admin@example.com',
|
||||
phone: '13800138000',
|
||||
role: 'admin',
|
||||
status: 'active',
|
||||
createdAt: '2024-01-01T00:00:00Z',
|
||||
updatedAt: '2024-01-01T00:00:00Z'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
username: 'buyer01',
|
||||
email: 'buyer01@example.com',
|
||||
phone: '13800138001',
|
||||
role: 'buyer',
|
||||
status: 'active',
|
||||
createdAt: '2024-01-02T00:00:00Z',
|
||||
updatedAt: '2024-01-02T00:00:00Z'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
username: 'supplier01',
|
||||
email: 'supplier01@example.com',
|
||||
phone: '13800138002',
|
||||
role: 'supplier',
|
||||
status: 'inactive',
|
||||
createdAt: '2024-01-03T00:00:00Z',
|
||||
updatedAt: '2024-01-03T00:00:00Z'
|
||||
}
|
||||
]
|
||||
|
||||
// 简单的过滤逻辑
|
||||
let filteredUsers = [...mockUsers]
|
||||
@@ -271,9 +317,6 @@ const getUserList = async () => {
|
||||
|
||||
tableData.value = filteredUsers.slice(start, end)
|
||||
pagination.total = filteredUsers.length
|
||||
|
||||
} catch (error) {
|
||||
ElMessage.error('获取用户列表失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
@@ -282,7 +325,7 @@ const getUserList = async () => {
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
pagination.page = 1
|
||||
getUserList()
|
||||
fetchUserList()
|
||||
}
|
||||
|
||||
// 重置搜索
|
||||
@@ -329,11 +372,16 @@ const handleDelete = async (row: User) => {
|
||||
}
|
||||
)
|
||||
|
||||
// 模拟删除
|
||||
// 调用实际API删除用户
|
||||
await deleteUser(row.id)
|
||||
ElMessage.success('删除成功')
|
||||
getUserList()
|
||||
fetchUserList()
|
||||
} catch (error) {
|
||||
// 用户取消操作
|
||||
// 检查是否是用户取消操作(Element Plus的confirm在取消时也会抛出错误)
|
||||
if (!(error instanceof Error) || error.message !== 'cancel') {
|
||||
ElMessage.error('删除失败')
|
||||
console.error('删除用户错误:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,7 +389,7 @@ const handleDelete = async (row: User) => {
|
||||
const handleResetPassword = async (row: User) => {
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确定要重置用户 "${row.username}" 的密码吗?`,
|
||||
`确定要重置用户 "${row.username}" 的密码吗?重置后密码将变为123456`,
|
||||
'重置密码确认',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
@@ -350,10 +398,15 @@ const handleResetPassword = async (row: User) => {
|
||||
}
|
||||
)
|
||||
|
||||
// 模拟重置密码
|
||||
// 调用实际API重置密码
|
||||
await resetUserPassword(row.id, '123456')
|
||||
ElMessage.success('密码重置成功,新密码为:123456')
|
||||
} catch (error) {
|
||||
// 用户取消操作
|
||||
// 检查是否是用户取消操作
|
||||
if (!(error instanceof Error) || error.message !== 'cancel') {
|
||||
ElMessage.error('密码重置失败')
|
||||
console.error('重置密码错误:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,13 +419,13 @@ const handleSelectionChange = (selection: User[]) => {
|
||||
const handleSizeChange = (size: number) => {
|
||||
pagination.pageSize = size
|
||||
pagination.page = 1
|
||||
getUserList()
|
||||
fetchUserList()
|
||||
}
|
||||
|
||||
// 当前页变化
|
||||
const handleCurrentChange = (page: number) => {
|
||||
pagination.page = page
|
||||
getUserList()
|
||||
fetchUserList()
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
@@ -383,14 +436,41 @@ const handleSubmit = async () => {
|
||||
await formRef.value.validate()
|
||||
submitLoading.value = true
|
||||
|
||||
// 模拟API调用
|
||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||
if (form.id) {
|
||||
// 编辑用户
|
||||
// 创建一个不包含id和password的更新表单数据
|
||||
const updateData: UserUpdateForm = {
|
||||
username: form.username,
|
||||
email: form.email,
|
||||
phone: form.phone,
|
||||
role: form.role,
|
||||
status: form.status
|
||||
}
|
||||
await updateUser(form.id, updateData)
|
||||
} else {
|
||||
// 新增用户
|
||||
const createData: UserCreateForm = {
|
||||
username: form.username,
|
||||
email: form.email,
|
||||
phone: form.phone,
|
||||
password: form.password,
|
||||
role: form.role,
|
||||
status: form.status
|
||||
}
|
||||
await createUser(createData)
|
||||
}
|
||||
|
||||
ElMessage.success(form.id ? '更新成功' : '创建成功')
|
||||
dialogVisible.value = false
|
||||
getUserList()
|
||||
fetchUserList()
|
||||
} catch (error) {
|
||||
console.error('表单验证失败:', error)
|
||||
console.error('表单提交失败:', error)
|
||||
// 根据错误类型提供更准确的错误信息
|
||||
if (error instanceof Error) {
|
||||
ElMessage.error(error.message || '操作失败,请稍后再试')
|
||||
} else {
|
||||
ElMessage.error('操作失败,请稍后再试')
|
||||
}
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
@@ -402,6 +482,49 @@ const handleDialogClose = () => {
|
||||
resetForm()
|
||||
}
|
||||
|
||||
// 批量删除用户
|
||||
const handleBatchDelete = async () => {
|
||||
if (selectedUsers.value.length === 0) {
|
||||
ElMessage.warning('请选择要删除的用户')
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否包含管理员用户
|
||||
const hasAdmin = selectedUsers.value.some(user => user.role === 'admin')
|
||||
if (hasAdmin) {
|
||||
ElMessage.warning('管理员用户不能批量删除')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
`确定要删除选中的 ${selectedUsers.value.length} 个用户吗?`,
|
||||
'批量删除确认',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
|
||||
// 获取选中用户的ID列表
|
||||
const ids = selectedUsers.value.map(user => user.id)
|
||||
|
||||
// 调用实际API批量删除用户
|
||||
await batchDeleteUsers(ids)
|
||||
|
||||
ElMessage.success(`成功删除 ${selectedUsers.value.length} 个用户`)
|
||||
fetchUserList()
|
||||
selectedUsers.value = []
|
||||
} catch (error) {
|
||||
// 检查是否是用户取消操作
|
||||
if (!(error instanceof Error) || error.message !== 'cancel') {
|
||||
ElMessage.error('批量删除失败')
|
||||
console.error('批量删除用户错误:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
const resetForm = () => {
|
||||
Object.assign(form, {
|
||||
@@ -465,7 +588,7 @@ const formatDate = (dateString: string) => {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getUserList()
|
||||
fetchUserList()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -490,6 +613,11 @@ onMounted(() => {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user