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