From 573c4975560e16b43651d07afdcd93732708e103 Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期六, 24 十月 2026 12:56:31 +0800
Subject: [PATCH] feat(hrm): 调岗申请表单新增「调岗人」选择,选中后自动带出原部门/原岗位

---
 src/views/hrm/transfer/data.ts                  |   24 ++++++++++-
 src/api/hrm/employee/index.ts                   |    5 ++
 src/api/hrm/transfer/index.ts                   |    6 ++-
 src/views/hrm/transfer/detail/approve/index.vue |    6 +-
 src/views/hrm/transfer/modules/form.vue         |   67 +++++++++++++++++++++++++--------
 5 files changed, 84 insertions(+), 24 deletions(-)

diff --git a/src/api/hrm/employee/index.ts b/src/api/hrm/employee/index.ts
index 7e1ae52..fdf7207 100644
--- a/src/api/hrm/employee/index.ts
+++ b/src/api/hrm/employee/index.ts
@@ -91,8 +91,13 @@
     id: number;
     employeeNo: string;
     name: string;
+    /** 閮ㄩ棬ID */
+    deptId?: number;
     deptName?: string;
+    /** 宀椾綅ID鍒楄〃 */
+    postIds?: number[];
     postName?: string;
+    employeeStatus?: number;
   }
 
   /** 鍛樺伐瀵煎叆缁撴灉 */
