From be8c526a454aa9081000d15f26bebdef8c183aea Mon Sep 17 00:00:00 2001
From: wsj <593216709@qq.com>
Date: Mon, 26 Oct 2026 23:34:23 +0800
Subject: [PATCH] feat: 提交
---
src/pages/system/users/components/UserFormDrawer.tsx | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 211 insertions(+), 0 deletions(-)
diff --git a/src/pages/system/users/components/UserFormDrawer.tsx b/src/pages/system/users/components/UserFormDrawer.tsx
new file mode 100644
index 0000000..aac230f
--- /dev/null
+++ b/src/pages/system/users/components/UserFormDrawer.tsx
@@ -0,0 +1,211 @@
+import { useCallback, useEffect, useState } from 'react';
+import {
+ App as AntdApp,
+ Button,
+ Drawer,
+ Form,
+ Input,
+ InputNumber,
+ Select,
+ Space,
+ Spin,
+} from 'antd';
+import { createEmployee, getEmployeeDetail, updateEmployee } from '../server';
+import type { EmployeeFormValues, EmployeeVO, SelectOption } from '../types';
+
+export type UserFormMode = 'create' | 'edit' | 'detail';
+
+interface UserFormDrawerProps {
+ open: boolean;
+ mode: UserFormMode;
+ /** 编辑 / 详情对象;新增时为空。 */
+ record: EmployeeVO | null;
+ orgOptions: SelectOption[];
+ roleOptions: SelectOption[];
+ onClose: () => void;
+ onSuccess: () => void;
+}
+
+const toFormValues = (employee: EmployeeVO): EmployeeFormValues => ({
+ name: employee.name,
+ phone: employee.phone,
+ orgId: employee.orgId,
+ roleId: employee.roleId,
+ position: employee.position,
+ email: employee.email,
+ holdLimit: employee.holdLimit,
+ region: employee.region,
+});
+
+const UserFormDrawer = ({
+ open,
+ mode,
+ record,
+ orgOptions,
+ roleOptions,
+ onClose,
+ onSuccess,
+}: UserFormDrawerProps) => {
+ const [form] = Form.useForm<EmployeeFormValues>();
+ const [submitting, setSubmitting] = useState(false);
+ const [loading, setLoading] = useState(false);
+ const { message } = AntdApp.useApp();
+ const isDetail = mode === 'detail';
+
+ useEffect(() => {
+ if (!open) return;
+
+ let active = true;
+
+ const initForm = async () => {
+ form.resetFields();
+
+ if (mode === 'detail') {
+ if (!record) return;
+
+ setLoading(true);
+ try {
+ const data = await getEmployeeDetail({ id: record.id });
+ if (active) form.setFieldsValue(toFormValues(data));
+ } catch {
+ // 错误已由 request 统一提示
+ if (active) onClose();
+ } finally {
+ if (active) setLoading(false);
+ }
+ return;
+ }
+
+ if (mode === 'edit' && record) {
+ form.setFieldsValue(toFormValues(record));
+ }
+ };
+
+ void initForm();
+
+ return () => {
+ active = false;
+ };
+ }, [form, mode, onClose, open, record]);
+
+ const handleSubmit = useCallback(async () => {
+ if (isDetail) return;
+
+ let values: EmployeeFormValues;
+ try {
+ values = await form.validateFields();
+ } catch {
+ return;
+ }
+
+ setSubmitting(true);
+ try {
+ if (mode === 'edit' && record) {
+ await updateEmployee({ id: record.id, ...values });
+ message.success('员工信息已更新');
+ } else {
+ await createEmployee(values);
+ message.success('员工创建成功');
+ }
+
+ onSuccess();
+ } catch {
+ // 错误已由 request 统一提示
+ } finally {
+ setSubmitting(false);
+ }
+ }, [form, isDetail, message, mode, onSuccess, record]);
+
+ const title = mode === 'create' ? '新增员工' : mode === 'edit' ? '编辑员工' : '员工详情';
+
+ return (
+ <Drawer
+ title={title}
+ width={420}
+ open={open}
+ forceRender
+ onClose={onClose}
+ footer={
+ <Space style={{ display: 'flex', justifyContent: 'flex-end' }}>
+ <Button onClick={onClose}>{isDetail ? '关闭' : '取消'}</Button>
+ {!isDetail && (
+ <Button type="primary" loading={submitting} onClick={handleSubmit}>
+ {mode === 'edit' ? '保存' : '创建'}
+ </Button>
+ )}
+ </Space>
+ }
+ >
+ <Spin spinning={loading}>
+ <Form form={form} layout="vertical" preserve={false}>
+ <Form.Item
+ name="name"
+ label="姓名"
+ rules={[{ required: true, message: '请输入姓名' }]}
+ >
+ <Input placeholder="请输入员工姓名" disabled={isDetail} />
+ </Form.Item>
+ <Form.Item
+ name="phone"
+ label="手机号"
+ rules={[
+ { required: true, message: '请输入手机号' },
+ { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号' },
+ ]}
+ >
+ <Input placeholder="请输入手机号" maxLength={11} disabled={isDetail} />
+ </Form.Item>
+ <Form.Item
+ name="orgId"
+ label="所属组织"
+ rules={[{ required: true, message: '请选择所属组织' }]}
+ >
+ <Select
+ showSearch
+ optionFilterProp="label"
+ options={orgOptions}
+ placeholder="请选择所属组织"
+ disabled={isDetail}
+ />
+ </Form.Item>
+ <Form.Item
+ name="roleId"
+ label="角色"
+ rules={[{ required: true, message: '请选择角色' }]}
+ >
+ <Select
+ showSearch
+ optionFilterProp="label"
+ options={roleOptions}
+ placeholder="请选择角色"
+ disabled={isDetail}
+ />
+ </Form.Item>
+ <Form.Item name="position" label="职位">
+ <Input placeholder="请输入职位" disabled={isDetail} />
+ </Form.Item>
+ <Form.Item name="region" label="负责区域">
+ <Input placeholder="请输入负责区域" disabled={isDetail} />
+ </Form.Item>
+ <Form.Item name="holdLimit" label="客户持有上限">
+ <InputNumber
+ min={0}
+ precision={0}
+ style={{ width: '100%' }}
+ disabled={isDetail}
+ />
+ </Form.Item>
+ <Form.Item
+ name="email"
+ label="邮箱"
+ rules={[{ type: 'email', message: '请输入正确的邮箱' }]}
+ >
+ <Input placeholder="请输入邮箱" disabled={isDetail} />
+ </Form.Item>
+ </Form>
+ </Spin>
+ </Drawer>
+ );
+};
+
+export default UserFormDrawer;
--
Gitblit v1.9.3