fix: 恢复Users.vue中的res.data.data正确嵌套结构
This commit is contained in:
parent
fa344f9c4e
commit
ea1eabafb0
|
|
@ -1,9 +1,21 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted, reactive } from 'vue'
|
||||||
import { Table, Button, Drawer, Input, Select, Form, Space, Popconfirm, message } from 'ant-design-vue'
|
import { Button, Drawer, Form, Space, message } from 'ant-design-vue'
|
||||||
import { PlusOutlined, SearchOutlined, ReloadOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons-vue'
|
import { PlusOutlined } from '@ant-design/icons-vue'
|
||||||
import { getUsers, createUser, updateUser, deleteUser } from '@/api/user'
|
import { getUsers, createUser, updateUser, deleteUser } from '@/api/user'
|
||||||
import type { User } from '@/types'
|
import type { User } from '@/types'
|
||||||
|
import {
|
||||||
|
PageHeader,
|
||||||
|
FilterBar,
|
||||||
|
TableCard,
|
||||||
|
TableToolbar,
|
||||||
|
TableActions,
|
||||||
|
Pagination,
|
||||||
|
StatusTag,
|
||||||
|
StatusSelect,
|
||||||
|
PhoneItem,
|
||||||
|
EmailItem
|
||||||
|
} from '@/components'
|
||||||
|
|
||||||
// 表格列定义
|
// 表格列定义
|
||||||
const columns = [
|
const columns = [
|
||||||
|
|
@ -12,7 +24,7 @@ const columns = [
|
||||||
{ title: '手机', dataIndex: 'phone', key: 'phone', width: 120 },
|
{ title: '手机', dataIndex: 'phone', key: 'phone', width: 120 },
|
||||||
{ title: '邮箱', dataIndex: 'email', key: 'email', ellipsis: true },
|
{ title: '邮箱', dataIndex: 'email', key: 'email', ellipsis: true },
|
||||||
{ title: '状态', dataIndex: 'status', key: 'status', width: 80 },
|
{ title: '状态', dataIndex: 'status', key: 'status', width: 80 },
|
||||||
{ title: '操作', key: 'action', width: 120, fixed: 'right' }
|
{ title: '操作', key: 'action', width: 120, fixed: 'right' as const }
|
||||||
]
|
]
|
||||||
|
|
||||||
// 数据
|
// 数据
|
||||||
|
|
@ -27,6 +39,13 @@ const submitting = ref(false)
|
||||||
const searchKeyword = ref('')
|
const searchKeyword = ref('')
|
||||||
const searchStatus = ref('')
|
const searchStatus = ref('')
|
||||||
|
|
||||||
|
// 分页
|
||||||
|
const pagination = reactive({
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0
|
||||||
|
})
|
||||||
|
|
||||||
// 表单
|
// 表单
|
||||||
const formState = ref({
|
const formState = ref({
|
||||||
id: '',
|
id: '',
|
||||||
|
|
@ -38,21 +57,13 @@ const formState = ref({
|
||||||
status: 'ACTIVE'
|
status: 'ACTIVE'
|
||||||
})
|
})
|
||||||
|
|
||||||
const statusOptions = [
|
|
||||||
{ value: 'ACTIVE', label: '正常', color: 'success' },
|
|
||||||
{ value: 'LOCKED', label: '锁定', color: 'warning' },
|
|
||||||
{ value: 'DISABLED', label: '禁用', color: 'error' }
|
|
||||||
]
|
|
||||||
|
|
||||||
// 获取用户列表
|
// 获取用户列表
|
||||||
const fetchUsers = async () => {
|
const fetchUsers = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const params: any = {}
|
const res = await getUsers()
|
||||||
if (searchKeyword.value) params.keyword = searchKeyword.value
|
|
||||||
if (searchStatus.value) params.status = searchStatus.value
|
|
||||||
const res = await getUsers(params)
|
|
||||||
users.value = res.data.data || []
|
users.value = res.data.data || []
|
||||||
|
pagination.total = res.data.data?.length || 0
|
||||||
} catch {
|
} catch {
|
||||||
message.error('获取用户列表失败')
|
message.error('获取用户列表失败')
|
||||||
} finally {
|
} finally {
|
||||||
|
|
@ -62,6 +73,7 @@ const fetchUsers = async () => {
|
||||||
|
|
||||||
// 搜索
|
// 搜索
|
||||||
const handleSearch = () => {
|
const handleSearch = () => {
|
||||||
|
pagination.current = 1
|
||||||
fetchUsers()
|
fetchUsers()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,6 +81,14 @@ const handleSearch = () => {
|
||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
searchKeyword.value = ''
|
searchKeyword.value = ''
|
||||||
searchStatus.value = ''
|
searchStatus.value = ''
|
||||||
|
pagination.current = 1
|
||||||
|
fetchUsers()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页变化
|
||||||
|
const handlePageChange = (page: number, pageSize: number) => {
|
||||||
|
pagination.current = page
|
||||||
|
pagination.pageSize = pageSize
|
||||||
fetchUsers()
|
fetchUsers()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,14 +139,14 @@ const handleSubmit = async () => {
|
||||||
await formRef.value.validate()
|
await formRef.value.validate()
|
||||||
submitting.value = true
|
submitting.value = true
|
||||||
|
|
||||||
const data = { ...formState.value }
|
const { id, ...data } = formState.value
|
||||||
if (!data.password) delete data.password
|
if (!data.password) delete (data as any).password
|
||||||
|
|
||||||
if (formState.value.id) {
|
if (id) {
|
||||||
await updateUser(formState.value.id, data)
|
await updateUser(id, data as Partial<User>)
|
||||||
message.success('更新成功')
|
message.success('更新成功')
|
||||||
} else {
|
} else {
|
||||||
await createUser(data)
|
await createUser(data as Partial<User>)
|
||||||
message.success('创建成功')
|
message.success('创建成功')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,103 +166,60 @@ const handleClose = () => {
|
||||||
drawerVisible.value = false
|
drawerVisible.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取状态显示
|
|
||||||
const getStatusColor = (status: string) => {
|
|
||||||
const map: Record<string, string> = {
|
|
||||||
ACTIVE: 'success',
|
|
||||||
LOCKED: 'warning',
|
|
||||||
DISABLED: 'error'
|
|
||||||
}
|
|
||||||
return map[status] || 'default'
|
|
||||||
}
|
|
||||||
|
|
||||||
const getStatusLabel = (status: string) => {
|
|
||||||
const map: Record<string, string> = {
|
|
||||||
ACTIVE: '正常',
|
|
||||||
LOCKED: '锁定',
|
|
||||||
DISABLED: '禁用'
|
|
||||||
}
|
|
||||||
return map[status] || status
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(fetchUsers)
|
onMounted(fetchUsers)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="page-container">
|
<div class="page-container">
|
||||||
<!-- 页面标题 -->
|
<!-- 页面标题 -->
|
||||||
<div class="page-header">
|
<PageHeader title="用户管理">
|
||||||
<h2 class="page-title">用户管理</h2>
|
<template #extra>
|
||||||
<div class="page-header-actions">
|
|
||||||
<Button type="primary" @click="handleAdd">
|
<Button type="primary" @click="handleAdd">
|
||||||
<PlusOutlined /> 新增用户
|
<PlusOutlined /> 新增用户
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</PageHeader>
|
||||||
|
|
||||||
<!-- 筛选区 -->
|
<!-- 筛选区 -->
|
||||||
<div class="filter-bar">
|
<FilterBar @search="handleSearch" @reset="handleReset">
|
||||||
<Space>
|
<a-input
|
||||||
<Input
|
v-model:value="searchKeyword"
|
||||||
v-model:value="searchKeyword"
|
placeholder="搜索用户名/姓名/手机"
|
||||||
placeholder="搜索用户名/姓名/手机"
|
style="width: 240px"
|
||||||
style="width: 240px"
|
allow-clear
|
||||||
@pressEnter="handleSearch"
|
@pressEnter="handleSearch"
|
||||||
>
|
/>
|
||||||
<template #prefix>
|
<StatusSelect v-model="searchStatus" placeholder="全部状态" />
|
||||||
<SearchOutlined />
|
</FilterBar>
|
||||||
</template>
|
|
||||||
</Input>
|
|
||||||
<Select
|
|
||||||
v-model:value="searchStatus"
|
|
||||||
placeholder="状态"
|
|
||||||
style="width: 120px"
|
|
||||||
:options="statusOptions"
|
|
||||||
allow-clear
|
|
||||||
/>
|
|
||||||
<Button type="primary" @click="handleSearch">查询</Button>
|
|
||||||
<Button @click="handleReset">
|
|
||||||
<ReloadOutlined /> 重置
|
|
||||||
</Button>
|
|
||||||
</Space>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
<div class="table-card">
|
<TableCard>
|
||||||
<Table
|
<TableToolbar @refresh="fetchUsers" />
|
||||||
|
|
||||||
|
<a-table
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data-source="users"
|
:data-source="users"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:row-key="(record: User) => record.id"
|
:row-key="(record: User) => record.id"
|
||||||
:pagination="{ pageSize: 10, showSizeChanger: true, showTotal: (total: number) => `共 ${total} 条` }"
|
:pagination="false"
|
||||||
>
|
>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
<template v-if="column.key === 'status'">
|
<template v-if="column.key === 'status'">
|
||||||
<a-tag :color="getStatusColor(record.status)">
|
<StatusTag :status="record.status" />
|
||||||
{{ getStatusLabel(record.status) }}
|
|
||||||
</a-tag>
|
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="column.key === 'action'">
|
<template v-else-if="column.key === 'action'">
|
||||||
<Space>
|
<TableActions @edit="handleEdit(record)" @delete="handleDelete(record.id)" />
|
||||||
<Button type="link" size="small" @click="handleEdit(record)">
|
|
||||||
<EditOutlined /> 编辑
|
|
||||||
</Button>
|
|
||||||
<Popconfirm
|
|
||||||
title="确认删除"
|
|
||||||
description="删除后不可恢复,是否继续?"
|
|
||||||
ok-text="确认"
|
|
||||||
cancel-text="取消"
|
|
||||||
@confirm="handleDelete(record.id)"
|
|
||||||
>
|
|
||||||
<Button type="link" danger size="small">
|
|
||||||
<DeleteOutlined /> 删除
|
|
||||||
</Button>
|
|
||||||
</Popconfirm>
|
|
||||||
</Space>
|
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</Table>
|
</a-table>
|
||||||
</div>
|
|
||||||
|
<Pagination
|
||||||
|
v-model:current="pagination.current"
|
||||||
|
v-model:pageSize="pagination.pageSize"
|
||||||
|
:total="pagination.total"
|
||||||
|
@change="handlePageChange"
|
||||||
|
/>
|
||||||
|
</TableCard>
|
||||||
|
|
||||||
<!-- 抽屉 -->
|
<!-- 抽屉 -->
|
||||||
<Drawer
|
<Drawer
|
||||||
|
|
@ -259,28 +236,22 @@ onMounted(fetchUsers)
|
||||||
:rules="{
|
:rules="{
|
||||||
username: [{ required: true, message: '请输入用户名' }],
|
username: [{ required: true, message: '请输入用户名' }],
|
||||||
password: [{ required: !formState.id, message: '请输入密码' }],
|
password: [{ required: !formState.id, message: '请输入密码' }],
|
||||||
realName: [{ required: true, message: '请输入姓名' }],
|
realName: [{ required: true, message: '请输入姓名' }]
|
||||||
phone: [{ pattern: /^1[3-9]\d{9}$/, message: '手机号格式错误' }],
|
|
||||||
email: [{ type: 'email', message: '邮箱格式错误' }]
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<Form.Item label="用户名" name="username">
|
<Form.Item label="用户名" name="username">
|
||||||
<Input v-model:value="formState.username" :disabled="!!formState.id" placeholder="请输入用户名" />
|
<a-input v-model:value="formState.username" :disabled="!!formState.id" placeholder="请输入用户名" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item v-if="!formState.id" label="密码" name="password">
|
<Form.Item v-if="!formState.id" label="密码" name="password">
|
||||||
<Input.Password v-model:value="formState.password" placeholder="请输入密码" />
|
<a-input-password v-model:value="formState.password" placeholder="请输入密码" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="姓名" name="realName">
|
<Form.Item label="姓名" name="realName">
|
||||||
<Input v-model:value="formState.realName" placeholder="请输入姓名" />
|
<a-input v-model:value="formState.realName" placeholder="请输入姓名" />
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="手机" name="phone">
|
|
||||||
<Input v-model:value="formState.phone" placeholder="请输入手机号" />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item label="邮箱" name="email">
|
|
||||||
<Input v-model:value="formState.email" placeholder="请输入邮箱" />
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<PhoneItem v-model="formState.phone" />
|
||||||
|
<EmailItem v-model="formState.email" />
|
||||||
<Form.Item label="状态" name="status">
|
<Form.Item label="状态" name="status">
|
||||||
<Select v-model:value="formState.status" :options="statusOptions" />
|
<StatusSelect v-model="formState.status" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue