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