From d26274d89d377067c1e2648192cffbf89464b361 Mon Sep 17 00:00:00 2001
From: wsj <593216709@qq.com>
Date: Wed, 28 Oct 2026 23:34:32 +0800
Subject: [PATCH] feat: 拆包
---
src/pages/system/users/index.tsx | 241 +++++++----------------------------------------
1 files changed, 37 insertions(+), 204 deletions(-)
diff --git a/src/pages/system/users/index.tsx b/src/pages/system/users/index.tsx
index 15711c8..e0e616a 100644
--- a/src/pages/system/users/index.tsx
+++ b/src/pages/system/users/index.tsx
@@ -7,35 +7,20 @@
} from '@ant-design/icons';
import { ProTable } from '@ant-design/pro-components';
import type { ActionType } from '@ant-design/pro-components';
-import {
- App as AntdApp,
- Button,
- Descriptions,
- Drawer,
- Form,
- Input,
- InputNumber,
- Modal,
- Select,
- Space,
- Tag,
- Upload,
-} from 'antd';
+import { App as AntdApp, Button, Modal, Upload } from 'antd';
import type { UploadFile } from 'antd';
-import { createUserColumns, getEmployeeStatusMeta } from './columns';
+import { createUserColumns } from './columns';
+import UserFormDrawer from './components/UserFormDrawer';
+import type { UserFormMode } from './components/UserFormDrawer';
import {
- createEmployee,
deleteEmployee,
exportEmployees,
- getEmployeeDetail,
getEmployeeList,
getOrgTree,
getRoleOptions,
importEmployees,
- updateEmployee,
-} from './server';
+} from './service';
import type {
- EmployeeFormValues,
EmployeeListQuery,
EmployeeVO,
OrgTreeNode,
@@ -54,15 +39,11 @@
const actionRef = useRef<ActionType>();
const lastQueryRef = useRef<TenantEmployeeListRequest>({});
const { message, modal } = AntdApp.useApp();
- const [form] = Form.useForm<EmployeeFormValues>();
- const [orgOptions, setOrgOptions] = useState<SelectOption[]>([]);
+ const [orgTree, setOrgTree] = useState<OrgTreeNode[]>([]);
const [roleOptions, setRoleOptions] = useState<SelectOption[]>([]);
const [formOpen, setFormOpen] = useState(false);
- const [editing, setEditing] = useState<EmployeeVO | null>(null);
- const [submitting, setSubmitting] = useState(false);
- const [detail, setDetail] = useState<EmployeeVO | null>(null);
- const [detailOpen, setDetailOpen] = useState(false);
- const [detailLoading, setDetailLoading] = useState(false);
+ const [formMode, setFormMode] = useState<UserFormMode>('create');
+ const [activeEmployee, setActiveEmployee] = useState<EmployeeVO | null>(null);
const [importOpen, setImportOpen] = useState(false);
const [importFileList, setImportFileList] = useState<UploadFile[]>([]);
const [importing, setImporting] = useState(false);
@@ -76,7 +57,7 @@
const [orgs, roles] = await Promise.all([getOrgTree(), getRoleOptions()]);
if (!active) return;
- setOrgOptions(flattenOrgOptions(orgs));
+ setOrgTree(orgs);
setRoleOptions(roles.map((role) => ({ label: role.roleName, value: role.id })));
} catch {
// 错误已由 request 统一提示
@@ -90,6 +71,8 @@
};
}, []);
+ const orgOptions = useMemo(() => flattenOrgOptions(orgTree), [orgTree]);
+
const orgNameMap = useMemo(
() => new Map(orgOptions.map((option) => [option.value, option.label])),
[orgOptions],
@@ -101,48 +84,31 @@
);
const openCreate = useCallback(() => {
- setEditing(null);
- form.resetFields();
+ setActiveEmployee(null);
+ setFormMode('create');
setFormOpen(true);
- }, [form]);
+ }, []);
const closeForm = useCallback(() => {
setFormOpen(false);
- setEditing(null);
+ setActiveEmployee(null);
}, []);
- const openEdit = useCallback(
- (record: EmployeeVO) => {
- setEditing(record);
- form.setFieldsValue({
- name: record.name,
- phone: record.phone,
- orgId: record.orgId,
- roleId: record.roleId,
- position: record.position,
- email: record.email,
- holdLimit: record.holdLimit,
- region: record.region,
- });
- setFormOpen(true);
- },
- [form],
- );
+ const handleFormSuccess = useCallback(() => {
+ closeForm();
+ actionRef.current?.reload();
+ }, [closeForm]);
- const handleDetail = useCallback(async (record: EmployeeVO) => {
- setDetail(null);
- setDetailOpen(true);
- setDetailLoading(true);
+ const openEdit = useCallback((record: EmployeeVO) => {
+ setActiveEmployee(record);
+ setFormMode('edit');
+ setFormOpen(true);
+ }, []);
- try {
- const data = await getEmployeeDetail({ id: record.id });
- setDetail(data);
- } catch {
- // 错误已由 request 统一提示
- setDetailOpen(false);
- } finally {
- setDetailLoading(false);
- }
+ const openDetail = useCallback((record: EmployeeVO) => {
+ setActiveEmployee(record);
+ setFormMode('detail');
+ setFormOpen(true);
}, []);
const handleDelete = useCallback(
@@ -162,35 +128,6 @@
},
[message, modal],
);
-
- const handleSubmit = useCallback(async () => {
- let values: EmployeeFormValues;
- try {
- values = await form.validateFields();
- } catch {
- return;
- }
-
- setSubmitting(true);
- try {
- if (editing) {
- await updateEmployee({ id: editing.id, ...values });
- message.success('员工信息已更新');
- } else {
- await createEmployee(values);
- message.success('员工创建成功');
- }
-
- setFormOpen(false);
- setEditing(null);
- form.resetFields();
- actionRef.current?.reload();
- } catch {
- // 错误已由 request 统一提示
- } finally {
- setSubmitting(false);
- }
- }, [editing, form, message]);
const handleExport = useCallback(async () => {
setExporting(true);
@@ -240,11 +177,11 @@
roleOptions,
orgNameMap,
roleNameMap,
- onDetail: handleDetail,
+ onDetail: openDetail,
onEdit: openEdit,
onDelete: handleDelete,
}),
- [orgOptions, roleOptions, orgNameMap, roleNameMap, handleDetail, openEdit, handleDelete],
+ [orgOptions, roleOptions, orgNameMap, roleNameMap, openDetail, openEdit, handleDelete],
);
return (
@@ -253,7 +190,6 @@
rowKey="id"
actionRef={actionRef}
columns={columns}
- cardProps={{ className: 'table-card' }}
search={{ labelWidth: 'auto', defaultCollapsed: false }}
scroll={{ x: 1290 }}
options={false}
@@ -307,118 +243,15 @@
}}
/>
- <Drawer
- title={editing ? '编辑员工' : '新增员工'}
- width={420}
+ <UserFormDrawer
open={formOpen}
- forceRender
+ mode={formMode}
+ record={activeEmployee}
+ orgTree={orgTree}
+ roleOptions={roleOptions}
onClose={closeForm}
- footer={
- <Space style={{ display: 'flex', justifyContent: 'flex-end' }}>
- <Button onClick={closeForm}>取消</Button>
- <Button type="primary" loading={submitting} onClick={handleSubmit}>
- {editing ? '保存' : '创建'}
- </Button>
- </Space>
- }
- >
- <Form form={form} layout="vertical" preserve={false}>
- <Form.Item
- name="name"
- label="姓名"
- rules={[{ required: true, message: '请输入姓名' }]}
- >
- <Input placeholder="请输入员工姓名" />
- </Form.Item>
- <Form.Item
- name="phone"
- label="手机号"
- rules={[
- { required: true, message: '请输入手机号' },
- { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号' },
- ]}
- >
- <Input placeholder="请输入手机号" maxLength={11} />
- </Form.Item>
- <Form.Item
- name="orgId"
- label="所属组织"
- rules={[{ required: true, message: '请选择所属组织' }]}
- >
- <Select
- showSearch
- optionFilterProp="label"
- options={orgOptions}
- placeholder="请选择所属组织"
- />
- </Form.Item>
- <Form.Item
- name="roleId"
- label="角色"
- rules={[{ required: true, message: '请选择角色' }]}
- >
- <Select
- showSearch
- optionFilterProp="label"
- options={roleOptions}
- placeholder="请选择角色"
- />
- </Form.Item>
- <Form.Item name="position" label="职位">
- <Input placeholder="请输入职位" />
- </Form.Item>
- <Form.Item name="region" label="负责区域">
- <Input placeholder="请输入负责区域" />
- </Form.Item>
- <Form.Item name="holdLimit" label="客户持有上限">
- <InputNumber min={0} precision={0} style={{ width: '100%' }} />
- </Form.Item>
- <Form.Item
- name="email"
- label="邮箱"
- rules={[{ type: 'email', message: '请输入正确的邮箱' }]}
- >
- <Input placeholder="请输入邮箱" />
- </Form.Item>
- </Form>
- </Drawer>
-
- <Drawer
- title="员工详情"
- width={480}
- open={detailOpen}
- loading={detailLoading}
- onClose={() => {
- setDetailOpen(false);
- setDetail(null);
- }}
- >
- {detail && (
- <Descriptions column={1} bordered size="small">
- <Descriptions.Item label="姓名">{detail.name}</Descriptions.Item>
- <Descriptions.Item label="手机号">{detail.phone}</Descriptions.Item>
- <Descriptions.Item label="所属组织">
- {orgNameMap.get(detail.orgId) ?? `#${detail.orgId}`}
- </Descriptions.Item>
- <Descriptions.Item label="角色">
- {roleNameMap.get(detail.roleId) ?? `#${detail.roleId}`}
- </Descriptions.Item>
- <Descriptions.Item label="职位">{detail.position || '-'}</Descriptions.Item>
- <Descriptions.Item label="邮箱">{detail.email || '-'}</Descriptions.Item>
- <Descriptions.Item label="负责区域">{detail.region || '-'}</Descriptions.Item>
- <Descriptions.Item label="客户持有上限">
- {detail.holdLimit ?? '-'}
- </Descriptions.Item>
- <Descriptions.Item label="状态">
- <Tag color={getEmployeeStatusMeta(detail.status).color} bordered={false}>
- {getEmployeeStatusMeta(detail.status).text}
- </Tag>
- </Descriptions.Item>
- <Descriptions.Item label="入职日期">{detail.hireDate || '-'}</Descriptions.Item>
- <Descriptions.Item label="创建时间">{detail.createdAt || '-'}</Descriptions.Item>
- </Descriptions>
- )}
- </Drawer>
+ onSuccess={handleFormSuccess}
+ />
<Modal
title="导入员工"
--
Gitblit v1.9.3