gaoluyang
2 天以前 e40146bf8fb1443492eb38cf43ffc6171cfbb1b0
feat(hrm): 调岗申请增加调岗人员选择,原部门/原岗位自动带出

- 新增/修改表单增加「调岗人员」用户选择(默认当前登录人),选择后自动回填原部门、原岗位
- 去掉原先取员工列表第一人的临时逻辑,申请人字段 employeeName 改为 userName
- 列表与审批详情同步展示「调岗人员」

Co-Authored-By: Claude Code <noreply@anthropic.com>
已修改4个文件
95 ■■■■■ 文件已修改
src/api/hrm/transfer/index.ts 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hrm/transfer/data.ts 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hrm/transfer/detail/approve/index.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hrm/transfer/modules/form.vue 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/hrm/transfer/index.ts
@@ -7,8 +7,8 @@
  /** 调岗申请 */
  export interface Transfer {
    id?: number;
    employeeId?: number;
    employeeName?: string;
    userId?: number;
    userName?: string;
    currentDeptId?: number;
    currentDeptName?: string;
    currentPostId?: number;
src/views/hrm/transfer/data.ts
@@ -1,6 +1,9 @@
import type { VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { HrmTransferApi } from '#/api/hrm/transfer';
import type { SystemUserApi } from '#/api/system/user';
import { markRaw } from 'vue';
import { DICT_TYPE } from '#/packages/constants/src';
import { getDictOptions } from '#/packages/effects/hooks/src';
@@ -8,12 +11,16 @@
import { getDeptList } from '#/api/system/dept';
import { getSimplePostList } from '#/api/system/post';
import { handleTree } from '#/packages/utils/src';
import { UserSelect } from '#/views/system/user/components';
/** 表单类型 */
export type FormType = 'create' | 'detail' | 'update';
/** 新增/修改调岗申请的表单 */
export function useFormSchema(formType: FormType): VbenFormSchema[] {
export function useFormSchema(
  formType: FormType,
  onUserChange?: (user?: SystemUserApi.User) => void,
): VbenFormSchema[] {
  return [
    {
      fieldName: 'id',
@@ -22,6 +29,16 @@
        triggerFields: [''],
        show: () => false,
      },
    },
    {
      fieldName: 'userId',
      label: '调岗人员',
      component: markRaw(UserSelect),
      componentProps: {
        placeholder: '请选择调岗人员',
        onChange: onUserChange,
      },
      rules: 'selectRequired',
    },
    {
      fieldName: 'currentDeptId',
@@ -175,7 +192,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 },
src/views/hrm/transfer/detail/approve/index.vue
@@ -30,7 +30,7 @@
  bordered: true,
  column: 2,
  schema: [
    { label: '员工姓名', field: 'employeeName', render: textRender },
    { label: '调岗人员', field: 'userName', render: textRender },
    { label: '当前部门', field: 'currentDeptName', render: textRender },
    { label: '当前职位', field: 'currentPostName', render: textRender },
    { label: '目标部门', field: 'targetDeptName', render: textRender },
src/views/hrm/transfer/modules/form.vue
@@ -1,8 +1,12 @@
<script lang="ts" setup>
import type { FormType } from '../data';
import type { HrmTransferApi } from '#/api/hrm/transfer';
import type { SystemPostApi } from '#/api/system/post';
import type { SystemUserApi } from '#/api/system/user';
import { computed, ref } from 'vue';
import { useUserStore } from '@vben/stores';
import { useVbenModal } from '#/packages/effects/common-ui/src';
@@ -10,14 +14,15 @@
import { useVbenForm } from '#/adapter/form';
import { createTransfer, getTransfer, updateTransfer } from '#/api/hrm/transfer';
import { getEmployeeSimpleList } from '#/api/hrm/employee';
import { getSimplePostList } from '#/api/system/post';
import { getUser } from '#/api/system/user';
import { $t } from '#/locales';
import { useFormSchema } from '../data';
const emit = defineEmits(['success']);
const formType = ref<FormType>('create');
const currentEmployeeId = ref<number>();
const userStore = useUserStore();
const isDetail = computed(() => formType.value === 'detail');
const getTitle = computed(() => {
@@ -41,6 +46,44 @@
  showDefaultActions: false,
});
/** 岗位列表缓存(用于把岗位 ID 回显成名称) */
const postList = ref<SystemPostApi.Post[]>([]);
/** 根据岗位编号取岗位名称 */
async function getPostName(postId?: number) {
  if (!postId) {
    return undefined;
  }
  if (postList.value.length === 0) {
    postList.value = await getSimplePostList();
  }
  return postList.value.find((item) => item.id === postId)?.name;
}
/** 选择调岗人员后,自动带出其原部门、原岗位 */
async function fillCurrentByUser(user?: SystemUserApi.User) {
  if (!user?.id) {
    await formApi.setValues({
      currentDeptId: undefined,
      currentDeptName: undefined,
      currentPostId: undefined,
      currentPostName: undefined,
    });
    return;
  }
  // 选择组件带回的数据可能缺少部门名称 / 岗位,按编号再查一次用户详情
  const detail = !user.deptName || !user.postIds?.length
    ? await getUser(user.id)
    : user;
  const postId = detail.postIds?.[0] ? Number(detail.postIds[0]) : undefined;
  await formApi.setValues({
    currentDeptId: detail.deptId,
    currentDeptName: detail.deptName,
    currentPostId: postId,
    currentPostName: await getPostName(postId),
  });
}
const [Modal, modalApi] = useVbenModal({
  async onConfirm() {
    if (isDetail.value) {
@@ -53,7 +96,6 @@
    }
    modalApi.lock();
    const data = (await formApi.getValues()) as HrmTransferApi.Transfer;
    data.employeeId = currentEmployeeId.value;
    try {
      if (data.id) {
        await updateTransfer(data);
@@ -73,27 +115,21 @@
    }
    const data = modalApi.getData<{ formType: FormType; id?: number }>();
    formType.value = data.formType;
    formApi.setState({ schema: useFormSchema(data.formType) });
    formApi.setState({ schema: useFormSchema(data.formType, fillCurrentByUser) });
    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,
        });
      // 新增时默认带出当前登录人,并回填其原部门 / 原岗位
      const loginUserId = userStore.userInfo?.id;
      if (loginUserId) {
        formApi.setFieldValue('userId', loginUserId);
        await fillCurrentByUser(await getUser(loginUserId));
      }
      return;
    }
    modalApi.lock();
    try {
      const transfer = await getTransfer(data.id);
      currentEmployeeId.value = transfer.employeeId;
      await formApi.setValues(transfer);
      if (transfer.attachmentList?.length) {
        await formApi.setFieldValue('blobIds', transfer.attachmentList.map(item => ({
@@ -115,4 +151,4 @@
  <Modal :title="getTitle" class="w-[600px]">
    <Form class="mx-4" />
  </Modal>
</template>
</template>