编辑 | blame | 历史 | 原始文档

HRM 人力资源模块前端开发文档

概述

HRM模块包含员工管理、人事审批、考勤管理、薪酬管理四大功能模块。


一、员工管理

1.1 涉及页面

  • 员工列表页 hrm/employee/index.vue
  • 员工详情页 hrm/employee/detail.vue
  • 员工表单弹窗 hrm/employee/EmployeeForm.vue
  • 教育经历组件 hrm/employee/components/EducationList.vue
  • 工作经历组件 hrm/employee/components/WorkHistoryList.vue
  • 紧急联系人组件 hrm/employee/components/EmergencyContactList.vue

1.2 API

方法 路径 说明
GET /hrm/employee/page 员工分页列表
GET /hrm/employee/get 获取员工详情
POST /hrm/employee/create 新增员工(同步创建系统用户、教育经历、工作经历、紧急联系人)
PUT /hrm/employee/update 更新员工
DELETE /hrm/employee/delete 删除员工
GET /hrm/employee/education/list 获取教育经历列表
GET /hrm/employee/work-history/list 获取工作经历列表
GET /hrm/employee/emergency-contact/list 获取紧急联系人列表

注意:教育经历、工作经历、紧急联系人只在新增员工时同步添加,不提供单独维护接口。

1.3 员工分页查询

请求参数:

参数 类型 必填 说明
pageNo Integer 页码
pageSize Integer 每页数量
employeeNo String 员工编号
name String 员工姓名
deptId Long 部门ID
employeeStatus Integer 员工状态:1-在职,2-试用,3-离职

响应结构:

{
  "code": 0,
  "data": {
    "list": [
      {
        "id": 1,
        "deptId": 100,
        "deptName": "技术部",
        "postId": 1,
        "postName": "Java开发工程师",
        "employeeNo": "EMP001",
        "name": "张三",
        "gender": 1,
        "birthday": "1990-01-15",
        "phone": "13800138000",
        "email": "zhangsan@example.com",
        "idCard": "320102199001150011",
        "hireDate": "2020-03-01",
        "regularDate": "2020-06-01",
        "leaveDate": null,
        "employeeStatus": 1,
        "annualLeaveBalance": 5.00,
        "sickLeaveBalance": 10.00,
        "bankName": "中国工商银行",
        "bankAccount": "6222021234567890123",
        "address": "江苏省南京市",
        "createTime": "2024-01-01 10:00:00"
      }
    ],
    "total": 100
  }
}

1.4 员工表单数据

注意:新增员工时会自动创建系统用户账号,用户名和默认密码均为手机号。

data() {
  return {
    form: {
      id: undefined,
      deptId: undefined,
      postId: undefined,
      employeeNo: undefined,         // 系统自动生成
      name: undefined,
      gender: undefined,
      birthday: undefined,
      phone: undefined,              // 手机号作为系统用户账号,必填且唯一
      email: undefined,
      idCard: undefined,
      hireDate: undefined,
      regularDate: undefined,
      employeeStatus: 1,
      annualLeaveBalance: 0,
      sickLeaveBalance: 0,
      salaryStructureId: undefined,  // 薪酬结构ID
      baseSalary: undefined,         // 基本工资(用于薪酬核算)
      roleIds: [],                   // 角色ID列表(用于分配系统用户角色)
      bankName: undefined,
      bankAccount: undefined,
      address: undefined,
      remark: undefined
    },
    // 教育经历列表
    educationList: [],
    // 工作经历列表
    workHistoryList: [],
    // 紧急联系人列表
    emergencyContactList: [],
    // 角色选项列表
    roleOptions: []
  }
}

1.5 角色选择组件

<el-form-item label="用户角色" prop="roleIds">
  <el-select v-model="form.roleIds" multiple placeholder="请选择角色">
    <el-option v-for="role in roleOptions" :key="role.id" :label="role.name" :value="role.id" />
  </el-select>
</el-form-item>

获取角色列表接口:
GET /system/role/simple-list

1.6 教育经历表单

<el-table :data="educationList" border>
  <el-table-column label="学校名称" prop="schoolName" />
  <el-table-column label="专业" prop="major" />
  <el-table-column label="学历" prop="degree">
    <template #default="{ row }">
      <dict-tag :type="DICT_TYPE.HRM_DEGREE" :value="row.degree" />
    </template>
  </el-table-column>
  <el-table-column label="入学时间" prop="startDate" />
  <el-table-column label="毕业时间" prop="endDate" />
  <el-table-column label="证书编号" prop="certificateNo" />
  <el-table-column label="操作" width="120">
    <template #default="{ $index, row }">
      <el-button link type="primary" @click="editEducation($index)">编辑</el-button>
      <el-button link type="danger" @click="deleteEducation($index)">删除</el-button>
    </template>
  </el-table-column>
