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;
|