diff --git a/src/api/hrm/transfer/index.ts b/src/api/hrm/transfer/index.ts
index e992674..926f8f1 100644
--- a/src/api/hrm/transfer/index.ts
+++ b/src/api/hrm/transfer/index.ts
@@ -7,8 +7,10 @@
   /** 璋冨矖鐢宠 */
   export interface Transfer {
     id?: number;
-    employeeId?: number;
-    employeeName?: string;
+    /** 璋冨矖浜猴紙鍛樺伐ID锛� */
+    userId?: number;
+    /** 璋冨矖浜哄鍚� */
+    userName?: string;
     currentDeptId?: number;
     currentDeptName?: string;
     currentPostId?: number;
diff --git a/src/views/hrm/transfer/data.ts b/src/views/hrm/transfer/data.ts
index e6f2411..c4e4c31 100644
--- a/src/views/hrm/transfer/data.ts
+++ b/src/views/hrm/transfer/data.ts
@@ -7,6 +7,7 @@
 
 import { getDeptList } from '#/api/system/dept';
 import { getSimplePostList } from '#/api/system/post';
+import { getEmployeeSimpleList } from '#/api/hrm/employee';
 import { handleTree } from '#/packages/utils/src';
 
 /** 琛ㄥ崟绫诲瀷 */
@@ -40,12 +41,29 @@
       },
     },
     {
+      fieldName: 'userId',
+      label: '璋冨矖浜�',
+      component: 'ApiSelect',
+      componentProps: {
+        api: getEmployeeSimpleList,
+        labelField: 'name',
+        valueField: 'id',
+        showSearch: true,
+        filterOption: (input: string, option: any) =>
+          `${option?.label ?? ''}`.toLowerCase().includes(input.toLowerCase()),
+        allowClear: true,
+        placeholder: '璇烽�夋嫨瑕佽皟宀楃殑鍛樺伐锛堥�夋嫨鍚庤嚜鍔ㄥ甫鍑哄師閮ㄩ棬/鍘熷矖浣嶏級',
+      },
+      rules: 'selectRequired',
+      formItemClass: 'col-span-2',
+    },
+    {
       fieldName: 'currentDeptName',
       label: '鍘熼儴闂�',
       component: 'Input',
       componentProps: {
         disabled: true,
-        placeholder: '鑷姩鑾峰彇',
+        placeholder: '閫夋嫨璋冨矖浜哄悗鑷姩甯﹀嚭',
       },
     },
     {
@@ -54,7 +72,7 @@
       component: 'Input',
       componentProps: {
         disabled: true,
-        placeholder: '鑷姩鑾峰彇',
+        placeholder: '閫夋嫨璋冨矖浜哄悗鑷姩甯﹀嚭',
       },
     },
     {
@@ -175,7 +193,7 @@
 export function useGridColumns(): VxeTableGridOptions<HrmTransferApi.Transfer>['columns'] {
   return [
     { field: 'id', title: '鐢宠缂栧彿', width: 80 },
-    { field: 'employeeName', title: '鐢宠浜�', minWidth: 100 },
+    { field: 'userName', title: '璋冨矖浜�', minWidth: 100 },
     { field: 'currentDeptName', title: '鍘熼儴闂�', minWidth: 120 },
     { field: 'currentPostName', title: '鍘熷矖浣�', minWidth: 120 },
     { field: 'targetDeptName', title: '鐩爣閮ㄩ棬', minWidth: 120 },
diff --git a/src/views/hrm/transfer/detail/approve/index.vue b/src/views/hrm/transfer/detail/approve/index.vue
index 5d983ef..e99659d 100644
--- a/src/views/hrm/transfer/detail/approve/index.vue
+++ b/src/views/hrm/transfer/detail/approve/index.vue
@@ -30,9 +30,9 @@
   bordered: true,
   column: 2,
   schema: [
-    { label: '鍛樺伐濮撳悕', field: 'employeeName', render: textRender },
-    { label: '褰撳墠閮ㄩ棬', field: 'currentDeptName', render: textRender },
-    { label: '褰撳墠鑱屼綅', field: 'currentPostName', render: textRender },
+    { label: '璋冨矖浜�', field: 'userName', render: textRender },
+    { label: '鍘熼儴闂�', field: 'currentDeptName', render: textRender },
+    { label: '鍘熷矖浣�', field: 'currentPostName', render: textRender },
     { label: '鐩爣閮ㄩ棬', field: 'targetDeptName', render: textRender },
     { label: '鐩爣鑱屼綅', field: 'targetPostName', render: textRender },
     {
diff --git a/src/views/hrm/transfer/modules/form.vue b/src/views/hrm/transfer/modules/form.vue
index 6e76835..5527a15 100644
--- a/src/views/hrm/transfer/modules/form.vue
+++ b/src/views/hrm/transfer/modules/form.vue
@@ -17,7 +17,8 @@
 
 const emit = defineEmits(['success']);
 const formType = ref<FormType>('create');
-const currentEmployeeId = ref<number>();
+/** 鍛樺伐绮剧畝鍒楄〃缂撳瓨锛堥�変汉鏃剁敤浜庡甫鍑哄師閮ㄩ棬 / 鍘熷矖浣嶏級 */
+let employeeCache: any[] = [];
 
 const isDetail = computed(() => formType.value === 'detail');
 const getTitle = computed(() => {
@@ -26,6 +27,34 @@
   }
   return formType.value === 'update' ? '淇敼璋冨矖鐢宠' : '鏂板璋冨矖鐢宠';
 });
+
+/**
+ * 鏍规嵁閫変腑鐨勫憳宸ワ紝鑷姩甯﹀嚭鍘熼儴闂� / 鍘熷矖浣嶏紙鍚� ID锛屼究浜庡悗绔惤搴擄級
+ */
+async function fillCurrentPosition(employeeId?: number) {
+  if (!employeeId) {
+    await formApi.setValues({
+      currentDeptId: undefined,
+      currentDeptName: undefined,
+      currentPostId: undefined,
+      currentPostName: undefined,
+    });
+    return;
+  }
+  if (employeeCache.length === 0) {
+    employeeCache = (await getEmployeeSimpleList()) || [];
+  }
+  const emp = employeeCache.find((item) => item.id === employeeId);
+  if (!emp) {
+    return;
+  }
+  await formApi.setValues({
+    currentDeptId: emp.deptId,
+    currentDeptName: emp.deptName,
+    currentPostId: emp.postIds?.[0],
+    currentPostName: emp.postName,
+  });
+}
 
 const [Form, formApi] = useVbenForm({
   commonConfig: {
@@ -39,6 +68,12 @@
   layout: 'horizontal',
   schema: [],
   showDefaultActions: false,
+  // 閫夋嫨銆岃皟宀椾汉銆嶅悗锛岃嚜鍔ㄥ甫鍑哄叾褰撳墠閮ㄩ棬 / 宀椾綅
+  async handleValuesChange(values: any, changedFields: string[]) {
+    if (changedFields?.includes('userId')) {
+      await fillCurrentPosition(values?.userId);
+    }
+  },
 });
 
 const [Modal, modalApi] = useVbenModal({
@@ -53,7 +88,6 @@
     }
     modalApi.lock();
     const data = (await formApi.getValues()) as HrmTransferApi.Transfer;
-    data.employeeId = currentEmployeeId.value;
     try {
       if (data.id) {
         await updateTransfer(data);
@@ -71,30 +105,31 @@
     if (!isOpen) {
       return;
     }
+    employeeCache = [];
     const data = modalApi.getData<{ formType: FormType; id?: number }>();
     formType.value = data.formType;
     formApi.setState({ schema: useFormSchema(data.formType) });
     formApi.setDisabled(data.formType === 'detail');
     modalApi.setState({ showConfirmButton: data.formType !== 'detail' });
     if (!data?.id) {
-      // 鏂板鏃讹紝鑷姩鑾峰彇褰撳墠鐧诲綍鍛樺伐鐨勯儴闂ㄥ拰宀椾綅淇℃伅
-      const employees = await getEmployeeSimpleList();
-      // TODO: 杩欓噷搴旇鏍规嵁鐧诲綍鐢ㄦ埛鑾峰彇瀵瑰簲鐨勫憳宸ヤ俊鎭紝鏆傛椂鍙栫涓�涓憳宸ヤ綔涓虹ず渚�
-      const currentEmployee = employees[0];
-      if (currentEmployee) {
-        currentEmployeeId.value = currentEmployee.id;
-        await formApi.setValues({
-          currentDeptName: currentEmployee.deptName,
-          currentPostName: currentEmployee.postName,
-        });
-      }
+      // 鏂板锛氭竻绌鸿〃鍗曪紝鐢辩敤鎴烽�夋嫨璋冨矖浜�
+      await formApi.setValues({
+        userId: undefined,
+        currentDeptId: undefined,
+        currentDeptName: undefined,
+        currentPostId: undefined,
+        currentPostName: undefined,
+      });
       return;
     }
     modalApi.lock();
     try {
       const transfer = await getTransfer(data.id);
-      currentEmployeeId.value = transfer.employeeId;
       await formApi.setValues(transfer);
+      // 鍘嗗彶鏁版嵁鍙兘娌℃湁鍘熼儴闂�/宀椾綅锛屾寜璋冨矖浜鸿ˉ榻�
+      if (transfer.userId && !transfer.currentDeptId) {
+        await fillCurrentPosition(transfer.userId);
+      }
       if (transfer.attachmentList?.length) {
         await formApi.setFieldValue('blobIds', transfer.attachmentList.map(item => ({
           uid: String(item.id),
@@ -112,7 +147,7 @@
 </script>
 
 <template>
-  <Modal :title="getTitle" class="w-[600px]">
+  <Modal :title="getTitle" class="w-[700px]">
     <Form class="mx-4" />
   </Modal>
-</template>
\ No newline at end of file
+</template>

--
Gitblit v1.9.3