</el-table>

1.6 字典类型

字典类型 说明
hrm_degree 学历:1-高中,2-大专,3-本科,4-硕士,5-博士
hrm_employee_status 员工状态:1-在职,2-试用,3-离职
hrm_gender 性别:1-男,2-女

二、人事审批 - 请假申请

2.1 涉及页面

  • 请假申请列表页 hrm/approval/leave/index.vue
  • 请假申请表单弹窗 hrm/approval/leave/LeaveForm.vue

2.2 API

方法 路径 说明
GET /hrm/leave/page 请假申请分页列表
GET /hrm/leave/get 获取请假申请详情
POST /hrm/leave/create 新增请假申请(草稿)
PUT /hrm/leave/update 更新请假申请
DELETE /hrm/leave/delete 删除请假申请
POST /hrm/leave/submit 提交请假申请(发起审批)
POST /hrm/leave/cancel 撤销请假申请

2.3 请假申请表单数据

data() {
  return {
    form: {
      id: undefined,
      leaveType: undefined,        // 请假类型
      startTime: undefined,        // 开始时间
      endTime: undefined,          // 结束时间
      duration: undefined,         // 请假时长(天)
      reason: undefined,           // 请假原因
      fileUrl: undefined,          // 附件
      remark: undefined
    },
    leaveTypeOptions: [
      { value: 1, label: '事假' },
      { value: 2, label: '病假' },
      { value: 3, label: '年假' },
      { value: 4, label: '婚假' },
      { value: 5, label: '产假' },
      { value: 6, label: '丧假' }
    ]
  }
}

2.4 表单示例

<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
  <el-form-item label="请假类型" prop="leaveType">
    <el-select v-model="form.leaveType" placeholder="请选择请假类型">
      <el-option v-for="item in leaveTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
    </el-select>
  </el-form-item>
  <el-form-item label="开始时间" prop="startTime">
    <el-date-picker v-model="form.startTime" type="datetime" placeholder="请选择开始时间" />
  </el-form-item>
  <el-form-item label="结束时间" prop="endTime">
    <el-date-picker v-model="form.endTime" type="datetime" placeholder="请选择结束时间" @change="calcDuration" />
  </el-form-item>
  <el-form-item label="请假时长" prop="duration">
    <el-input-number v-model="form.duration" :precision="2" :min="0.5" :step="0.5" />
    <span style="margin-left: 10px;">天</span>
    <span v-if="form.leaveType === 3" style="margin-left: 10px; color: #999;">
      年假余额:{{ annualLeaveBalance }} 天
    </span>
  </el-form-item>
  <el-form-item label="请假原因" prop="reason">
    <el-input v-model="form.reason" type="textarea" :rows="3" placeholder="请输入请假原因" maxlength="500" show-word-limit />
  </el-form-item>
  <el-form-item label="附件" prop="fileUrl">
    <UploadFile v-model="form.fileUrl" />
  </el-form-item>
</el-form>

2.5 列表页状态标签

<dict-tag :type="DICT_TYPE.HRM_AUDIT_STATUS" :value="row.status" />
状态值 状态名 标签颜色
0 草稿 info
10 审批中 warning
20 审批通过 success
30 审批驳回 danger
40 已撤销 info

三、人事审批 - 调岗申请

3.1 涉及页面

  • 调岗申请列表页 hrm/approval/transfer/index.vue
  • 调岗申请表单弹窗 hrm/approval/transfer/TransferForm.vue

3.2 API

方法 路径 说明
GET /hrm/transfer/page 调岗申请分页列表
GET /hrm/transfer/get 获取调岗申请详情
POST /hrm/transfer/create 新增调岗申请(草稿)
PUT /hrm/transfer/update 更新调岗申请
DELETE /hrm/transfer/delete 删除调岗申请
POST /hrm/transfer/submit 提交调岗申请(发起审批)
POST /hrm/transfer/cancel 撤销调岗申请

3.3 调岗申请表单数据

