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