.playwright-mcp/img.pngBinary files differ
.playwright-mcp/page-2026-07-21T07-05-51-287Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-21T07-06-20-697Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-21T07-06-46-253Z.pngBinary files differ
.playwright-mcp/page-2026-07-21T07-08-30-493Z.pngBinary files differ
.playwright-mcp/page-2026-07-21T07-08-59-408Z.pngBinary files differ
.playwright-mcp/page-2026-07-21T07-09-42-959Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-21T07-09-59-810Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-21T07-11-18-147Z.pngBinary files differ
.playwright-mcp/page-2026-07-21T07-13-43-647Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-21T07-14-06-572Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-21T07-14-13-732Z.pngBinary files differ
.playwright-mcp/page-2026-07-21T07-14-34-792Z.pngBinary files differ
.playwright-mcp/page-2026-07-21T07-57-24-131Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-29T06-40-35-404Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-29T06-42-11-724Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-29T06-42-36-804Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-29T06-43-35-225Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-29T06-47-24-223Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-29T06-47-38-983Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-29T06-47-57-125Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-29T06-51-00-932Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-29T06-56-04-077Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-29T06-56-14-335Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-29T07-10-45-745Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-29T07-12-31-548Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-29T07-14-24-445Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-29T07-14-44-587Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-07-29T07-14-58-476Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-03T09-16-38-621Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-03T09-20-27-740Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-03T09-20-36-226Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-03T09-22-30-620Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-03T09-22-42-679Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-03T09-22-54-018Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-04T07-44-03-300Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-04T07-44-19-942Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-04T07-44-38-346Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T07-36-48-990Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T07-36-56-155Z.pngBinary files differ
.playwright-mcp/page-2026-08-05T07-41-09-497Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T07-41-21-485Z.pngBinary files differ
.playwright-mcp/page-2026-08-05T07-51-48-188Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T07-54-21-100Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T07-58-12-325Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T07-58-23-056Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T08-54-54-463Z.yml
.playwright-mcp/page-2026-08-05T08-59-40-566Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-17-10-326Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-17-21-418Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-18-45-630Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-18-52-745Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-20-49-932Z.pngBinary files differ
.playwright-mcp/page-2026-08-05T09-25-58-846Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-27-33-763Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-27-39-409Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-29-05-292Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-29-11-606Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-33-00-314Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-39-43-280Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-39-54-145Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-40-09-408Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-40-13-937Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-40-19-588Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-40-24-098Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-40-28-333Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-40-33-342Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-40-42-217Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-40-49-786Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-53-15-917Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-53-22-647Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-53-30-790Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-05T09-53-35-271Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-12T08-14-30-909Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-12T08-14-46-176Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-12T08-15-00-361Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-12T08-16-45-289Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-14T05-18-36-135Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-14T05-18-50-100Z.yml
ÎļþÒÑɾ³ý .playwright-mcp/page-2026-08-14T05-19-08-995Z.yml
ÎļþÒÑɾ³ý sql/mysql/hrm_employee_contract_import_menu.sql
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,13 @@ -- åå·¥åå - å¯¼å ¥/å¯¼å ¥æ¨¡æ¿ æé®æé -- ç¶èåï¼åå·¥ååï¼parent_id = 1063105ï¼ -- åç §ï¼ååæ°å¢æé® id=1063107ï¼type=3, permission=hrm:employee-contract:createï¼ INSERT INTO system_menu (id, name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted) VALUES (1063300, 'ååå¯¼å ¥', 'hrm:employee-contract:import', 3, 5, 1063105, '', '#', '', NULL, 0, 1, 0, 1, '1', NOW(), '1', NOW(), 0); -- æäºè¶ 级管çåè§è²ï¼role_id=1ï¼è¯¥æé®æéï¼å¹çï¼ INSERT INTO system_role_menu (role_id, menu_id, creator, create_time, updater, update_time, deleted) SELECT 1, 1063300, '1', NOW(), '1', NOW(), 0 FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM system_role_menu WHERE role_id = 1 AND menu_id = 1063300); yudao-module-hrm-api/src/main/java/cn/iocoder/yudao/module/hrm/enums/ErrorCodeConstants.java
@@ -26,6 +26,11 @@ ErrorCode EMPLOYEE_CONTRACT_END_DATE_REQUIRE_FOR_FIXED = new ErrorCode(1_030_000_013, "åºå®æéååå¿ é¡»å¡«åç»ææ¥æ"); ErrorCode EMPLOYEE_CONTRACT_DATE_INVALID = new ErrorCode(1_030_000_014, "å忥æä¸åæ³ï¼å¼å§æ¥æä¸è½æäºç»ææ¥æ"); ErrorCode EMPLOYEE_CONTRACT_DATE_OVERLAP = new ErrorCode(1_030_000_015, "该å工卿鿶鴿®µå·²å卿ªè§£é¤/æªç»æ¢çååï¼è¯·å è§£é¤/ç»æ¢ååç¾è®¢"); ErrorCode EMPLOYEE_CONTRACT_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_030_000_016, "å¯¼å ¥åå·¥ååæ°æ®ä¸è½ä¸ºç©º"); ErrorCode EMPLOYEE_CONTRACT_IMPORT_FIELD_REQUIRED = new ErrorCode(1_030_000_017, "å¯¼å ¥åæ®µã{}ãä¸è½ä¸ºç©º"); ErrorCode EMPLOYEE_CONTRACT_IMPORT_EMPLOYEE_NAME_NOT_EXISTS = new ErrorCode(1_030_000_018, "åå·¥å§åã{}ãä¸åå¨ï¼è¯·å ç»´æ¤å工档æ¡"); ErrorCode EMPLOYEE_CONTRACT_IMPORT_EMPLOYEE_NAME_MULTIPLE = new ErrorCode(1_030_000_019, "åå·¥å§åã{}ã对åºå¤ä¸ªå工档æ¡ï¼æ æ³èªå¨å¹é ï¼è¯·å å¨é¡µé¢æå·¥ä¸ºè¯¥åå·¥æ°å¢åå"); ErrorCode EMPLOYEE_CONTRACT_IMPORT_CONTRACT_EXISTS = new ErrorCode(1_030_000_020, "该åå·¥ã{}ãå·²åå¨ç¸åç±»åãç¸åå¼å§æ¥æçååï¼å¦éè¦ç请å¾éâå·²å卿¶æ´æ°â"); // ========== 请åç³è¯· 1-030-001-000 ========== ErrorCode LEAVE_APPLICATION_NOT_EXISTS = new ErrorCode(1_030_001_000, "请åç³è¯·ä¸åå¨"); yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/employee/HrmEmployeeContractController.java
@@ -2,6 +2,10 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractImportExcelVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractImportReqVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractImportRespVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractPageReqVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractRespVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractSaveReqVO; @@ -11,10 +15,17 @@ import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.io.IOException; import java.math.BigDecimal; import java.time.LocalDate; import java.util.Arrays; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -81,4 +92,30 @@ return success(contractService.getExpiringCount()); } @GetMapping("/import-template") @Operation(summary = "ä¸è½½åå·¥ååå¯¼å ¥æ¨¡æ¿") @PreAuthorize("@ss.hasPermission('hrm:employee-contract:import')") public void importTemplate(HttpServletResponse response) throws IOException { // è¾åºç¤ºä¾æ°æ®ï¼æ¹ä¾¿ä½¿ç¨è åèãååç±»å/æéç±»åæåå ¸ä¸æå¡«å List<HrmEmployeeContractImportExcelVO> list = Arrays.asList( HrmEmployeeContractImportExcelVO.builder().name("å¼ ä¸").contractType(1).contractTermType(1) .signCompany("åéXXç§ææéå ¬å¸").signDate(LocalDate.of(2026, 1, 1)) .startDate(LocalDate.of(2026, 1, 1)).endDate(LocalDate.of(2028, 12, 31)) .probationStartDate(LocalDate.of(2026, 1, 1)).probationEndDate(LocalDate.of(2026, 6, 30)) .probationSalary(new BigDecimal("8000.00")).regularSalary(new BigDecimal("10000.00")) .remark("示ä¾ï¼è¯·æå®é ä¿®æ¹åå¯¼å ¥").build() ); ExcelUtils.write(response, "åå·¥ååå¯¼å ¥æ¨¡æ¿.xls", "åå·¥åå", HrmEmployeeContractImportExcelVO.class, list); } @PostMapping("/import") @Operation(summary = "å¯¼å ¥åå·¥åå", description = "æåå·¥å§å + ååç±»å + ååå¼å§æ¥æå¤å®ï¼å·²åå¨ä¸å¼å¯âå·²å卿¶æ´æ°âåè¦çæ´æ°è¯¥è¡") @PreAuthorize("@ss.hasPermission('hrm:employee-contract:import')") public CommonResult<HrmEmployeeContractImportRespVO> importExcel(@Valid HrmEmployeeContractImportReqVO importReqVO) throws Exception { List<HrmEmployeeContractImportExcelVO> list = ExcelUtils.read(importReqVO.getFile(), HrmEmployeeContractImportExcelVO.class); return success(contractService.importContractList(list, importReqVO)); } } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/employee/vo/HrmEmployeeContractImportExcelVO.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,61 @@ package cn.iocoder.yudao.module.hrm.controller.admin.employee.vo; import cn.idev.excel.annotation.ExcelProperty; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.math.BigDecimal; import java.time.LocalDate; /** * åå·¥åå Excel å¯¼å ¥ VO */ @Data @Builder @AllArgsConstructor @NoArgsConstructor public class HrmEmployeeContractImportExcelVO { @ExcelProperty("åå·¥å§å") private String name; @ExcelProperty(value = "ååç±»å", converter = DictConvert.class) @DictFormat("hrm_contract_type") private Integer contractType; @ExcelProperty(value = "ååæéç±»å", converter = DictConvert.class) @DictFormat("hrm_contract_term_type") private Integer contractTermType; @ExcelProperty("ç¾çº¦ä¸»ä½ï¼å ¬å¸å ¨ç§°ï¼") private String signCompany; @ExcelProperty("ç¾è®¢æ¥æ") private LocalDate signDate; @ExcelProperty("ååå¼å§æ¥æ") private LocalDate startDate; @ExcelProperty("ååç»ææ¥æ") private LocalDate endDate; @ExcelProperty("è¯ç¨æå¼å§æ¥æ") private LocalDate probationStartDate; @ExcelProperty("è¯ç¨æç»ææ¥æ") private LocalDate probationEndDate; @ExcelProperty("è¯ç¨æå·¥èµ") private BigDecimal probationSalary; @ExcelProperty("转æ£å·¥èµ") private BigDecimal regularSalary; @ExcelProperty("夿³¨") private String remark; } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/employee/vo/HrmEmployeeContractImportReqVO.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,19 @@ package cn.iocoder.yudao.module.hrm.controller.admin.employee.vo; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import lombok.Data; import org.springframework.web.multipart.MultipartFile; @Schema(description = "管çåå° - åå·¥ååå¯¼å ¥ Request VO") @Data public class HrmEmployeeContractImportReqVO { @Schema(description = "Excel æä»¶", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull(message = "Excel æä»¶ä¸è½ä¸ºç©º") private MultipartFile file; @Schema(description = "æ¯å¦è¦çæ´æ°ï¼å¹é å°ååå·¥ç¸åååç±»åä¸å¼å§æ¥æçåååè¦çæ´æ°ï¼ï¼é»è®¤ false", example = "true") private Boolean updateSupport = false; } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/employee/vo/HrmEmployeeContractImportRespVO.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,24 @@ package cn.iocoder.yudao.module.hrm.controller.admin.employee.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; import java.util.List; import java.util.Map; @Schema(description = "管çåå° - åå·¥ååå¯¼å ¥ Response VO") @Data @Builder public class HrmEmployeeContractImportRespVO { @Schema(description = "æ°å¢æåçå工忰ç»", requiredMode = Schema.RequiredMode.REQUIRED) private List<String> createNames; @Schema(description = "è¦çæ´æ°æåçå工忰ç»", requiredMode = Schema.RequiredMode.REQUIRED) private List<String> updateNames; @Schema(description = "å¯¼å ¥å¤±è´¥çåå·¥åéåï¼key 为åå·¥åï¼value 为失败åå ", requiredMode = Schema.RequiredMode.REQUIRED) private Map<String, String> failureNames; } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/employee/HrmEmployeeContractMapper.java
@@ -165,6 +165,24 @@ } /** * æ¥è¯¢å工卿ååç±»åãæå¼å§æ¥æä¸å·²åå¨çååï¼ç¨äºå¯¼å ¥æ¶å¤å®è¦çæ´æ°ï¼ï¼åææ°ä¸æ¡ * * @param employeeId åå·¥ID * @param contractType ååç±»å * @param startDate ååå¼å§æ¥æ * @return å·²åå¨çååï¼ä¸åå¨è¿å null */ default HrmEmployeeContractDO selectByEmployeeTypeStartDate(Long employeeId, Integer contractType, LocalDate startDate) { return selectOne(new LambdaQueryWrapperX<HrmEmployeeContractDO>() .eq(HrmEmployeeContractDO::getEmployeeId, employeeId) .eq(HrmEmployeeContractDO::getContractType, contractType) .eq(HrmEmployeeContractDO::getStartDate, startDate) .orderByDesc(HrmEmployeeContractDO::getId) .last("LIMIT 1")); } /** * æ¸ é¤è¯¥åå·¥å ¨é¨ååç"å½ååå"æ è®° * * @param employeeId åå·¥ID yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeContractService.java
@@ -1,10 +1,15 @@ package cn.iocoder.yudao.module.hrm.service.employee; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractImportExcelVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractImportReqVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractImportRespVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractPageReqVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractRespVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractSaveReqVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractTerminateReqVO; import java.util.List; /** * åå·¥åå Service æ¥å£ @@ -65,4 +70,16 @@ */ Long getExpiringCount(); /** * æ¹éå¯¼å ¥åå·¥åå * <p> * å¤å®è§åï¼æãåå·¥å§å + ååç±»å + ååå¼å§æ¥æã夿æ¯å¦åå¨ï¼åå¨ä¸å¼å¯ updateSupport æ¶è¦çæ´æ°è¯¥è¡ï¼ä¿çååç¼å·ï¼ï¼å¦åæ°å¢ã * * @param importContracts å¯¼å ¥çåå Excel è¡ * @param importReqVO å¯¼å ¥è¯·æ±ï¼å«æ¯å¦è¦çæ´æ°å¼å ³ï¼ * @return å¯¼å ¥ç»æï¼æ°å¢/æ´æ°æåå表ã失败æç»ï¼ */ HrmEmployeeContractImportRespVO importContractList(List<HrmEmployeeContractImportExcelVO> importContracts, HrmEmployeeContractImportReqVO importReqVO); } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeContractServiceImpl.java
@@ -2,26 +2,34 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractPageReqVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractRespVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractSaveReqVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractImportExcelVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractImportReqVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractImportRespVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractTerminateReqVO; import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeContractDO; import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeContractMapper; import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper; import cn.iocoder.yudao.module.hrm.dal.redis.HrmNoRedisDAO; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi; import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.time.LocalDate; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -50,11 +58,16 @@ @Resource private HrmEmployeeService employeeService; @Resource private HrmEmployeeMapper employeeMapper; @Resource private DeptApi deptApi; @Resource private StorageAttachmentApi storageAttachmentApi; @Resource private HrmNoRedisDAO noRedisDAO; @Resource @Lazy // èªæ³¨å ¥éå»¶è¿å è½½ï¼å¯¼å ¥æ¶éæ¡èµ°äºå¡è¾¹ç private HrmEmployeeContractService self; @Override @Transactional(rollbackFor = Exception.class) @@ -318,4 +331,101 @@ } } @Override public HrmEmployeeContractImportRespVO importContractList(List<HrmEmployeeContractImportExcelVO> importContracts, HrmEmployeeContractImportReqVO importReqVO) { // 1. è¿æ»¤åå·¥å§å为空çè¡ importContracts = importContracts.stream() .filter(item -> item.getName() != null && StrUtil.isNotBlank(item.getName().trim())) .collect(Collectors.toList()); if (CollUtil.isEmpty(importContracts)) { throw exception(EMPLOYEE_CONTRACT_IMPORT_LIST_IS_EMPTY); } // 2. é¢å è½½åå·¥å§å -> åå·¥æ¡£æ¡ æ å°ï¼å«å·²ç¦»èï¼ä¾¿äºè¡¥å½åå²ååï¼ Map<String, List<HrmEmployeeDO>> employeeNameMap = employeeMapper.selectList().stream() .filter(emp -> StrUtil.isNotBlank(emp.getName())) .collect(Collectors.groupingBy(emp -> emp.getName().trim(), LinkedHashMap::new, Collectors.toList())); // 3. éæ¡å¤çï¼å¹é å°åè¦çæ´æ°ï¼å¦åæ°å»º HrmEmployeeContractImportRespVO respVO = HrmEmployeeContractImportRespVO.builder() .createNames(new ArrayList<>()) .updateNames(new ArrayList<>()) .failureNames(new LinkedHashMap<>()) .build(); for (HrmEmployeeContractImportExcelVO importContract : importContracts) { String name = importContract.getName().trim(); try { // 3.1 åå·¥å§å转åå·¥ ID Long employeeId = parseEmployeeId(name, employeeNameMap); // 3.2 ç»è£ ä¿å请æ±ï¼å¿ å¡«åæ®µæ ¡éªï¼ HrmEmployeeContractSaveReqVO saveReqVO = buildImportSaveReqVO(importContract, employeeId); // 3.3 æãåå·¥ + ååç±»å + ååå¼å§æ¥æãå¤å®å·²åå¨ HrmEmployeeContractDO exist = contractMapper.selectByEmployeeTypeStartDate(employeeId, saveReqVO.getContractType(), saveReqVO.getStartDate()); if (exist == null) { self.createContract(saveReqVO); respVO.getCreateNames().add(name); } else { if (!Boolean.TRUE.equals(importReqVO.getUpdateSupport())) { respVO.getFailureNames().put(name, StrUtil.format(EMPLOYEE_CONTRACT_IMPORT_CONTRACT_EXISTS.getMsg(), saveReqVO.getStartDate().toString())); continue; } saveReqVO.setId(exist.getId()); self.updateContract(saveReqVO); respVO.getUpdateNames().add(name); } } catch (ServiceException ex) { respVO.getFailureNames().put(name, ex.getMessage()); } catch (Exception ex) { respVO.getFailureNames().put(name, ex.getMessage()); } } return respVO; } /** * åå·¥å§åè§£æä¸ºåå·¥ IDï¼éåæ¶æç¤ºéæå·¥å¤ç */ private Long parseEmployeeId(String name, Map<String, List<HrmEmployeeDO>> employeeNameMap) { List<HrmEmployeeDO> employees = employeeNameMap.get(name); if (CollUtil.isEmpty(employees)) { throw exception(EMPLOYEE_CONTRACT_IMPORT_EMPLOYEE_NAME_NOT_EXISTS, name); } if (employees.size() > 1) { throw exception(EMPLOYEE_CONTRACT_IMPORT_EMPLOYEE_NAME_MULTIPLE, name); } return employees.get(0).getId(); } /** * ç»è£ å¯¼å ¥ååä¿å请æ±å¹¶åå¿ å¡«åæ®µæ ¡éªï¼æ¥æé»è¾æ ¡éªäº¤ç± create/update å¤çï¼ */ private HrmEmployeeContractSaveReqVO buildImportSaveReqVO(HrmEmployeeContractImportExcelVO importContract, Long employeeId) { if (importContract.getContractType() == null) { throw exception(EMPLOYEE_CONTRACT_IMPORT_FIELD_REQUIRED, "ååç±»å"); } if (importContract.getContractTermType() == null) { throw exception(EMPLOYEE_CONTRACT_IMPORT_FIELD_REQUIRED, "ååæéç±»å"); } if (importContract.getStartDate() == null) { throw exception(EMPLOYEE_CONTRACT_IMPORT_FIELD_REQUIRED, "ååå¼å§æ¥æ"); } HrmEmployeeContractSaveReqVO reqVO = new HrmEmployeeContractSaveReqVO(); reqVO.setEmployeeId(employeeId); reqVO.setContractType(importContract.getContractType()); reqVO.setContractTermType(importContract.getContractTermType()); reqVO.setSignCompany(importContract.getSignCompany()); reqVO.setSignDate(importContract.getSignDate()); reqVO.setStartDate(importContract.getStartDate()); reqVO.setEndDate(importContract.getEndDate()); reqVO.setProbationStartDate(importContract.getProbationStartDate()); reqVO.setProbationEndDate(importContract.getProbationEndDate()); reqVO.setProbationSalary(importContract.getProbationSalary()); reqVO.setRegularSalary(importContract.getRegularSalary()); reqVO.setRemark(importContract.getRemark()); return reqVO; } }