From fe1692fd7f4f307fea8054da6c6c50d5df2bf2d8 Mon Sep 17 00:00:00 2001
From: wsj <593216709@qq.com>
Date: Tue, 27 Oct 2026 23:02:57 +0800
Subject: [PATCH] feat: 提交
---
src/pages/system/users/components/UserFormDrawer.tsx | 72 ++++++++++++++++++++++++++++-------
1 files changed, 57 insertions(+), 15 deletions(-)
diff --git a/src/pages/system/users/components/UserFormDrawer.tsx b/src/pages/system/users/components/UserFormDrawer.tsx
index aac230f..b71a3f6 100644
--- a/src/pages/system/users/components/UserFormDrawer.tsx
+++ b/src/pages/system/users/components/UserFormDrawer.tsx
@@ -1,7 +1,8 @@
-import { useCallback, useEffect, useState } from 'react';
+import { useCallback, useEffect, useMemo, useState } from 'react';
import {
App as AntdApp,
Button,
+ Cascader,
Drawer,
Form,
Input,
@@ -11,7 +12,38 @@
Spin,
} from 'antd';
import { createEmployee, getEmployeeDetail, updateEmployee } from '../server';
-import type { EmployeeFormValues, EmployeeVO, SelectOption } from '../types';
+import type {
+ EmployeeFormValues,
+ EmployeeVO,
+ OrgTreeNode,
+ SelectOption,
+} from '../types';
+
+interface OrgCascaderOption {
+ value: number;
+ label: string;
+ children?: OrgCascaderOption[];
+}
+
+/** 组织树转为级联选择选项,按层级展示。 */
+const toCascaderOptions = (nodes: OrgTreeNode[]): OrgCascaderOption[] =>
+ nodes.map((node) => ({
+ value: node.id,
+ label: node.orgName,
+ children: node.children?.length ? toCascaderOptions(node.children) : undefined,
+ }));
+
+/** 在组织树中查找某个组织 ID 的完整路径,用于编辑 / 详情时回填级联值。 */
+const findOrgPath = (nodes: OrgTreeNode[], targetId: number): number[] | null => {
+ for (const node of nodes) {
+ if (node.id === targetId) return [node.id];
+
+ const childPath = node.children ? findOrgPath(node.children, targetId) : null;
+ if (childPath) return [node.id, ...childPath];
+ }
+
+ return null;
+};
export type UserFormMode = 'create' | 'edit' | 'detail';
@@ -20,16 +52,20 @@
mode: UserFormMode;
/** 编辑 / 详情对象;新增时为空。 */
record: EmployeeVO | null;
- orgOptions: SelectOption[];
+ /** 组织树,用于所属组织的二级联动选择。 */
+ orgTree: OrgTreeNode[];
roleOptions: SelectOption[];
onClose: () => void;
onSuccess: () => void;
}
-const toFormValues = (employee: EmployeeVO): EmployeeFormValues => ({
+const toFormValues = (
+ employee: EmployeeVO,
+ orgTree: OrgTreeNode[],
+): EmployeeFormValues => ({
name: employee.name,
phone: employee.phone,
- orgId: employee.orgId,
+ orgPath: findOrgPath(orgTree, employee.orgId) ?? [],
roleId: employee.roleId,
position: employee.position,
email: employee.email,
@@ -41,7 +77,7 @@
open,
mode,
record,
- orgOptions,
+ orgTree,
roleOptions,
onClose,
onSuccess,
@@ -51,6 +87,7 @@
const [loading, setLoading] = useState(false);
const { message } = AntdApp.useApp();
const isDetail = mode === 'detail';
+ const orgCascaderOptions = useMemo(() => toCascaderOptions(orgTree), [orgTree]);
useEffect(() => {
if (!open) return;
@@ -66,7 +103,7 @@
setLoading(true);
try {
const data = await getEmployeeDetail({ id: record.id });
- if (active) form.setFieldsValue(toFormValues(data));
+ if (active) form.setFieldsValue(toFormValues(data, orgTree));
} catch {
// 错误已由 request 统一提示
if (active) onClose();
@@ -77,7 +114,7 @@
}
if (mode === 'edit' && record) {
- form.setFieldsValue(toFormValues(record));
+ form.setFieldsValue(toFormValues(record, orgTree));
}
};
@@ -86,7 +123,7 @@
return () => {
active = false;
};
- }, [form, mode, onClose, open, record]);
+ }, [form, mode, onClose, open, orgTree, record]);
const handleSubmit = useCallback(async () => {
if (isDetail) return;
@@ -99,12 +136,16 @@
}
setSubmitting(true);
+
+ const { orgPath, ...rest } = values;
+ const orgId = orgPath[orgPath.length - 1];
+
try {
if (mode === 'edit' && record) {
- await updateEmployee({ id: record.id, ...values });
+ await updateEmployee({ id: record.id, ...rest, orgId });
message.success('员工信息已更新');
} else {
- await createEmployee(values);
+ await createEmployee({ ...rest, orgId });
message.success('员工创建成功');
}
@@ -156,16 +197,17 @@
<Input placeholder="请输入手机号" maxLength={11} disabled={isDetail} />
</Form.Item>
<Form.Item
- name="orgId"
+ name="orgPath"
label="所属组织"
rules={[{ required: true, message: '请选择所属组织' }]}
>
- <Select
+ <Cascader
+ options={orgCascaderOptions}
+ changeOnSelect
showSearch
- optionFilterProp="label"
- options={orgOptions}
placeholder="请选择所属组织"
disabled={isDetail}
+ style={{ width: '100%' }}
/>
</Form.Item>
<Form.Item
--
Gitblit v1.9.3