data() {
  return {
    form: {
      id: undefined,
      currentDeptId: undefined,    // 原部门ID(自动获取当前员工部门)
      currentPostId: undefined,    // 原岗位ID(自动获取当前员工岗位)
      targetDeptId: undefined,     // 目标部门ID
      targetPostId: undefined,     // 目标岗位ID
      transferType: undefined,     // 调岗类型:1-平调,2-升职,3-降职
      effectiveDate: undefined,    // 生效日期
      reason: undefined,           // 调岗原因
      fileUrl: undefined,          // 附件
      remark: undefined
    },
    transferTypeOptions: [
      { value: 1, label: '平调' },
      { value: 2, label: '升职' },
      { value: 3, label: '降职' }
    ]
  }
}

3.4 表单示例

<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
  <el-row :gutter="20">
    <el-col :span="12">
      <el-form-item label="原部门">
        <el-input :value="currentDeptName" disabled />
      </el-form-item>
    </el-col>
    <el-col :span="12">
      <el-form-item label="原岗位">
        <el-input :value="currentPostName" disabled />
      </el-form-item>
    </el-col>
  </el-row>
  <el-row :gutter="20">
    <el-col :span="12">
      <el-form-item label="目标部门" prop="targetDeptId">
        <DeptTreeSelect v-model="form.targetDeptId" />
      </el-form-item>
    </el-col>
    <el-col :span="12">
      <el-form-item label="目标岗位" prop="targetPostId">
        <el-select v-model="form.targetPostId" placeholder="请选择目标岗位">
          <el-option v-for="post in postOptions" :key="post.id" :label="post.name" :value="post.id" />
        </el-select>
      </el-form-item>
    </el-col>
  </el-row>
  <el-form-item label="调岗类型" prop="transferType">
    <el-radio-group v-model="form.transferType">
      <el-radio v-for="item in transferTypeOptions" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
    </el-radio-group>
  </el-form-item>
  <el-form-item label="生效日期" prop="effectiveDate">
    <el-date-picker v-model="form.effectiveDate" type="date" placeholder="请选择生效日期" />
  </el-form-item>
  <el-form-item label="调岗原因" prop="reason">
    <el-input v-model="form.reason" type="textarea" :rows="3" placeholder="请输入调岗原因" maxlength="500" show-word-limit />
  </el-form-item>
</el-form>

四、人事审批 - 离职申请

4.1 涉及页面

  • 离职申请列表页 hrm/approval/resignation/index.vue
  • 离职申请表单弹窗 hrm/approval/resignation/ResignationForm.vue

4.2 API

方法 路径 说明
GET /hrm/resignation/page 离职申请分页列表
GET /hrm/resignation/get 获取离职申请详情
POST /hrm/resignation/create 新增离职申请(草稿)
PUT /hrm/resignation/update 更新离职申请
DELETE /hrm/resignation/delete 删除离职申请
POST /hrm/resignation/submit 提交离职申请(发起审批)
POST /hrm/resignation/cancel 撤销离职申请
PUT /hrm/resignation/handover 更新交接状态

4.3 离职申请表单数据

data() {
  return {
    form: {
      id: undefined,
      resignationType: undefined,    // 离职类型:1-主动离职,2-被动离职,3-合同到期
      expectedDate: undefined,       // 预计离职日期
      reason: undefined,             // 离职原因
      handoverUserId: undefined,     // 交接人ID
      fileUrl: undefined,            // 附件
      remark: undefined
    },
    resignationTypeOptions: [
      { value: 1, label: '主动离职' },
      { value: 2, label: '被动离职' },
      { value: 3, label: '合同到期' }
    ]
  }
}

4.4 交接状态

状态值 状态名
0 未开始
10 进行中
20 已完成

五、考勤管理

5.1 涉及页面

  • 考勤记录列表页 hrm/attendance/record/index.vue
  • 考勤记录导入弹窗 hrm/attendance/record/ImportForm.vue
  • 考勤异常申请页 hrm/attendance/exception/index.vue

5.2 API

方法 路径 说明
GET /hrm/attendance/record/page 考勤记录分页列表
GET /hrm/attendance/record/statistics 考勤统计(按月)
POST /hrm/attendance/record/import 导入考勤记录
GET /hrm/attendance/record/export 导出考勤记录
GET /hrm/attendance/exception/page 考勤异常申请分页列表
POST /hrm/attendance/exception/create 新增考勤异常申请
POST /hrm/attendance/exception/submit 提交考勤异常申请

5.3 考勤记录查询参数

data() {
  return {
    queryParams: {
      pageNo: 1,
      pageSize: 10,
      userId: undefined,          // 员工ID
      deptId: undefined,          // 部门ID
      date: [],                   // 考勤日期范围
      clockInType: undefined,     // 上班打卡类型
      clockOutType: undefined     // 下班打卡类型
    }
  }
}

