# 员工合同管理 - 前端联调方案 ## 涉及页面 - 新增「员工合同」管理页:`views/hrm/employee/contract/index.vue` - 新增「员工合同」菜单(已配置后端菜单,挂载在 HRM → 人力资源 下、与「员工管理」平级,component = `hrm/employee/contract/index`;不要挂到「员工管理」下,否则该菜单会变成目录导致员工列表页无法直达) - 选择员工下拉:复用现有员工精简列表接口 - 员工详情页:新增「员工合同」Tab,展示该员工签订的全部合同(复用 `/hrm/employee-contract/page`,按 `employeeId` 过滤) ## 业务流程与数据带入 1. 创建合同:员工从 `/hrm/employee/simple-list` 下拉选择 → 自动带入员工(无需再选部门/岗位) 2. 续签合同:合同列表操作列「续签」按钮 → 自动带入该员工 + 上份合同的类型/期限/签约主体/工资,日期需重新填写;提交时显式传 `parentId` 指向被续签合同 3. 合同列表:按合同编号、员工、合同类型、期限类型、合同状态、到期类型筛选 3. 解除/终止:仅对"待生效/生效中/即将到期"的合同可操作,弹出确认框填写解除日期与原因 4. 到期提醒:列表支持「即将到期 / 已到期」快捷筛选;HRM 首页可调用 `expiring-count` 展示即将到期合同数量 ## API | 方法 | 路径 | 说明 | |------|------|------| | POST | /hrm/employee-contract/create | 新增合同 | | PUT | /hrm/employee-contract/update | 修改合同 | | PUT | /hrm/employee-contract/terminate | 解除/终止合同 | | DELETE | /hrm/employee-contract/delete | 删除合同 | | GET | /hrm/employee-contract/get | 合同详情(含附件) | | GET | /hrm/employee-contract/page | 合同分页 | | GET | /hrm/employee-contract/expiring-count | 即将到期合同数量(供待办/首页提醒) | ### 创建/修改合同 **请求参数(create/update 共用):** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | id | Long | 否 | 合同ID(修改时必传) | | employeeId | Long | 是 | 员工ID | | parentId | Long | 否 | 续签上一份合同ID。**续签按钮**点击时前端会传(指向被续签的合同);普通新增不传,后端自动关联该员工最近一份合同 | | contractType | Integer | 是 | 合同类型,字典 hrm_contract_type:1-劳动合同 2-劳务合同 3-实习协议 4-劳务派遣 5-其他 | | contractTermType | Integer | 是 | 期限类型,字典 hrm_contract_term_type:1-固定期限 2-无固定期限 3-以完成一定工作任务为期限 | | signCompany | String | 否 | 签约主体(公司全称) | | signDate | date | 否 | 签订日期 | | startDate | date | 是 | 合同开始日期 | | endDate | date | 否 | 合同结束日期(无固定期限可为空) | | probationStartDate | date | 否 | 试用期开始日期 | | probationEndDate | date | 否 | 试用期结束日期 | | probationSalary | BigDecimal | 否 | 试用期工资 | | regularSalary | BigDecimal | 否 | 转正工资 | | remark | String | 否 | 备注 | | blobIds | Array | 否 | 合同附件 blobId 列表 | **校验规则(后端强制):** - 期限类型 ≠ 无固定期限(2) 时,endDate 必填 - startDate 不能晚于 endDate;试用期开始不能晚于试用期结束 - 合同编号由后端自动生成(HT + 日期 + 序号),前端无需填写、不可修改 **响应示例:** ```json { "code": 0, "data": 1 } ``` ### 解除/终止合同 **请求参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | id | Long | 是 | 合同ID | | terminateStatus | Integer | 是 | 1-已解除 2-已终止 | | terminateDate | date | 是 | 解除/终止日期 | | terminateReason | String | 是 | 解除/终止原因 | **响应:** `{ "code": 0, "data": true }` ### 合同分页 **请求参数(筛选):** | 参数 | 类型 | 说明 | |------|------|------| | pageNo / pageSize | Integer | 分页参数 | | contractNo | String | 合同编号(模糊匹配) | | employeeId | Long | 员工ID | | contractType | Integer | 合同类型 | | contractTermType | Integer | 期限类型 | | terminateStatus | Integer | 0-正常 1-已解除 2-已终止 | | status | Integer | 合同状态(动态计算):1-待生效 2-生效中 3-即将到期 4-已到期 5-已解除 6-已终止 | | expiryType | Integer | 到期类型:1-即将到期 2-已到期(待办提醒用,与 status 互斥) | **响应字段新增:** | 字段 | 类型 | 说明 | |------|------|------| | contractNo | String | 合同编号(自动生成) | | parentId | Long | 续签上一份合同ID | | parentNo | String | 续签上一份合同编号(前端展示"续签自") | | isCurrent | Boolean | 是否员工当前生效合同(true 时前端打标) | | employeeName | String | 员工姓名(自动填充) | | employeeNo | String | 员工工号(自动填充) | | deptName | String | 部门名称(自动填充) | | status | Integer | 合同状态(后端按当前日期动态计算) | | attachmentList | Array | 附件列表(仅详情接口返回) | **响应示例:** ```json { "code": 0, "data": { "list": [ { "id": 1, "contractNo": "HT202608100001", "employeeId": 1, "employeeName": "张三", "employeeNo": "EMP202401010001", "deptName": "研发部", "contractType": 1, "contractTermType": 1, "startDate": "2026-01-01", "endDate": "2027-01-01", "status": 2, "terminateStatus": 0 } ], "total": 1 } } ``` ## 字段展示规则 | 字段 | 列表 | 表单 | 详情 | 说明 | |------|------|------|------|------| | 合同编号 | ✅ | 只读自动生成 | ✅ | HT + 日期 + 序号 | | 员工姓名 | ✅ | 下拉选择 | ✅ | 复用员工精简列表 | | 部门名称 | ✅ | 自动带入 | ✅ | 选择员工后展示 | | 合同类型 | ✅ | 下拉 | ✅ | 字典 hrm_contract_type | | 期限类型 | ✅ | 下拉 | ✅ | 字典 hrm_contract_term_type | | 签订日期 | ✅ | 日期 | ✅ | | | 开始/结束日期 | ✅ | 日期 | ✅ | 无固定期限结束日期可空 | | 试用期起止 | ✅ | 日期 | ✅ | | | 试用期/转正工资 | ✅ | 数字 | ✅ | | | 合同状态 | ✅ 标签 | - | ✅ | 动态计算,按颜色区分:生效中(绿)/即将到期(橙)/已到期(灰)/已解除·已终止(红)/待生效(蓝) | | 附件 | - | 上传 | ✅ | 走系统附件上传 | | 操作 | ✅ | - | - | 编辑 / 解除/终止 / 删除 | ## 附件对接流程 1. 上传:调用 `POST /system/storage-blob/upload` 获取 blobId 2. 保存合同:表单 `blobIds` 字段传 blobId 数组,后端绑定 3. 查询:详情接口返回 `attachmentList`;列表页如需单独刷新附件,可调用 `GET /system/storage-attachment/list?recordType=hrm_employee_contract&recordId=xxx` 4. 业务表不存文件地址,禁止在前端调用 `/infra/file/*` 旧接口 ## 业务规则说明 > **多合同设计**:一个员工可签订多次合同(续签/换签)。数据表通过 `parent_id`(续签上一份合同ID)形成续签链,通过 `is_current`(是否当前生效合同)标识员工当前合同;同一员工任意时刻仅一份 `is_current=true` 的合同。 | 场景 | 规则 | |------|------| | 状态计算 | 已解除(5)/已终止(6) > 已到期(4) > 待生效(1) > 即将到期(3) > 生效中(2),后端按当前日期动态计算,前端无需维护 | | 即将到期 | 结束日期在当天起的 30 天内(含当天)且未解除/终止 | | 续签关联 | 操作列「续签」按钮点击时前端显式传 `parent_id` 指向被续签合同;普通新增不传,后端自动把该员工最近一份合同作为 `parent_id`(续签链)。前端列表/详情展示"续签自 xxx" | | 当前合同 | 创建新合同时,后端自动清除该员工旧合同的 `is_current` 并置新合同为 true;解除/终止当前合同时自动清除标记 | | 时间重叠 | 后端强制校验:同一员工不能存在时间重叠的未解除/未终止合同(无固定期限视为无限长),报错"该员工在所选时间段已存在生效合同",需先解除/终止旧合同或调整日期 | | 解除/终止 | 仅未解除/未终止的合同可操作;已解除/已终止合同不可重复操作;操作后状态固定为已解除/已终止 | | 编辑限制 | 已解除/已终止的合同建议只读展示,不允许修改起止日期(后端未强制,前端提示即可) | | 删除 | 直接删除记录并级联删除附件 | | 到期提醒 | 列表「即将到期」筛选 = status=3 或 expiryType=1;首页可通过 expiring-count 展示数量 | | 员工维度 | 合同页按员工筛选可查看某员工全部合同;员工详情页「员工合同」Tab 展示该员工全部合同并标记当前合同 | ## 注意事项 - 合同编号唯一,由后端生成,前端不能修改 - 新增/编辑合同的校验(固定期限必须填结束日期、日期先后)由后端返回明确错误提示,前端表单校验可同步加上 - 列表状态列需根据 status 值映射字典 hrm_contract_status 展示中文与颜色 - 解除/终止操作需二次确认,避免误操作 - 分页查询附件列表为空时不返回该字段,前端需做空值兼容