yudao-module-hrm-api/src/main/java/cn/iocoder/yudao/module/hrm/enums/ErrorCodeConstants.java
@@ -125,6 +125,9 @@ ErrorCode SALARY_STRUCTURE_IN_USE = new ErrorCode(1_030_005_026, "èªé ¬ç»ææ£å¨è¢«å工使ç¨ï¼æ æ³å é¤"); ErrorCode OVERTIME_WAGE_CONFIG_NOT_EXISTS = new ErrorCode(1_030_005_027, "å²ä½å çå·¥èµé ç½®ä¸åå¨"); ErrorCode OVERTIME_WAGE_CONFIG_POST_EXISTS = new ErrorCode(1_030_005_028, "该å²ä½å·²é ç½®å çå·¥èµï¼è¯·å¿é夿·»å "); ErrorCode CONTRACT_TEMPLATE_TYPE_NOT_SUPPORT = new ErrorCode(1_030_005_029, "䏿¯æçå忍¡æ¿ç±»å"); ErrorCode CONTRACT_TEMPLATE_LOAD_FAILED = new ErrorCode(1_030_005_030, "å忍¡æ¿å 载失败"); ErrorCode EMPLOYEE_REGULARIZE_NEED_LABOR_CONTRACT = new ErrorCode(1_030_005_031, "该åå·¥å½ååå䏿¯å³å¨ååï¼æ æ³è½¬æ£"); // ========== çæ¬¡ç®¡ç 1-030-009-000 ========== ErrorCode SHIFT_NOT_EXISTS = new ErrorCode(1_030_009_000, "çæ¬¡ä¸åå¨"); yudao-module-hrm/pom.xml
@@ -70,6 +70,13 @@ <artifactId>yudao-spring-boot-starter-excel</artifactId> </dependency> <!-- Word å忍¡æ¿æ¸²æï¼poi-tlï¼ --> <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.12.2</version> </dependency> <!-- Test æµè¯ç¸å ³ --> <dependency> <groupId>cn.iocoder.boot</groupId> yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/employee/HrmEmployeeContractController.java
@@ -11,6 +11,11 @@ import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractSaveReqVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeContractTerminateReqVO; import cn.iocoder.yudao.module.hrm.service.employee.HrmEmployeeContractService; import cn.iocoder.yudao.module.hrm.service.employee.contract.ContractDocumentService; import cn.iocoder.yudao.module.hrm.service.employee.contract.ByteArrayMultipartFile; import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi; import cn.iocoder.yudao.module.system.service.storage.SystemStorageBlobService; import org.springframework.web.multipart.MultipartFile; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -22,12 +27,19 @@ import org.springframework.web.bind.annotation.*; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.util.Arrays; import java.util.Collections; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.CONTRACT_TEMPLATE_LOAD_FAILED; import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.CONTRACT_TEMPLATE_TYPE_NOT_SUPPORT; @Tag(name = "管çåå° - HRM åå·¥åå") @RestController @@ -37,6 +49,12 @@ @Resource private HrmEmployeeContractService contractService; @Resource private ContractDocumentService contractDocumentService; @Resource private SystemStorageBlobService storageBlobService; @Resource private StorageAttachmentApi storageAttachmentApi; @PostMapping("/create") @Operation(summary = "å建åå·¥åå") @@ -92,6 +110,72 @@ return success(contractService.getExpiringCount()); } @PostMapping("/generate") @Operation(summary = "çæååå¹¶åå为ååéä»¶") @Parameter(name = "id", description = "ååID", required = true) @Parameter(name = "templateType", description = "模æ¿ç±»åï¼1-å³å¨åå(ç®ç) 2-å³å¨åå(æ å) 3-å³å¡åå", required = true) @PreAuthorize("@ss.hasPermission('hrm:employee-contract:query')") public CommonResult<Long> generateContract(@RequestParam("id") Long id, @RequestParam("templateType") Integer templateType) { byte[] bytes = contractDocumentService.generateDocx(id, templateType); String fileName = contractDocumentService.buildFileName(id, templateType); MultipartFile file = new ByteArrayMultipartFile("file", fileName, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", bytes); Long blobId = storageBlobService.upload(Collections.singletonList(file), false).get(0).getId(); storageAttachmentApi.bindAttachments("file", "hrm_employee_contract", id, Collections.singletonList(blobId)); return success(blobId); } @GetMapping("/generate-docx") @Operation(summary = "çæå¹¶ä¸è½½ååææ¡£ï¼docxï¼") @Parameter(name = "id", description = "ååID", required = true) @Parameter(name = "templateType", description = "模æ¿ç±»åï¼1-å³å¨åå(ç®ç) 2-å³å¨åå(æ å) 3-å³å¡åå", required = true) @PreAuthorize("@ss.hasPermission('hrm:employee-contract:query')") public void generateDocx(@RequestParam("id") Long id, @RequestParam("templateType") Integer templateType, HttpServletResponse response) throws IOException { byte[] bytes = contractDocumentService.generateDocx(id, templateType); String fileName = URLEncoder.encode(contractDocumentService.buildFileName(id, templateType), StandardCharsets.UTF_8); response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); response.setHeader("Content-Disposition", "attachment; filename=" + fileName + "; filename*=UTF-8''" + fileName); response.getOutputStream().write(bytes); } @GetMapping("/download-template") @Operation(summary = "ä¸è½½ååç©ºç½æ¨¡æ¿", description = "1-å³å¨åå(ç®ç) 2-å³å¨åå(æ å) 3-å³å¡åå") @Parameter(name = "type", description = "模æ¿ç±»åï¼1-å³å¨åå(ç®ç) 2-å³å¨åå(æ å) 3-å³å¡åå", required = true) @PreAuthorize("@ss.hasPermission('hrm:employee-contract:query')") public void downloadTemplate(@RequestParam("type") Integer type, HttpServletResponse response) throws IOException { String path; String fileName; String contentType; if (type == 1) { path = "template/contract/original/labor_simple.docx"; fileName = "å³å¨åå(ç®ç).docx"; contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; } else if (type == 2) { path = "template/contract/original/labor_standard.docx"; fileName = "å³å¨åå(æ å).docx"; contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; } else if (type == 3) { path = "template/contract/original/service.doc"; fileName = "å³å¡åå.doc"; contentType = "application/msword"; } else { throw exception(CONTRACT_TEMPLATE_TYPE_NOT_SUPPORT); } try (InputStream in = getClass().getClassLoader().getResourceAsStream(path)) { if (in == null) { throw exception(CONTRACT_TEMPLATE_LOAD_FAILED); } byte[] bytes = in.readAllBytes(); String enc = URLEncoder.encode(fileName, StandardCharsets.UTF_8); response.setContentType(contentType); response.setHeader("Content-Disposition", "attachment; filename=" + enc + "; filename*=UTF-8''" + enc); response.getOutputStream().write(bytes); } } @GetMapping("/import-template") @Operation(summary = "ä¸è½½åå·¥ååå¯¼å ¥æ¨¡æ¿") @PreAuthorize("@ss.hasPermission('hrm:employee-contract:import')") yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/employee/HrmEmployeeController.java
@@ -222,4 +222,22 @@ return success(employeeService.importEmployeeList(list, importReqVO)); } @PutMapping("/regular") @Operation(summary = "å工转æ£", description = "ä» ãå³å¨ååãåå·¥å¯è½¬æ£ï¼å³å¡ååä¸è½¬æ£ã转æ£åªæ¹ç¶æ+è½¬æ£æ¥æï¼ä¸å«è°å²") @Parameter(name = "id", description = "åå·¥ID", required = true) @PreAuthorize("@ss.hasPermission('hrm:employee:update')") public CommonResult<Boolean> regularizeEmployee(@RequestParam("id") Long id) { employeeService.regularizeEmployee(id); return success(true); } @GetMapping("/regularize-reminders") @Operation(summary = "è·å¾å¾ è½¬æ£æéå表", description = "è¯ç¨ä¸ãä¸å½å为å³å¨ååãè¯ç¨æå¨ days 天å å°æçåå·¥") @PreAuthorize("@ss.hasPermission('hrm:employee:query')") public CommonResult<List<HrmEmployeeRespVO>> getRegularizeReminders( @RequestParam(value = "days", required = false, defaultValue = "7") Integer days) { List<HrmEmployeeDO> list = employeeService.getRegularizeReminderList(days); return success(BeanUtils.toBean(list, HrmEmployeeRespVO.class)); } } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/employee/vo/HrmEmployeeImportExcelVO.java
@@ -8,6 +8,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import java.math.BigDecimal; import java.time.LocalDate; /** @@ -45,6 +46,10 @@ @DictFormat("hrm_employee_status") private Integer employeeStatus; @ExcelProperty(value = "å工类å«", converter = DictConvert.class) @DictFormat("hrm_employee_category") private Integer employeeCategory; @ExcelProperty("身份è¯å·") private String idCard; @@ -72,4 +77,16 @@ @ExcelProperty("夿³¨") private String remark; @ExcelProperty("åºæ¬å·¥èµ") private BigDecimal baseSalary; @ExcelProperty("弿·é¶è¡") private String bankName; @ExcelProperty("é¶è¡è´¦å·") private String bankAccount; @ExcelProperty("å± ä½å°å") private String address; } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/employee/vo/HrmEmployeeRespVO.java
@@ -46,7 +46,7 @@ @Schema(description = "æ§å«") @ExcelProperty(value = "æ§å«", converter = DictConvert.class) @DictFormat("system_user_sex") @DictFormat("hrm_gender") private Integer gender; @Schema(description = "åºçæ¥æ") @@ -54,7 +54,7 @@ private LocalDate birthday; @Schema(description = "ææºå·ç ") @ExcelProperty("ææºå·ç ") @ExcelProperty("ææºå·") private String phone; @Schema(description = "é®ç®±") @@ -126,7 +126,7 @@ private List<Long> roleIds; @Schema(description = "è§è²åç§°å表") @ExcelProperty("è§è²") @ExcelProperty("ç¨æ·è§è²") private String roleNames; @Schema(description = "弿·é¶è¡") yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeService.java
@@ -115,4 +115,19 @@ HrmEmployeeImportRespVO importEmployeeList(List<HrmEmployeeImportExcelVO> importEmployees, HrmEmployeeImportReqVO importReqVO); /** * å工转æ£ï¼ä» ãå³å¨ååãå¯è½¬æ£ï¼å³å¡ååä¸å¯ï¼ï¼ç¶æ è¯ç¨ -> å¨èï¼è®°å½è½¬æ£æ¥æ * * @param id åå·¥ID */ void regularizeEmployee(Long id); /** * è·å¾å¾ è½¬æ£æéå表ï¼è¯ç¨ä¸ãä¸å½å为å³å¨ååãè¯ç¨æå¨ days 天å å°æçåå·¥ * * @param days æåå¤©æ° * @return åå·¥å表 */ List<HrmEmployeeDO> getRegularizeReminderList(Integer days); } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java
@@ -6,6 +6,7 @@ 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.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeEducationSaveReqVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeEmergencyContactSaveReqVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeImportExcelVO; @@ -16,10 +17,12 @@ import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeSaveReqVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeSimpleRespVO; import cn.iocoder.yudao.module.hrm.controller.admin.employee.vo.HrmEmployeeWorkHistorySaveReqVO; 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.dataobject.employee.HrmEmployeeEducationDO; import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeEmergencyContactDO; import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeWorkHistoryDO; import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeContractMapper; import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeEducationMapper; import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeEmergencyContactMapper; import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper; @@ -42,6 +45,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.time.LocalDate; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -68,6 +72,8 @@ @Resource private HrmEmployeeMapper employeeMapper; @Resource private HrmEmployeeContractMapper contractMapper; @Resource private HrmEmployeeEducationMapper educationMapper; @Resource @@ -475,6 +481,11 @@ reqVO.setEducation(importEmployee.getEducation()); reqVO.setPoliticalStatus(importEmployee.getPoliticalStatus()); reqVO.setRemark(importEmployee.getRemark()); reqVO.setEmployeeCategory(importEmployee.getEmployeeCategory()); reqVO.setBaseSalary(importEmployee.getBaseSalary()); reqVO.setBankName(importEmployee.getBankName()); reqVO.setBankAccount(importEmployee.getBankAccount()); reqVO.setAddress(importEmployee.getAddress()); return reqVO; } @@ -530,4 +541,57 @@ return roleIds; } // ========== è½¬æ£ ========== @Override public void regularizeEmployee(Long id) { validateEmployee(id); HrmEmployeeContractDO contract = findCurrentContract(id); // ä» ãå³å¨ååãå¯è½¬æ£ï¼å³å¡ååä¸è½¬æ£ if (contract == null || !Integer.valueOf(1).equals(contract.getContractType())) { throw exception(EMPLOYEE_REGULARIZE_NEED_LABOR_CONTRACT); } HrmEmployeeDO updateObj = new HrmEmployeeDO(); updateObj.setId(id); updateObj.setEmployeeStatus(1); // 1-å¨è updateObj.setRegularDate(LocalDate.now()); employeeMapper.updateById(updateObj); } @Override public List<HrmEmployeeDO> getRegularizeReminderList(Integer days) { int aheadDays = days == null ? 7 : days; LocalDate limit = LocalDate.now().plusDays(aheadDays); // è¯ç¨ä¸çåå·¥ List<HrmEmployeeDO> trials = employeeMapper.selectList( new LambdaQueryWrapperX<HrmEmployeeDO>().eq(HrmEmployeeDO::getEmployeeStatus, 2)); List<HrmEmployeeDO> result = new ArrayList<>(); for (HrmEmployeeDO employee : trials) { HrmEmployeeContractDO contract = findCurrentContract(employee.getId()); // ä» å³å¨ååãä¸è¯ç¨æå³å°å°æ if (contract == null || !Integer.valueOf(1).equals(contract.getContractType())) { continue; } LocalDate probationEnd = contract.getProbationEndDate(); if (probationEnd != null && !probationEnd.isAfter(limit)) { result.add(employee); } } return result; } /** æ¥è¯¢åå·¥å½åçæåå */ private HrmEmployeeContractDO findCurrentContract(Long employeeId) { List<HrmEmployeeContractDO> list = contractMapper.selectListByEmployee(employeeId); if (CollUtil.isEmpty(list)) { return null; } for (HrmEmployeeContractDO contract : list) { if (Boolean.TRUE.equals(contract.getIsCurrent())) { return contract; } } return null; } } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/contract/ByteArrayMultipartFile.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,71 @@ package cn.iocoder.yudao.module.hrm.service.employee.contract; import org.springframework.web.multipart.MultipartFile; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; /** * åèæ°ç»ç MultipartFileï¼æå åä¸çåèå è£ æ MultipartFileï¼ * 便äºå¤ç¨ system ç SystemStorageBlobService.upload(...) å卿件并æ¿å° blobIdã */ public class ByteArrayMultipartFile implements MultipartFile { private final String name; private final String originalFilename; private final String contentType; private final byte[] content; public ByteArrayMultipartFile(String name, String originalFilename, String contentType, byte[] content) { this.name = name; this.originalFilename = originalFilename; this.contentType = contentType; this.content = content == null ? new byte[0] : content; } @Override public String getName() { return name; } @Override public String getOriginalFilename() { return originalFilename; } @Override public String getContentType() { return contentType; } @Override public boolean isEmpty() { return content.length == 0; } @Override public long getSize() { return content.length; } @Override public byte[] getBytes() { return content; } @Override public InputStream getInputStream() { return new ByteArrayInputStream(content); } @Override public void transferTo(File dest) throws IOException { try (FileOutputStream fos = new FileOutputStream(dest)) { fos.write(content); } } } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/contract/ContractDocumentService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,26 @@ package cn.iocoder.yudao.module.hrm.service.employee.contract; /** * åå·¥ååææ¡£çæ Service * * æåå + åå·¥æ°æ®ï¼å¥ç¨ Word 模æ¿çæå³å¨åå / å³å¡åå docxã * * @author è¶ çº§ç®¡çå */ public interface ContractDocumentService { /** * çæåå docx * * @param contractId ååç¼å· * @param templateType 模æ¿ç±»åï¼1-å³å¨åå(ç®ç) 2-å³å¨åå(æ å) 3-å³å¡åå * @return docx åè */ byte[] generateDocx(Long contractId, Integer templateType); /** * çææä»¶å */ String buildFileName(Long contractId, Integer templateType); } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/contract/ContractDocumentServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,204 @@ package cn.iocoder.yudao.module.hrm.service.employee.contract; 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 com.deepoove.poi.XWPFTemplate; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.math.BigDecimal; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.HashMap; import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.CONTRACT_TEMPLATE_LOAD_FAILED; import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.CONTRACT_TEMPLATE_TYPE_NOT_SUPPORT; /** * åå·¥ååææ¡£çæ Service å®ç°ç±» * * @author è¶ çº§ç®¡çå */ @Slf4j @Service public class ContractDocumentServiceImpl implements ContractDocumentService { /** å³å¨ååï¼ç®çÂ·ç¤¾ä¿æç°ï¼ */ public static final int TYPE_LABOR_SIMPLE = 1; /** å³å¨ååï¼æ åÂ·å®æ¹å¶å¼ï¼ */ public static final int TYPE_LABOR_STANDARD = 2; /** å³å¡åå */ public static final int TYPE_SERVICE = 3; private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyyå¹´MMæddæ¥"); private static final Map<Integer, String> TEMPLATE_PATHS = Map.of( TYPE_LABOR_SIMPLE, "template/contract/contract_labor_simple.docx", TYPE_LABOR_STANDARD, "template/contract/contract_labor_standard.docx", TYPE_SERVICE, "template/contract/contract_service.docx"); private static final Map<Integer, String> TEMPLATE_NAMES = Map.of( TYPE_LABOR_SIMPLE, "å³å¨åå(ç®ç)", TYPE_LABOR_STANDARD, "å³å¨åå(æ å)", TYPE_SERVICE, "å³å¡åå"); @Resource private HrmEmployeeContractMapper contractMapper; @Resource private HrmEmployeeMapper employeeMapper; @Override public byte[] generateDocx(Long contractId, Integer templateType) { HrmEmployeeContractDO contract = contractMapper.selectById(contractId); if (contract == null) { throw exception(CONTRACT_TEMPLATE_LOAD_FAILED); } HrmEmployeeDO employee = contract.getEmployeeId() == null ? null : employeeMapper.selectById(contract.getEmployeeId()); Map<String, Object> vars = buildVariables(contract, employee); String path = TEMPLATE_PATHS.get(templateType); if (path == null) { throw exception(CONTRACT_TEMPLATE_TYPE_NOT_SUPPORT); } try (InputStream in = getClass().getClassLoader().getResourceAsStream(path)) { if (in == null) { throw exception(CONTRACT_TEMPLATE_LOAD_FAILED); } XWPFTemplate template = XWPFTemplate.compile(in).render(vars); ByteArrayOutputStream out = new ByteArrayOutputStream(); template.write(out); template.close(); return out.toByteArray(); } catch (Exception e) { log.error("[generateDocx][åå({}) 模æ¿({}) çæå¤±è´¥]", contractId, templateType, e); throw exception(CONTRACT_TEMPLATE_LOAD_FAILED); } } @Override public String buildFileName(Long contractId, Integer templateType) { HrmEmployeeContractDO contract = contractMapper.selectById(contractId); String no = contract != null && contract.getContractNo() != null ? contract.getContractNo() : String.valueOf(contractId); String name = TEMPLATE_NAMES.getOrDefault(templateType, "åå"); return no + "-" + name + ".docx"; } private Map<String, Object> buildVariables(HrmEmployeeContractDO contract, HrmEmployeeDO employee) { Map<String, Object> vars = new HashMap<>(); // ç²æ¹ï¼å ¬å¸ï¼ââ ç®ååç¾çº¦ä¸»ä½ï¼å ¶ä½ç空åç»å¯æ¥å ¥å ¬å¸é ç½® vars.put("companyName", nvl(contract.getSignCompany())); vars.put("companyAddress", ""); vars.put("legalPerson", ""); vars.put("companyPhone", ""); vars.put("creditCode", ""); // 乿¹ï¼åå·¥ï¼ vars.put("employeeName", employee != null ? nvl(employee.getName()) : ""); vars.put("gender", employee != null ? genderText(employee.getGender()) : ""); vars.put("age", employee != null ? nvl(employee.getAge()) : ""); vars.put("idCard", employee != null ? nvl(employee.getIdCard()) : ""); vars.put("householdAddress", employee != null ? nvl(employee.getAddress()) : ""); vars.put("address", employee != null ? nvl(employee.getAddress()) : ""); vars.put("phone", employee != null ? nvl(employee.getPhone()) : ""); vars.put("emergencyPhone", ""); // åå vars.put("contractNo", nvl(contract.getContractNo())); vars.put("postName", ""); vars.put("postDuty", ""); vars.put("workPlace", ""); vars.put("contractStart", formatDate(contract.getStartDate())); vars.put("contractEnd", formatDate(contract.getEndDate())); vars.put("contractMonths", monthsBetween(contract.getStartDate(), contract.getEndDate())); vars.put("probationStart", formatDate(contract.getProbationStartDate())); vars.put("probationEnd", formatDate(contract.getProbationEndDate())); vars.put("probationMonths", monthsBetween(contract.getProbationStartDate(), contract.getProbationEndDate())); vars.put("probationDays", daysBetween(contract.getProbationStartDate(), contract.getProbationEndDate())); vars.put("birthday", employee != null ? formatDate(employee.getBirthday()) : ""); // å¹´ææ¥ï¼ä¾ã___å¹´___æ___æ¥ãéæ ¼å¡«åï¼ vars.put("contractStartY", y(contract.getStartDate())); vars.put("contractStartM", mo(contract.getStartDate())); vars.put("contractStartD", d(contract.getStartDate())); vars.put("contractEndY", y(contract.getEndDate())); vars.put("contractEndM", mo(contract.getEndDate())); vars.put("contractEndD", d(contract.getEndDate())); vars.put("probationStartY", y(contract.getProbationStartDate())); vars.put("probationStartM", mo(contract.getProbationStartDate())); vars.put("probationStartD", d(contract.getProbationStartDate())); vars.put("probationEndY", y(contract.getProbationEndDate())); vars.put("probationEndM", mo(contract.getProbationEndDate())); vars.put("probationEndD", d(contract.getProbationEndDate())); vars.put("probationSalary", nvl(contract.getProbationSalary())); vars.put("regularSalary", nvl(contract.getRegularSalary())); vars.put("baseSalary", nvl(contract.getRegularSalary())); vars.put("performanceSalary", ""); vars.put("socialSecuritySalary", ""); vars.put("signDate", formatDate(contract.getSignDate())); // å³å¡ååéçå¯é项 vars.put("payType", "ä¸"); vars.put("payDay", ""); vars.put("workVolume", ""); vars.put("workAmount", ""); vars.put("piecePrice", ""); vars.put("noticeCompensation", ""); vars.put("copies", "两"); vars.put("eachCopies", "ä¸"); return vars; } private static String nvl(Object o) { return o == null ? "" : o.toString(); } private static String formatDate(LocalDate d) { return d == null ? "" : d.format(DATE_FMT); } private static String monthsBetween(LocalDate start, LocalDate end) { if (start == null || end == null) { return ""; } long months = ChronoUnit.MONTHS.between(start, end); return String.valueOf(Math.max(months, 0)); } private static String daysBetween(LocalDate start, LocalDate end) { if (start == null || end == null) { return ""; } long days = ChronoUnit.DAYS.between(start, end); return String.valueOf(Math.max(days, 0)); } private static String y(LocalDate date) { return date == null ? "" : String.format("%04d", date.getYear()); } private static String mo(LocalDate date) { return date == null ? "" : String.format("%02d", date.getMonthValue()); } private static String d(LocalDate date) { return date == null ? "" : String.format("%02d", date.getDayOfMonth()); } private static String genderText(Integer sex) { if (sex == null) { return ""; } return sex == 1 ? "ç·" : sex == 2 ? "女" : ""; } // å ¼å®¹ BigDecimal ç´æ¥ toString private static String nvl(BigDecimal v) { return v == null ? "" : v.toPlainString(); } } yudao-module-hrm/src/main/resources/template/contract/contract_labor_simple.docxBinary files differ
yudao-module-hrm/src/main/resources/template/contract/contract_labor_standard.docxBinary files differ
yudao-module-hrm/src/main/resources/template/contract/contract_service.docxBinary files differ
yudao-module-hrm/src/main/resources/template/contract/original/labor_simple.docxBinary files differ
yudao-module-hrm/src/main/resources/template/contract/original/labor_standard.docxBinary files differ
yudao-module-hrm/src/main/resources/template/contract/original/service.docBinary files differ