5.4 考勤记录响应结构

{
  "code": 0,
  "data": {
    "list": [
      {
        "id": 1,
        "userId": 1,
        "userName": "张三",
        "deptId": 100,
        "deptName": "技术部",
        "date": "2024-01-15",
        "clockInTime": "2024-01-15 08:55:00",
        "clockOutTime": "2024-01-15 18:30:00",
        "clockInType": 1,
        "clockInTypeName": "正常",
        "clockOutType": 1,
        "clockOutTypeName": "正常",
        "workHours": 9.58,
        "overtimeHours": 0.50,
        "location": "公司总部",
        "dataSource": 1,
        "dataSourceName": "打卡"
      }
    ],
    "total": 100
  }
}

5.5 打卡类型

类型值 类型名 颜色
1 正常 success
2 迟到/早退 warning
3 缺卡 danger

5.6 导入模板

列名 必填 说明
员工编号
员工姓名
考勤日期 格式:yyyy-MM-dd
上班打卡时间 格式:HH:mm:ss
下班打卡时间 格式:HH:mm:ss
打卡地点
备注

六、薪酬管理

6.1 涉及页面

  • 薪酬结构配置页 hrm/salary/structure/index.vue
  • 员工薪酬档案页 hrm/salary/employee-salary/index.vue
  • 薪酬核算页 hrm/salary/calculation/index.vue
  • 薪资发放页 hrm/salary/payment/index.vue

6.2 薪酬核算API

方法 路径 说明
GET /hrm/salary/calculation/page 薪酬核算分页列表
POST /hrm/salary/calculation/calculate 执行薪酬核算(按周期)
POST /hrm/salary/calculation/confirm 确认薪酬核算
GET /hrm/salary/calculation/export 导出薪酬核算表

6.3 薪酬核算查询参数

data() {
  return {
    queryParams: {
      pageNo: 1,
      pageSize: 10,
      period: undefined,        // 核算周期(如 2024-01)
      userId: undefined,        // 员工ID
      deptId: undefined,        // 部门ID
      status: undefined         // 状态:0-待确认,10-已确认,20-已发放
    }
  }
}

6.4 薪酬核算响应结构

{
  "code": 0,
  "data": {
    "list": [
      {
        "id": 1,
        "no": "SC202401001",
        "period": "2024-01",
        "userId": 1,
        "userName": "张三",
        "deptId": 100,
        "deptName": "技术部",
        "baseSalary": 10000.00,
        "performanceSalary": 2000.00,
        "overtimePay": 500.00,
        "mealAllowance": 300.00,
        "transportAllowance": 200.00,
        "otherAllowance": 0.00,
        "socialSecurityDeduction": 1050.00,
        "housingFundDeduction": 1200.00,
        "taxDeduction": 290.00,
        "otherDeduction": 0.00,
        "actualSalary": 10460.00,
        "workDays": 22,
        "overtimeHours": 8.00,
        "status": 0,
        "statusName": "待确认"
      }
    ],
    "total": 100
  }
}

6.5 薪酬核算状态

状态值 状态名 颜色
0 待确认 warning
10 已确认 success
20 已发放 info

七、菜单配置

// router/modules/hrm.js
export default {
  path: '/hrm',
  component: Layout,
  name: 'Hrm',
  meta: { title: '人事管理', icon: 'ep:user' },
  children: [
    {
      path: 'employee',
      name: 'HrmEmployee',
      component: () => import('@/views/hrm/employee/index.vue'),
      meta: { title: '员工管理' }
    },
    {
      path: 'leave',
      name: 'HrmLeave',
      component: () => import('@/views/hrm/approval/leave/index.vue'),
      meta: { title: '请假申请' }
    },
    {
      path: 'transfer',
      name: 'HrmTransfer',
      component: () => import('@/views/hrm/approval/transfer/index.vue'),
      meta: { title: '调岗申请' }
    },
    {
      path: 'resignation',
      name: 'HrmResignation',
      component: () => import('@/views/hrm/approval/resignation/index.vue'),
      meta: { title: '离职申请' }
    },
    {
      path: 'attendance-record',
      name: 'HrmAttendanceRecord',
      component: () => import('@/views/hrm/attendance/record/index.vue'),
      meta: { title: '考勤记录' }
    },
    {
      path: 'attendance-exception',
      name: 'HrmAttendanceException',
      component: () => import('@/views/hrm/attendance/exception/index.vue'),
      meta: { title: '考勤异常' }
    },
    {
      path: 'salary-calculation',
      name: 'HrmSalaryCalculation',
      component: () => import('@/views/hrm/salary/calculation/index.vue'),
      meta: { title: '薪酬核算' }
    },
    {
      path: 'salary-payment',
      name: 'HrmSalaryPayment',
      component: () => import('@/views/hrm/salary/payment/index.vue'),
      meta: { title: '薪资发放' }
    }
  ]
}

