feat(hrm): 调岗申请表单新增「调岗人」选择,选中后自动带出原部门/原岗位
- 表单新增「调岗人」下拉(可按姓名搜索),替代原先硬编码取第一个员工的临时逻辑
- 选择员工后自动填充原部门/原岗位(含ID与名称),只读展示
- 提交改为传 userId,修正与后端字段不一致导致调岗人为空的问题
- 列表/详情列改为 userName,标题统一为「调岗人 / 原部门 / 原岗位」
| | |
| | | id: number; |
| | | employeeNo: string; |
| | | name: string; |
| | | /** 部门ID */ |
| | | deptId?: number; |
| | | deptName?: string; |
| | | /** 岗位ID列表 */ |
| | | postIds?: number[]; |
| | | postName?: string; |
| | | employeeStatus?: number; |
| | | } |
| | | |
| | | /** 员工导入结果 */ |
| | |
| | | /** 调岗申请 */ |
| | | export interface Transfer { |
| | | id?: number; |
| | | employeeId?: number; |
| | | employeeName?: string; |
| | | /** 调岗人(员工ID) */ |
| | | userId?: number; |
| | | /** 调岗人姓名 */ |
| | | userName?: string; |
| | | currentDeptId?: number; |
| | | currentDeptName?: string; |
| | | currentPostId?: number; |
| | |
| | | |
| | | import { getDeptList } from '#/api/system/dept'; |
| | | import { getSimplePostList } from '#/api/system/post'; |
| | | import { getEmployeeSimpleList } from '#/api/hrm/employee'; |
| | | import { handleTree } from '#/packages/utils/src'; |
| | | |
| | | /** 表单类型 */ |
| | |
| | | }, |
| | | }, |
| | | { |
| | | 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: '选择调岗人后自动带出', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | component: 'Input', |
| | | componentProps: { |
| | | disabled: true, |
| | | placeholder: '自动获取', |
| | | placeholder: '选择调岗人后自动带出', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | 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 }, |
| | |
| | | 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 }, |
| | | { |
| | |
| | | |
| | | 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(() => { |
| | |
| | | } |
| | | 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: { |
| | |
| | | layout: 'horizontal', |
| | | schema: [], |
| | | showDefaultActions: false, |
| | | // 选择「调岗人」后,自动带出其当前部门 / 岗位 |
| | | async handleValuesChange(values: any, changedFields: string[]) { |
| | | if (changedFields?.includes('userId')) { |
| | | await fillCurrentPosition(values?.userId); |
| | | } |
| | | }, |
| | | }); |
| | | |
| | | const [Modal, modalApi] = useVbenModal({ |
| | |
| | | } |
| | | modalApi.lock(); |
| | | const data = (await formApi.getValues()) as HrmTransferApi.Transfer; |
| | | data.employeeId = currentEmployeeId.value; |
| | | try { |
| | | if (data.id) { |
| | | await updateTransfer(data); |
| | |
| | | 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), |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal :title="getTitle" class="w-[600px]"> |
| | | <Modal :title="getTitle" class="w-[700px]"> |
| | | <Form class="mx-4" /> |
| | | </Modal> |
| | | </template> |
| | | </template> |