sql/mysql/hrm_transfer_application_nullable_current.sql
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,41 @@ -- ============================================= -- è°å²ç³è¯·ï¼å 许ãåé¨é¨ããåå²ä½ã为空 -- -- é®é¢ï¼hrm_transfer_application.current_dept_id / current_post_id 为 NOT NULL 䏿 é»è®¤å¼ï¼ -- è客æ·ç¯å¢ 133 个åå·¥å ¨é¨æ²¡æé ç½®å²ä½ï¼hrm_employee.post_id 为 NULLï¼ï¼ -- å端æäº¤è°å²ç³è¯·æ¶è¿ä¸¤ä¸ªå段为空 â insert æ¥ -- "Field 'current_post_id' doesn't have a default value" â è°å²ç³è¯·ä¸ç´æäº¤å¤±è´¥ã -- -- å¤çï¼æè¿ä¸¤åæ¹ä¸ºå 许 NULLãåé¨é¨/åå²ä½å±äºãç³è¯·æ¶çå¿«ç §ãï¼åå·¥æ¡£æ¡æªé ç½®æ¶ä¸ºç©ºæ¯åççï¼ -- ä¸åºå æ¤é»æç³è¯·ãç®æ é¨é¨/ç®æ å²ä½ä»ä¿æ NOT NULLï¼åç«¯å¿ å¡«ï¼å±äºä¸å¡å¿ éï¼ã -- -- èæ¬å¯é夿§è¡ï¼å¹çï¼ -- ============================================= SET NAMES utf8mb4; SET @sch := DATABASE(); -- 1. åå²ä½å 许为空 SET @nullable := (SELECT IS_NULLABLE FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @sch AND TABLE_NAME = 'hrm_transfer_application' AND COLUMN_NAME = 'current_post_id'); SET @sql := IF(@nullable = 'NO', 'ALTER TABLE `hrm_transfer_application` MODIFY COLUMN `current_post_id` bigint NULL DEFAULT NULL COMMENT ''åå²ä½IDï¼åå·¥æªé ç½®å²ä½æ¶ä¸ºç©ºï¼''', 'SELECT ''current_post_id å·²å 许为空'' AS msg'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- 2. åé¨é¨å 许为空 SET @nullable := (SELECT IS_NULLABLE FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @sch AND TABLE_NAME = 'hrm_transfer_application' AND COLUMN_NAME = 'current_dept_id'); SET @sql := IF(@nullable = 'NO', 'ALTER TABLE `hrm_transfer_application` MODIFY COLUMN `current_dept_id` bigint NULL DEFAULT NULL COMMENT ''åé¨é¨IDï¼åå·¥æªé ç½®é¨é¨æ¶ä¸ºç©ºï¼''', 'SELECT ''current_dept_id å·²å 许为空'' AS msg'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- 3. æ ¸å¯¹ SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_DEFAULT, COLUMN_COMMENT FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @sch AND TABLE_NAME = 'hrm_transfer_application' AND COLUMN_NAME IN ('current_dept_id','current_post_id','target_dept_id','target_post_id') ORDER BY ORDINAL_POSITION; SELECT 'è°å²ç³è¯· åé¨é¨/åå²ä½ å 许为空 åå§å宿' AS result; yudao-module-hrm-api/src/main/java/cn/iocoder/yudao/module/hrm/enums/ErrorCodeConstants.java
@@ -52,6 +52,7 @@ ErrorCode TRANSFER_APPLICATION_SAME_DEPT = new ErrorCode(1_030_002_005, "è°å²å¤±è´¥ï¼åå ï¼ç®æ é¨é¨ä¸åé¨é¨ç¸å"); ErrorCode TRANSFER_APPLICATION_SAME_POST = new ErrorCode(1_030_002_006, "è°å²å¤±è´¥ï¼åå ï¼ç®æ å²ä½ä¸åå²ä½ç¸å"); ErrorCode TRANSFER_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS = new ErrorCode(1_030_002_007, "è°å²å®¡æ¹æµç¨ä¸åå¨"); ErrorCode TRANSFER_APPLICATION_CANCEL_FAIL_NOT_PROCESS = new ErrorCode(1_030_002_008, "è°å²ç³è¯·æ¤é失败ï¼åå ï¼ä¸æ¯å®¡æ¹ä¸ç¶æ"); // ========== 离èç³è¯· 1-030-003-000 ========== ErrorCode RESIGNATION_APPLICATION_NOT_EXISTS = new ErrorCode(1_030_003_000, "离èç³è¯·ä¸åå¨"); yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/approval/HrmTransferApplicationController.java
@@ -82,10 +82,10 @@ @PostMapping("/submit") @Operation(summary = "æäº¤è°å²ç³è¯·å®¡æ¹") @Parameter(name = "id", description = "ç³è¯·ID", required = true) @Parameter(name = "processDefinitionKey", description = "æµç¨å®ä¹Key", required = true) @Parameter(name = "processDefinitionKey", description = "æµç¨å®ä¹Keyï¼ä¸ä¼ æ¶èªå¨ä½¿ç¨ãè°å¨å®¡æ¹ãåç±»ä¸ææ°çæ´»è·æµç¨ï¼") @PreAuthorize("@ss.hasPermission('hrm:transfer:submit')") public CommonResult<Boolean> submitTransferApplication(@RequestParam("id") Long id, @RequestParam("processDefinitionKey") String processDefinitionKey) { @RequestParam(value = "processDefinitionKey", required = false) String processDefinitionKey) { Long userId = SecurityFrameworkUtils.getLoginUserId(); transferApplicationService.submitTransferApplication(id, processDefinitionKey, userId); return success(true); @@ -98,6 +98,15 @@ return success(transferApplicationService.getApproveProcessDefinitionList()); } @PostMapping("/cancel") @Operation(summary = "æ¤éè°å²ç³è¯·") @Parameter(name = "id", description = "ç³è¯·ID", required = true) @PreAuthorize("@ss.hasPermission('hrm:transfer:cancel')") public CommonResult<Boolean> cancelTransferApplication(@RequestParam("id") Long id) { transferApplicationService.cancelTransferApplication(id, SecurityFrameworkUtils.getLoginUserId()); return success(true); } @GetMapping("/export-excel") @Operation(summary = "导åºè°å²ç³è¯· Excel") @PreAuthorize("@ss.hasPermission('hrm:transfer:export')") yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/salary/HrmSalaryCalculationController.java
@@ -161,6 +161,14 @@ return success(true); } @DeleteMapping("/delete-batch") @Operation(summary = "æ¹éå é¤èªé ¬æ ¸ç®è®°å½", description = "å ¨éåä¸é®å é¤ï¼ä¸éå¶ç¶æ") @Parameter(name = "ids", description = "æ ¸ç®IDå表", required = true) @PreAuthorize("@ss.hasPermission('hrm:salary-calculation:delete')") public CommonResult<Integer> deleteSalaryCalculationList(@RequestParam("ids") List<Long> ids) { return success(salaryCalculationService.deleteSalaryCalculationList(ids)); } @GetMapping("/export-excel") @Operation(summary = "导åºèªé ¬æ ¸ç® Excel") @PreAuthorize("@ss.hasPermission('hrm:salary-calculation:export')") yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmTransferApplicationService.java
@@ -83,6 +83,14 @@ void submitTransferApplication(Long id, String processDefinitionKey, Long userId); /** * æ¤éè°å²ç³è¯·ï¼å®¡æ¹ä¸ â å·²æ¤éï¼ * * @param id ç³è¯·ID * @param userId æä½äººï¼å½åç»å½ç¨æ·ï¼ */ void cancelTransferApplication(Long id, Long userId); /** * è·åå¯ç¨çå®¡æ¹æµç¨å®ä¹å表 * * @return æµç¨å®ä¹å表 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/approval/HrmTransferApplicationServiceImpl.java
@@ -1,14 +1,17 @@ package cn.iocoder.yudao.module.hrm.service.approval; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCancelReqVO; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmTransferApplicationPageReqVO; import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmTransferApplicationRespVO; import cn.iocoder.yudao.module.hrm.controller.admin.approval.vo.HrmTransferApplicationSaveReqVO; @@ -35,6 +38,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -77,6 +81,8 @@ private StorageAttachmentApi storageAttachmentApi; @Resource private BpmProcessDefinitionService bpmProcessDefinitionService; @Resource private BpmProcessInstanceService bpmProcessInstanceService; @Override @Transactional(rollbackFor = Exception.class) @@ -269,17 +275,41 @@ throw exception(TRANSFER_APPLICATION_SUBMIT_FAIL_NOT_DRAFT); } validateApproveCategoryAndProcessDefinition(); ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(processDefinitionKey); // æªæå®æµç¨å®ä¹ Key æ¶ï¼èªå¨åãè°å¨å®¡æ¹ãåç±»ä¸å½åæ´»è·çæµç¨ï¼ // é¿å å端æªä¼ key å¯¼è´æ¥å£åæ°ç¼ºå¤±ç´æ¥æ¥ç³»ç»å¼å¸¸ String key = resolveProcessDefinitionKey(processDefinitionKey); ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(key); if (processDefinition == null) { throw exception(TRANSFER_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS); } String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() .setProcessDefinitionKey(processDefinitionKey).setBusinessKey(String.valueOf(id))); .setProcessDefinitionKey(key).setBusinessKey(String.valueOf(id))); transferApplicationMapper.updateById(HrmTransferApplicationDO.builder() .id(id) .processInstanceId(processInstanceId) .status(HrmAuditStatusEnum.PROCESS.getStatus()) .build()); } /** * è§£ææµç¨å®ä¹ Keyï¼ä¼å 使ç¨è°ç¨æ¹ä¼ å ¥å¼ï¼ä¸ºç©ºæ¶åãè°å¨å®¡æ¹ãåç±»ä¸ææ°çæ´»è·æµç¨ */ private String resolveProcessDefinitionKey(String processDefinitionKey) { if (StrUtil.isNotBlank(processDefinitionKey)) { return processDefinitionKey.trim(); } List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService .getProcessDefinitionInfoListByCategory(APPROVE_CATEGORY_CODE); if (CollUtil.isEmpty(definitionInfoList)) { throw exception(TRANSFER_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS); } Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId); List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds); return processDefinitions.stream() .filter(pd -> !pd.isSuspended()) .max(Comparator.comparingInt(ProcessDefinition::getVersion)) .map(ProcessDefinition::getKey) .orElseThrow(() -> exception(TRANSFER_APPLICATION_BPM_PROCESS_DEFINITION_NOT_EXISTS)); } private void validateApproveCategoryAndProcessDefinition() { @@ -302,6 +332,26 @@ } @Override @Transactional(rollbackFor = Exception.class) public void cancelTransferApplication(Long id, Long userId) { HrmTransferApplicationDO application = validateTransferApplicationExists(id); if (ObjUtil.notEqual(application.getStatus(), HrmAuditStatusEnum.PROCESS.getStatus())) { throw exception(TRANSFER_APPLICATION_CANCEL_FAIL_NOT_PROCESS); } // 忶坹åºç BPM æµç¨å®ä¾ï¼ä»¥å起人身份æ¤éï¼ if (StrUtil.isNotBlank(application.getProcessInstanceId())) { BpmProcessInstanceCancelReqVO cancelReqVO = new BpmProcessInstanceCancelReqVO(); cancelReqVO.setId(application.getProcessInstanceId()); cancelReqVO.setReason("åå·¥æ¤éè°å²ç³è¯·"); bpmProcessInstanceService.cancelProcessInstanceByStartUser(userId, cancelReqVO); } transferApplicationMapper.updateById(HrmTransferApplicationDO.builder() .id(id) .status(HrmAuditStatusEnum.CANCEL.getStatus()) .build()); } @Override public List<Map<String, Object>> getApproveProcessDefinitionList() { validateApproveCategoryAndProcessDefinition(); List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/salary/HrmSalaryCalculationService.java
@@ -61,6 +61,14 @@ void deleteSalaryCalculation(Long id); /** * æ¹éå 餿 ¸ç®è®°å½ï¼ä¸éå¶ç¶æï¼å¾éå³å ï¼ * * @param ids æ ¸ç®è®°å½ ID å表 * @return å®é å é¤çæ¡æ° */ Integer deleteSalaryCalculationList(List<Long> ids); /** * è·å¾æå®å¨æçèªé ¬æ ¸ç®å表 */ List<HrmSalaryCalculationDO> getSalaryCalculationListByPeriod(String period); yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/salary/HrmSalaryCalculationServiceImpl.java
@@ -277,19 +277,17 @@ BigDecimal socialSecurityBase = (socialSecurity != null && socialSecurity.getSocialSecurityBase() != null) ? socialSecurity.getSocialSecurityBase() : baseSalary; // è·åå ¬ç§¯éåºæ°ï¼åå·¥ç¤¾ä¿æ¡£æ¡ > åå·¥åºæ¬å·¥èµ BigDecimal housingFundBase = (socialSecurity != null && socialSecurity.getHousingFundBase() != null) ? socialSecurity.getHousingFundBase() : baseSalary; // 仿¹æ¡ä¸è·å缴纳æ¯ä¾ï¼ä¼å ä½¿ç¨æ¹æ¡ä¸çæ¯ä¾ï¼å¦å使ç¨é»è®¤æ¯ä¾ï¼ // 仿¹æ¡ä¸è·å社ä¿ç¼´çº³æ¯ä¾ï¼æ¹æ¡æªé ç½®æ¶åéé»è®¤æ¯ä¾ï¼ BigDecimal pensionPersonalRatio = (scheme != null && scheme.getPensionPersonalRatio() != null) ? scheme.getPensionPersonalRatio() : DEFAULT_PENSION_PERSONAL_RATIO; BigDecimal medicalPersonalRatio = (scheme != null && scheme.getMedicalPersonalRatio() != null) ? scheme.getMedicalPersonalRatio() : DEFAULT_MEDICAL_PERSONAL_RATIO; BigDecimal unemploymentPersonalRatio = (scheme != null && scheme.getUnemploymentPersonalRatio() != null) ? scheme.getUnemploymentPersonalRatio() : DEFAULT_UNEMPLOYMENT_PERSONAL_RATIO; BigDecimal housingFundPersonalRatio = (scheme != null && scheme.getHousingFundPersonalRatio() != null) ? scheme.getHousingFundPersonalRatio() : DEFAULT_HOUSING_FUND_PERSONAL_RATIO; // å ¬ç§¯é个人æ¯ä¾ï¼åªåæ¹æ¡é ç½®å¼ï¼ä¸ååéé»è®¤æ¯ä¾ã // å¦åãå ¬å¸æ²¡é å ¬ç§¯éæ¹æ¡ãæ¶ä¼è¢«æé»è®¤ 12% æ£æ¬¾ï¼è¿å°±æ¯å®¢æ·åé¦çé®é¢ï¼ã BigDecimal housingFundPersonalRatio = scheme != null ? scheme.getHousingFundPersonalRatio() : null; // ç¤¾ä¿æ£é¤ = åºæ° à (å »è个人æ¯ä¾ + å»ç个人æ¯ä¾ + 失ä¸ä¸ªäººæ¯ä¾) BigDecimal socialSecurityDeduction = socialSecurityBase @@ -298,8 +296,15 @@ .add(socialSecurityBase.multiply(unemploymentPersonalRatio)) .setScale(2, RoundingMode.HALF_UP); // å ¬ç§¯éæ£é¤ = åºæ° Ã å ¬ç§¯é个人æ¯ä¾ BigDecimal housingFundDeduction = housingFundBase.multiply(housingFundPersonalRatio).setScale(2, RoundingMode.HALF_UP); // å ¬ç§¯éæ£é¤ï¼å¿ é¡»åæ¶æ»¡è¶³ãæ¹æ¡é ç½®äºå ¬ç§¯éæ¯ä¾ > 0ãä¸ãå工档æ¡é ç½®äºå ¬ç§¯éåºæ° > 0ãææ£æ¬¾ï¼ // ä»»ä¸ä¸æ»¡è¶³é½è§ä¸ºå ¬å¸æªç¼´çº³å ¬ç§¯éï¼æ£æ¬¾ä¸º 0ã BigDecimal housingFundDeduction = BigDecimal.ZERO; BigDecimal housingFundBase = socialSecurity != null ? socialSecurity.getHousingFundBase() : null; if (housingFundPersonalRatio != null && housingFundPersonalRatio.signum() > 0 && housingFundBase != null && housingFundBase.signum() > 0) { housingFundDeduction = housingFundBase.multiply(housingFundPersonalRatio) .setScale(2, RoundingMode.HALF_UP); } // 计ç®è¯·åæ£æ¬¾ BigDecimal leaveDeduction = calculateLeaveDeduction(employee, period, baseSalary); @@ -873,4 +878,25 @@ salaryCalculationMapper.deleteById(id); } /** * æ¹éå 餿 ¸ç®è®°å½ï¼å ¨éåä¸é®å é¤ï¼ * * 说æï¼æä¸å¡è¦æ±ï¼æ¹éå é¤ä¸éå¶ç¶æï¼å¾éå³å ã * ä¸åå¨ç ID ç´æ¥è·³è¿ï¼ä¸æ¥éï¼é¿å å端å¾éå表ä¸åºä¸ä¸è´æ¶æ´ä½å¤±è´¥ï¼ã */ @Override public Integer deleteSalaryCalculationList(List<Long> ids) { if (CollUtil.isEmpty(ids)) { return 0; } List<Long> existIds = salaryCalculationMapper.selectBatchIds(ids).stream() .map(HrmSalaryCalculationDO::getId) .collect(Collectors.toList()); if (CollUtil.isEmpty(existIds)) { return 0; } salaryCalculationMapper.deleteByIds(existIds); return existIds.size(); } } yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java
@@ -22,6 +22,9 @@ @Schema(description = "ç¨æ·è´¦å·ï¼æ¨¡ç³å¹é ", example = "yudao") private String username; @Schema(description = "å ³é®è¯ï¼åæ¶æ¨¡ç³å¹é ãè´¦å·ãä¸ãå§åãï¼ä¾éæ©ç¨æ·å¼¹çªçæç´¢æ¡ä½¿ç¨ï¼", example = "å¼ ä¸") private String keyword; @Schema(description = "ææºå·ç ï¼æ¨¡ç³å¹é ", example = "yudao") private String mobile; yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java
@@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.system.dal.mysql.user; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; @@ -26,7 +27,14 @@ } default PageResult<AdminUserDO> selectPage(UserPageReqVO reqVO, Collection<Long> deptIds, Collection<Long> userIds) { return selectPage(reqVO, new LambdaQueryWrapperX<AdminUserDO>() LambdaQueryWrapperX<AdminUserDO> wrapper = new LambdaQueryWrapperX<>(); // å ³é®è¯ï¼åæ¶æ¨¡ç³å¹é ãè´¦å·ãä¸ãå§åãï¼ä¾éæ©ç¨æ·å¼¹çªçæç´¢æ¡ä½¿ç¨ if (StrUtil.isNotBlank(reqVO.getKeyword())) { String keyword = reqVO.getKeyword().trim(); wrapper.and(w -> w.like(AdminUserDO::getUsername, keyword) .or().like(AdminUserDO::getNickname, keyword)); } return selectPage(reqVO, wrapper .likeIfPresent(AdminUserDO::getUsername, reqVO.getUsername()) .likeIfPresent(AdminUserDO::getMobile, reqVO.getMobile()) .eqIfPresent(AdminUserDO::getStatus, reqVO.getStatus())