八、API 接口文件

// api/hrm/employee.js
import request from '@/utils/request'

export function getEmployeePage(data) {
  return request({ url: '/hrm/employee/page', method: 'GET', params: data })
}

export function getEmployee(id) {
  return request({ url: '/hrm/employee/get', method: 'GET', params: { id } })
}

export function createEmployee(data) {
  return request({ url: '/hrm/employee/create', method: 'POST', data })
}

export function updateEmployee(data) {
  return request({ url: '/hrm/employee/update', method: 'PUT', data })
}

export function deleteEmployee(id) {
  return request({ url: '/hrm/employee/delete', method: 'DELETE', params: { id } })
}

// api/hrm/leave.js
import request from '@/utils/request'

export function getLeavePage(data) {
  return request({ url: '/hrm/leave/page', method: 'GET', params: data })
}

export function getLeave(id) {
  return request({ url: '/hrm/leave/get', method: 'GET', params: { id } })
}

export function createLeave(data) {
  return request({ url: '/hrm/leave/create', method: 'POST', data })
}

export function updateLeave(data) {
  return request({ url: '/hrm/leave/update', method: 'PUT', data })
}

export function deleteLeave(id) {
  return request({ url: '/hrm/leave/delete', method: 'DELETE', params: { id } })
}

export function submitLeave(id) {
  return request({ url: '/hrm/leave/submit', method: 'POST', params: { id } })
}

export function cancelLeave(id) {
  return request({ url: '/hrm/leave/cancel', method: 'POST', params: { id } })
}

// api/hrm/attendance.js
import request from '@/utils/request'

export function getAttendanceRecordPage(data) {
  return request({ url: '/hrm/attendance/record/page', method: 'GET', params: data })
}

export function importAttendanceRecord(data) {
  return request({ url: '/hrm/attendance/record/import', method: 'POST', data })
}

export function exportAttendanceRecord(data) {
  return request({ url: '/hrm/attendance/record/export', method: 'GET', params: data, responseType: 'blob' })
}

// api/hrm/salary.js
import request from '@/utils/request'

export function getSalaryCalculationPage(data) {
  return request({ url: '/hrm/salary/calculation/page', method: 'GET', params: data })
}

export function calculateSalary(data) {
  return request({ url: '/hrm/salary/calculation/calculate', method: 'POST', data })
}

export function confirmSalary(data) {
  return request({ url: '/hrm/salary/calculation/confirm', method: 'POST', data })
}

export function exportSalaryCalculation(data) {
  return request({ url: '/hrm/salary/calculation/export', method: 'GET', params: data, responseType: 'blob' })
}

九、BPM 流程集成

9.1 流程定义配置

需要在 BPM 系统中配置以下审批分类和流程定义:

业务类型 分类编码 流程定义Key 说明
请假申请 hrm_leave_approve hrm_leave 请假审批流程
调岗申请 hrm_transfer_approve hrm_transfer 调岗审批流程
离职申请 hrm_resignation_approve hrm_resignation 离职审批流程

9.2 提交审批接口

请假申请提交:

POST /hrm/leave/submit?id=1&processDefinitionKey=hrm_leave

获取可用流程定义列表:

GET /hrm/leave/approve-process-definition-list

响应示例:

[
  {
    "id": "hrm_leave:1:xxx",
    "key": "hrm_leave",
    "name": "请假审批流程",
    "version": 1
  }
]

9.3 审批状态流转

状态值 状态名 说明
0 草稿 新建未提交
10 审批中 已提交BPM流程
20 审批通过 BPM流程审批通过
30 审批驳回 BPM流程审批驳回
40 已撤销 BPM流程被撤销

十、注意事项

  1. 数据权限:列表查询会自动根据当前用户的部门权限过滤数据
  2. 审批流程:提交申请后,状态变为"审批中",需等待BPM流程完成
  3. 年假校验:请假类型为年假时,需校验年假余额是否充足
  4. 考勤导入:导入时会自动根据考勤规则判断打卡类型
  5. 薪酬核算:核算前需确保当月考勤数据已导入完成
  6. 数据追溯:所有操作都会记录操作日志,支持3个月数据追溯