员工姓名
diff --git a/src/pages/Users.tsx b/src/pages/Users.tsx
deleted file mode 100644
index 1d11327..0000000
--- a/src/pages/Users.tsx
+++ /dev/null
@@ -1,433 +0,0 @@
-import { useEffect, useState } from 'react';
-import {
- Card,
- Table,
- Button,
- Space,
- Input,
- Select,
- Tag,
- Modal,
- Form,
- message,
- Pagination,
-} from 'antd';
-import {
- UserOutlined,
- PlusOutlined,
- EditOutlined,
- DeleteOutlined,
- KeyOutlined,
-} from '@ant-design/icons';
-import { usersApi, authApi } from '@/services/api';
-import type { User, UserRole, CreateUserRequest, UpdateUserRequest } from '@/types';
-
-const ROLE_LABEL: Record
= {
- admin: '管理员',
- technician: '技术员',
- employee: '员工(不可登录后台)',
- user: '普通用户',
-};
-
-const ROLE_COLOR: Record = {
- admin: 'red',
- technician: 'blue',
- employee: 'green',
- user: 'default',
-};
-
-function UsersPage() {
- const currentUser = authApi.getCurrentUser();
-
- const [users, setUsers] = useState([]);
- const [loading, setLoading] = useState(true);
- const [page, setPage] = useState(1);
- const [limit, setLimit] = useState(10);
- const [total, setTotal] = useState(0);
- const [search, setSearch] = useState('');
- const [roleFilter, setRoleFilter] = useState();
-
- const [createVisible, setCreateVisible] = useState(false);
- const [createLoading, setCreateLoading] = useState(false);
- const [createForm] = Form.useForm();
-
- const [editingUser, setEditingUser] = useState(null);
- const [editLoading, setEditLoading] = useState(false);
- const [editForm] = Form.useForm();
-
- const [resetPasswordUser, setResetPasswordUser] = useState(null);
- const [resetLoading, setResetLoading] = useState(false);
- const [resetForm] = Form.useForm<{ newPassword: string }>();
-
- const loadUsers = async () => {
- setLoading(true);
- try {
- const result = await usersApi.list({
- page,
- limit,
- search: search || undefined,
- role: roleFilter,
- });
- setUsers(result.data || []);
- setTotal(result.pagination?.total || 0);
- } catch (err: any) {
- message.error(err?.response?.data?.message || err.message || '加载用户列表失败');
- setUsers([]);
- } finally {
- setLoading(false);
- }
- };
-
- useEffect(() => {
- loadUsers();
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [page, limit, search, roleFilter]);
-
- const handleCreate = async (values: CreateUserRequest) => {
- setCreateLoading(true);
- try {
- await usersApi.create(values);
- message.success('用户创建成功');
- setCreateVisible(false);
- createForm.resetFields();
- loadUsers();
- } catch (err: any) {
- message.error(err?.response?.data?.message || err.message || '创建失败');
- } finally {
- setCreateLoading(false);
- }
- };
-
- const openEdit = (user: User) => {
- setEditingUser(user);
- editForm.setFieldsValue({
- name: user.name,
- email: user.email,
- role: user.role,
- });
- };
-
- const handleEdit = async (values: UpdateUserRequest) => {
- if (!editingUser) return;
- setEditLoading(true);
- try {
- await usersApi.update(editingUser.id, values);
- message.success('用户更新成功');
- setEditingUser(null);
- loadUsers();
- } catch (err: any) {
- message.error(err?.response?.data?.message || err.message || '更新失败');
- } finally {
- setEditLoading(false);
- }
- };
-
- const handleResetPassword = async (values: { newPassword: string }) => {
- if (!resetPasswordUser) return;
- setResetLoading(true);
- try {
- await usersApi.resetPassword(resetPasswordUser.id, values.newPassword);
- message.success('密码重置成功');
- setResetPasswordUser(null);
- resetForm.resetFields();
- } catch (err: any) {
- message.error(err?.response?.data?.message || err.message || '重置失败');
- } finally {
- setResetLoading(false);
- }
- };
-
- const handleDelete = (user: User) => {
- Modal.confirm({
- title: '确认删除',
- content: `确定要删除用户 "${user.username}" 吗?此操作不可恢复!`,
- okText: '确定',
- okType: 'danger',
- cancelText: '取消',
- onOk: async () => {
- try {
- await usersApi.delete(user.id);
- message.success('删除成功');
- loadUsers();
- } catch (err: any) {
- message.error(err?.response?.data?.message || err.message || '删除失败');
- }
- },
- });
- };
-
- const columns = [
- {
- title: '用户名',
- dataIndex: 'username',
- key: 'username',
- render: (text: string) => {text},
- },
- {
- title: '姓名',
- dataIndex: 'name',
- key: 'name',
- },
- {
- title: '邮箱',
- dataIndex: 'email',
- key: 'email',
- render: (text?: string) => text || '-',
- },
- {
- title: '角色',
- dataIndex: 'role',
- key: 'role',
- width: 100,
- render: (role: UserRole) => {ROLE_LABEL[role]},
- },
- {
- title: '创建时间',
- dataIndex: 'createdAt',
- key: 'createdAt',
- width: 170,
- render: (date: string) => new Date(date).toLocaleString('zh-CN'),
- },
- {
- title: '操作',
- key: 'actions',
- width: 260,
- render: (_: any, record: User) => (
-
- }
- onClick={() => openEdit(record)}
- >
- 编辑
-
- }
- onClick={() => setResetPasswordUser(record)}
- >
- 重置密码
-
- {record.id !== currentUser?.id && (
- }
- onClick={() => handleDelete(record)}
- >
- 删除
-
- )}
-
- ),
- },
- ];
-
- return (
-
- );
-}
-
-export default UsersPage;
diff --git a/src/services/api.ts b/src/services/api.ts
index 6e1b021..0d96587 100644
--- a/src/services/api.ts
+++ b/src/services/api.ts
@@ -445,6 +445,13 @@ export const aftersalesApi = {
};
export const usersApi = {
+ assignable: async () => {
+ const response = await apiClient.get('/users/assignable');
+ return (response.data?.data || []) as User[];
+ },
+};
+
+export const employeesApi = {
list: async (filter?: UserListFilter) => {
const params = new URLSearchParams();
if (filter?.page && filter.page > 1) params.append('page', String(filter.page));
@@ -452,29 +459,29 @@ export const usersApi = {
if (filter?.role) params.append('role', filter.role);
if (filter?.search) params.append('search', filter.search);
- const url = params.toString() ? `/users?${params.toString()}` : '/users';
+ const url = params.toString() ? `/employees?${params.toString()}` : '/employees';
const response = await apiClient.get(url);
return response.data as UserListResponse;
},
create: async (data: CreateUserRequest) => {
- const response = await apiClient.post('/users', data);
- if (response.data.user) {
- return response.data.user as User;
+ const response = await apiClient.post('/employees', data);
+ if (response.data.employee) {
+ return response.data.employee as User;
}
- throw new Error(response.data.error || '创建用户失败');
+ throw new Error(response.data.error || '创建员工失败');
},
update: async (id: number, data: UpdateUserRequest) => {
- const response = await apiClient.patch(`/users/${id}`, data);
- if (response.data.user) {
- return response.data.user as User;
+ const response = await apiClient.patch(`/employees/${id}`, data);
+ if (response.data.employee) {
+ return response.data.employee as User;
}
- throw new Error(response.data.error || '更新用户失败');
+ throw new Error(response.data.error || '更新员工失败');
},
resetPassword: async (id: number, newPassword: string) => {
- const response = await apiClient.post(`/users/${id}/reset-password`, { newPassword });
+ const response = await apiClient.post(`/employees/${id}/reset-password`, { newPassword });
if (response.data.message) {
return true;
}
@@ -482,15 +489,10 @@ export const usersApi = {
},
delete: async (id: number) => {
- const response = await apiClient.delete(`/users/${id}`);
+ const response = await apiClient.delete(`/employees/${id}`);
if (response.data.message) {
return true;
}
- throw new Error(response.data.error || '删除用户失败');
+ throw new Error(response.data.error || '删除员工失败');
},
-
- assignable: async () => {
- const response = await apiClient.get('/users/assignable');
- return (response.data?.data || []) as User[];
- },
-};
\ No newline at end of file
+};
diff --git a/src/types/index.ts b/src/types/index.ts
index eadd088..64f44ec 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -1,25 +1,35 @@
-export type UserRole = 'admin' | 'technician' | 'employee' | 'user';
+export type UserRole = 'admin' | 'technician' | 'employee';
export interface User {
id: number;
username: string;
name: string;
email?: string;
+ phone?: string;
+ employeeNo?: string;
+ position?: string;
role: UserRole;
createdAt: string;
+ employeeSerials?: EmployeeSerial[];
}
export interface CreateUserRequest {
- username: string;
- password: string;
+ username?: string;
+ password?: string;
name: string;
email?: string;
+ phone: string;
+ employeeNo: string;
+ position: string;
role: UserRole;
}
export interface UpdateUserRequest {
name?: string;
email?: string;
+ phone?: string;
+ employeeNo?: string;
+ position?: string;
role?: UserRole;
}
@@ -135,10 +145,12 @@ export interface CompanyFilter {
}
export interface EmployeeSerial {
+ id?: number;
serialNumber: string;
companyName: string;
position: string;
employeeName: string;
+ employeeId?: number;
isActive: boolean;
createdAt: string;
updatedAt?: string;