main-business/pom.xml
@@ -44,6 +44,10 @@ <groupId>com.ruoyi</groupId> <artifactId>basic-server</artifactId> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> </dependency> </dependencies> <properties> main-business/src/main/java/com/ruoyi/business/controller/ArchiveController.java
@@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.business.dto.ArchiveDto; import com.ruoyi.business.entity.Archive; import com.ruoyi.business.service.ArchiveService; import com.ruoyi.common.core.domain.R; import lombok.AllArgsConstructor; @@ -28,7 +29,7 @@ * æ¥è¯¢æ¡£æ¡ä¿¡æ¯è¡¨ */ @GetMapping("/list") public R<IPage<ArchiveDto>> treeList(Page page, ArchiveDto archiveDto) { public R<IPage<ArchiveDto>> treeList(Page<Archive> page, ArchiveDto archiveDto) { IPage<ArchiveDto> list = archiveService.selectArchiveList(page, archiveDto); return R.ok(list); } main-business/src/main/java/com/ruoyi/business/controller/EquipmentManagementController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,56 @@ package com.ruoyi.business.controller; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.business.dto.EquipmentManagementDto; import com.ruoyi.business.dto.ProductionDto; import com.ruoyi.business.entity.EquipmentManagement; import com.ruoyi.business.entity.Production; import com.ruoyi.business.service.EquipmentManagementService; import com.ruoyi.common.core.domain.R; import org.springframework.web.bind.annotation.*; import lombok.AllArgsConstructor; /** * <p> * 设å¤ç®¡ç表 å端æ§å¶å¨ * </p> * * @author ld * @since 2025-07-01 */ @RestController @AllArgsConstructor @RequestMapping("/equipmentManagement") public class EquipmentManagementController { private EquipmentManagementService equipmentManagementService; /** * 设å¤ç®¡ç表æ¥è¯¢ */ @GetMapping("/list") public R<IPage<EquipmentManagementDto>> list(Page<EquipmentManagement> page, EquipmentManagementDto equipmentManagementDto) { IPage<EquipmentManagementDto> list = equipmentManagementService.selectProductionList(page, equipmentManagementDto); return R.ok(list); } /** * 设å¤ç®¡ç表æ°å¢ä¿®æ¹ */ @PostMapping("/addOrEditEquipment") public R addOrEditEquipment(@RequestBody EquipmentManagementDto equipmentManagementDto) { return R.ok(equipmentManagementService.addOrEditEquipment(equipmentManagementDto)); } /** * 设å¤ç®¡ç表å é¤ */ @DeleteMapping("/delEquipment") public R remove(@RequestBody Long[] ids) { return R.ok(equipmentManagementService.delByIds(ids)); } } main-business/src/main/java/com/ruoyi/business/controller/InputInventoryRecordController.java
@@ -2,20 +2,20 @@ import org.springframework.web.bind.annotation.RequestMapping; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController; /** * <p> * å ¥åºè®°å½è¡¨ å端æ§å¶å¨ * </p> * * @author chenhj * @since 2025-06-14 */ * <p> * å ¥åºè®°å½è¡¨ å端æ§å¶å¨ * </p> * * @author chenhj * @since 2025-06-14 */ @RestController @AllArgsConstructor @RequestMapping("/business/inputInventoryRecord") public class InputInventoryRecordController { public class InputInventoryRecordController { } } main-business/src/main/java/com/ruoyi/business/controller/InspectionTaskController.java
@@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.business.dto.InspectionTaskDto; import com.ruoyi.business.entity.InspectionTask; import com.ruoyi.business.service.InspectionTaskService; import com.ruoyi.common.core.domain.R; import lombok.AllArgsConstructor; @@ -27,7 +28,7 @@ * å·¡æ£ä»»å¡è¡¨è¡¨æ¥è¯¢ */ @GetMapping("/list") public R<IPage<InspectionTaskDto>> list(Page page, InspectionTaskDto inspectionTaskDto) { public R<IPage<InspectionTaskDto>> list(Page<InspectionTask> page, InspectionTaskDto inspectionTaskDto) { IPage<InspectionTaskDto> list = inspectionTaskService.selectInspectionTaskList(page,inspectionTaskDto); return R.ok(list); } main-business/src/main/java/com/ruoyi/business/controller/TimingTaskController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,56 @@ package com.ruoyi.business.controller; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.business.dto.SalesRecordDto; import com.ruoyi.business.dto.TimingTaskDto; import com.ruoyi.business.entity.SalesRecord; import com.ruoyi.business.entity.TimingTask; import com.ruoyi.business.service.TimingTaskService; import com.ruoyi.common.core.domain.R; import org.quartz.SchedulerException; import org.springframework.web.bind.annotation.*; import lombok.AllArgsConstructor; /** * <p> * 宿¶å·¡æ£ä»»å¡è¡¨ å端æ§å¶å¨ * </p> * * @author ld * @since 2025-06-30 */ @RestController @AllArgsConstructor @RequestMapping("/timingTask") public class TimingTaskController { private TimingTaskService timingTaskService; /** * 宿¶å·¡æ£ä»»å¡è¡¨æ¥è¯¢ */ @GetMapping("/list") public R<IPage<TimingTaskDto>> list(Page<TimingTask> page, TimingTask timingTask) { IPage<TimingTaskDto> list = timingTaskService.selectTimingTaskList(page,timingTask); return R.ok(list); } /** * 宿¶å·¡æ£ä»»å¡è¡¨æ°å¢ä¿®æ¹ */ @PostMapping("/addOrEditTimingTask") public R addOrEditTimingTask(@RequestBody TimingTaskDto timingTaskDto) throws SchedulerException { return R.ok(timingTaskService.addOrEditTimingTask(timingTaskDto)); } /** * 宿¶å·¡æ£ä»»å¡è¡¨å é¤ */ @DeleteMapping("/delTimingTask") public R remove(@RequestBody Long[] ids) { return R.ok(timingTaskService.delByIds(ids)); } } main-business/src/main/java/com/ruoyi/business/dto/ArchiveDto.java
@@ -15,4 +15,6 @@ private List<StorageBlobDTO> storageBlobDTO; private List<StorageBlob> attachments; private String searchAll; } main-business/src/main/java/com/ruoyi/business/dto/EquipmentManagementDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,8 @@ package com.ruoyi.business.dto; import com.ruoyi.business.entity.EquipmentManagement; import lombok.Data; @Data public class EquipmentManagementDto extends EquipmentManagement { } main-business/src/main/java/com/ruoyi/business/dto/TimingTaskDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,10 @@ package com.ruoyi.business.dto; import com.ruoyi.business.entity.TimingTask; import lombok.Data; @Data public class TimingTaskDto extends TimingTask { private String inspector; } main-business/src/main/java/com/ruoyi/business/entity/EquipmentManagement.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,79 @@ package com.ruoyi.business.entity; import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import com.ruoyi.common.core.domain.MyBaseEntity; import java.math.BigDecimal; import java.time.LocalDate; /** * 设å¤ç®¡ç表 å®ä½ç±» * * @author ld * @date 2025-07-01 */ @Data @TableName("equipment_management") public class EquipmentManagement extends MyBaseEntity { private static final long serialVersionUID = 1L; /** * ä¸»é® ID */ @TableId(value = "id", type = IdType.AUTO) private Long id; /** * 设å¤ç¼å· */ @TableField(value = "equipment_id") private String equipmentId; /** * 设å¤åç§° */ @TableField(value = "equipment_name") private String equipmentName; /** * æ°é */ @TableField(value = "quantity") private Integer quantity; /** * è§æ ¼åå· */ @TableField(value = "specification") private String specification; /** * 使ç¨ç¶æ */ @TableField(value = "usage_status") private String usageStatus; /** * 使ç¨é¨é¨ */ @TableField(value = "using_department") private String usingDepartment; /** * 使ç¨äººID */ @TableField(value = "user_id") private Long userId; /** * åæ¾ä½ç½® */ @TableField(value = "storage_location") private String storageLocation; /** * éè´æ¥æ */ @TableField(value = "purchase_date") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate purchaseDate; /** * éè´ä»·æ ¼ */ @TableField(value = "purchase_price") private BigDecimal purchasePrice; } main-business/src/main/java/com/ruoyi/business/entity/InspectionTask.java
@@ -30,7 +30,7 @@ * */ @TableField(value = "inspector_id") private Long inspectorId; private String inspectorId; /** * æ§è¡å·¡æ£ç人åå§å */ @@ -39,8 +39,8 @@ /** * å·¡æ£å°ç¹è¯¦ç»æè¿° */ @TableField(value = "port") private String port; @TableField(value = "inspection_location") private String inspectionLocation; /** * ä»»å¡éå 说ææç¹æ®æ åµè®°å½ */ @@ -56,4 +56,9 @@ */ @TableField(value = "registrant") private String registrant; /** * 颿¬¡ */ @TableField(value = "frequency_type") private String frequencyType; } main-business/src/main/java/com/ruoyi/business/entity/TimingTask.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,96 @@ package com.ruoyi.business.entity; import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import com.ruoyi.common.core.domain.MyBaseEntity; import java.time.LocalDate; import java.time.LocalDateTime; /** * 宿¶å·¡æ£ä»»å¡è¡¨ å®ä½ç±» * * @author ld * @date 2025-06-30 */ @Data @TableName("timing_task") public class TimingTask extends MyBaseEntity { private static final long serialVersionUID = 1L; /** * 主é®ID */ @TableId(value = "id", type = IdType.AUTO) private Long id; /** * ä»»å¡åç§° */ @TableField(value = "task_name") private String taskName; /** * å·¡æ£äºº */ @TableField(value = "inspector_ids") private String inspectorIds; /** * å·¡æ£å°ç¹ */ @TableField(value = "inspection_location") private String inspectionLocation; /** * 颿¬¡ */ @TableField(value = "frequency_type") private String frequencyType; /** * å ·ä½æ¶é´ */ @TableField(value = "frequency_detail") private String frequencyDetail; /** * 䏿¬¡æ§è¡æ¶é´ */ @TableField(value = "next_execution_time") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime nexExecutionTime; /** * æåæ§è¡æ¶é´ */ @TableField(value = "last_execution_time") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime lastExecuteTime; /** * æ¯å¦æ¿æ´» */ @TableField(value = "is_active") private boolean isActive; /** * 夿³¨ */ @TableField(value = "remarks") private String remarks; /** * ç»è®°äººid */ @TableField(value = "registrant_id") private Long registrantId; /** * ç»è®°äºº */ @TableField(value = "registrant") private String registrant; /** * ç»è®°æ¥æ */ @TableField(value = "registration_date") @JsonFormat(pattern = "yyyy-MM-dd") private LocalDate registrationDate; /** * ä»»å¡ç¶æ */ @TableField(value = "status") private String status; // ACTIVE, PAUSED, COMPLETEDç } main-business/src/main/java/com/ruoyi/business/mapper/EquipmentManagementMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,18 @@ package com.ruoyi.business.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.business.entity.EquipmentManagement; import org.apache.ibatis.annotations.Mapper; /** * <p> * 设å¤ç®¡ç表 Mapper æ¥å£ * </p> * * @author ld * @since 2025-07-01 */ @Mapper public interface EquipmentManagementMapper extends BaseMapper<EquipmentManagement> { } main-business/src/main/java/com/ruoyi/business/mapper/TimingTaskMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,24 @@ package com.ruoyi.business.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.business.entity.TimingTask; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import java.time.LocalDateTime; import java.util.List; /** * <p> * 宿¶å·¡æ£ä»»å¡è¡¨ Mapper æ¥å£ * </p> * * @author ld * @since 2025-06-30 */ @Mapper public interface TimingTaskMapper extends BaseMapper<TimingTask> { @Select("SELECT * FROM timing_task WHERE next_execution_time <= #{currentTime}") List<TimingTask> selectActiveTasks(@Param("currentTime") LocalDateTime currentTime);} main-business/src/main/java/com/ruoyi/business/mapper/TreeMapper.java
@@ -4,6 +4,8 @@ import com.ruoyi.business.entity.Tree; import org.apache.ibatis.annotations.Mapper; import java.util.List; /** * <p> * æ¡£æ¡ä¿¡æ¯è¡¨ï¼è®°å½ç³»ç»ä¸å类档æ¡çåºæ¬ä¿¡æ¯ Mapper æ¥å£ @@ -15,4 +17,5 @@ @Mapper public interface TreeMapper extends BaseMapper<Tree> { List<Long> listRecursiveSubNodeIds(Long treeId); } main-business/src/main/java/com/ruoyi/business/service/ArchiveService.java
@@ -19,7 +19,7 @@ */ public interface ArchiveService extends IService<Archive> { IPage<ArchiveDto> selectArchiveList(Page page, ArchiveDto archiveDto); IPage<ArchiveDto> selectArchiveList(Page<Archive> page, ArchiveDto archiveDto); int addOrEditArchive(ArchiveDto archiveDto); main-business/src/main/java/com/ruoyi/business/service/EquipmentManagementService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,24 @@ package com.ruoyi.business.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.business.dto.EquipmentManagementDto; import com.ruoyi.business.entity.EquipmentManagement; import com.baomidou.mybatisplus.extension.service.IService; /** * <p> * 设å¤ç®¡ç表 æå¡ç±» * </p> * * @author ld * @since 2025-07-01 */ public interface EquipmentManagementService extends IService<EquipmentManagement> { IPage<EquipmentManagementDto> selectProductionList(Page<EquipmentManagement> page, EquipmentManagementDto equipmentManagementDto); int addOrEditEquipment(EquipmentManagementDto equipmentManagementDto); int delByIds(Long[] ids); } main-business/src/main/java/com/ruoyi/business/service/InspectionTaskService.java
@@ -16,7 +16,7 @@ */ public interface InspectionTaskService extends IService<InspectionTask> { IPage<InspectionTaskDto> selectInspectionTaskList(Page page, InspectionTaskDto inspectionTaskDto); IPage<InspectionTaskDto> selectInspectionTaskList(Page<InspectionTask> page, InspectionTaskDto inspectionTaskDto); int addOrEditInspectionTask(InspectionTaskDto inspectionTaskDto); main-business/src/main/java/com/ruoyi/business/service/TimingTaskService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,27 @@ package com.ruoyi.business.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.business.dto.TimingTaskDto; import com.ruoyi.business.entity.TimingTask; import com.baomidou.mybatisplus.extension.service.IService; import org.quartz.SchedulerException; /** * <p> * 宿¶å·¡æ£ä»»å¡è¡¨ æå¡ç±» * </p> * * @author ld * @since 2025-06-30 */ public interface TimingTaskService extends IService<TimingTask> { IPage<TimingTaskDto> selectTimingTaskList(Page<TimingTask> page, TimingTask timingTask); int addOrEditTimingTask(TimingTaskDto timingTaskDto) throws SchedulerException; int delByIds(Long[] ids); void updateTaskExecutionTime(Long taskId); } main-business/src/main/java/com/ruoyi/business/service/impl/ArchiveServiceImpl.java
@@ -14,7 +14,9 @@ import com.ruoyi.basic.service.StorageAttachmentService; import com.ruoyi.business.dto.ArchiveDto; import com.ruoyi.business.entity.Archive; import com.ruoyi.business.entity.Tree; import com.ruoyi.business.mapper.ArchiveMapper; import com.ruoyi.business.mapper.TreeMapper; import com.ruoyi.business.service.ArchiveService; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.common.utils.file.MinioUtils; @@ -43,6 +45,8 @@ private final ArchiveMapper archiveMapper; private final TreeMapper treeMapper; private final StorageAttachmentService storageAttachmentService; private final StorageBlobMapper storageBlobMapper; @@ -53,12 +57,30 @@ @Override public IPage<ArchiveDto> selectArchiveList(Page page, ArchiveDto archiveDto) { public IPage<ArchiveDto> selectArchiveList(Page<Archive> page, ArchiveDto archiveDto) { // 1. å页æ¥è¯¢ä¸»æ°æ® LambdaQueryWrapper<Archive> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.orderByDesc(Archive::getCreateTime); if (archiveDto.getTreeId() != null) { queryWrapper.eq(Archive::getTreeId, archiveDto.getTreeId()); Long treeId = archiveDto.getTreeId(); // 夿æ¯å¦ä¸ºä¸»ID Tree tree = treeMapper.selectById(archiveDto.getTreeId()); boolean isMainId = tree != null && tree.getParentId() == null; if (isMainId) { // è·å主IDçææéå½åèç¹ID List<Long> recursiveSubIds = treeMapper.listRecursiveSubNodeIds(treeId); // å°ä¸»IDæ¬èº«åææåèç¹IDå å ¥æ¥è¯¢æ¡ä»¶ recursiveSubIds.add(treeId); queryWrapper.in(Archive::getTreeId, recursiveSubIds); } else { // é主IDï¼ç´æ¥æåæ¡ä»¶æ¥è¯¢ queryWrapper.eq(Archive::getTreeId, treeId); } } if (archiveDto.getSearchAll() != null) { queryWrapper.like(Archive::getName, archiveDto.getSearchAll()); } IPage<Archive> archivePage = archiveMapper.selectPage(page, queryWrapper); @@ -114,7 +136,7 @@ .map(blob -> { StorageBlobDTO blobDTO = new StorageBlobDTO(); BeanUtils.copyProperties(blob, blobDTO); // 卿çæé¢è§å°ååä¸è½½å°å // 设置é¢è§URL blobDTO.setUrl(minioUtils.getPreviewUrls( main-business/src/main/java/com/ruoyi/business/service/impl/EquipmentManagementServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,57 @@ package com.ruoyi.business.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.business.dto.EquipmentManagementDto; import com.ruoyi.business.dto.ProductionMasterDto; import com.ruoyi.business.entity.EquipmentManagement; import com.ruoyi.business.entity.Production; import com.ruoyi.business.mapper.EquipmentManagementMapper; import com.ruoyi.business.service.EquipmentManagementService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.utils.bean.BeanUtils; import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; import java.util.Arrays; import java.util.Objects; /** * <p> * 设å¤ç®¡ç表 æå¡å®ç°ç±» * </p> * * @author ld * @since 2025-07-01 */ @Service @RequiredArgsConstructor public class EquipmentManagementServiceImpl extends ServiceImpl<EquipmentManagementMapper, EquipmentManagement> implements EquipmentManagementService { private final EquipmentManagementMapper equipmentManagementMapper; public IPage<EquipmentManagementDto> selectProductionList(Page<EquipmentManagement> page, EquipmentManagementDto equipmentManagementDto) { Page<EquipmentManagement> entityPage = equipmentManagementMapper.selectPage(page, null); IPage<EquipmentManagementDto> dtoPage = new Page<>(); BeanUtils.copyProperties(entityPage, dtoPage); return dtoPage; } @Override public int addOrEditEquipment(EquipmentManagementDto equipmentManagementDto) { EquipmentManagement equipmentManagement = new EquipmentManagement(); BeanUtils.copyProperties(equipmentManagementDto, equipmentManagement); if (Objects.isNull(equipmentManagementDto.getId())) { return equipmentManagementMapper.insert(equipmentManagement); } else { return equipmentManagementMapper.updateById(equipmentManagement); } } @Override public int delByIds(Long[] ids) { return equipmentManagementMapper.deleteByIds(Arrays.asList(ids)); } } main-business/src/main/java/com/ruoyi/business/service/impl/InspectionTaskServiceImpl.java
@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.basic.entity.StorageAttachment; import com.ruoyi.basic.entity.StorageBlob; import com.ruoyi.basic.entity.Supply; import com.ruoyi.basic.entity.dto.StorageBlobDTO; import com.ruoyi.basic.mapper.StorageAttachmentMapper; import com.ruoyi.basic.mapper.StorageBlobMapper; @@ -15,9 +16,12 @@ import com.ruoyi.business.entity.InspectionTask; import com.ruoyi.business.mapper.InspectionTaskMapper; import com.ruoyi.business.service.InspectionTaskService; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.common.utils.file.MinioUtils; import com.ruoyi.system.mapper.SysUserMapper; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -50,8 +54,10 @@ private final MinioUtils minioUtils; private final SysUserMapper sysUserMapper; @Override public IPage<InspectionTaskDto> selectInspectionTaskList(Page page, InspectionTaskDto inspectionTaskDto) { public IPage<InspectionTaskDto> selectInspectionTaskList(Page<InspectionTask> page, InspectionTaskDto inspectionTaskDto) { LambdaQueryWrapper<InspectionTask> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.orderByDesc(InspectionTask::getCreateTime); IPage<InspectionTask> entityPage = inspectionTaskMapper.selectPage(page, queryWrapper); @@ -61,8 +67,46 @@ return new Page<>(entityPage.getCurrent(), entityPage.getSize(), entityPage.getTotal()); } // è·åidéå List<Long> ids = entityPage.getRecords().stream().map(InspectionTask::getId).collect(Collectors.toList()); List<Long> ids = entityPage.getRecords().stream().map(InspectionTask::getId).toList(); //ç»è®°äººids List<Long> registrantIds = entityPage.getRecords().stream().map(InspectionTask::getRegistrantId).toList(); // æ¹éæ¥è¯¢ç»è®°äºº Map<Long, SysUser> sysUserMap; if (!registrantIds.isEmpty()) { List<SysUser> sysUsers = sysUserMapper.selectList(registrantIds); sysUserMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity())); } else { sysUserMap = new HashMap<>(); } //å·¡æ£äººids List<String> inspectorIds = entityPage.getRecords().stream().map(InspectionTask::getInspectorId).toList(); //è·åææä¸éå¤çç¨æ·ID Set<Long> allUserIds = entityPage.getRecords().stream() .map(InspectionTask::getInspectorId) // è·å"2,3"è¿æ ·çå符串 .filter(StringUtils::isNotBlank) .flatMap(idsStr -> Arrays.stream(idsStr.split(","))) .map(idStr -> { try { return Long.parseLong(idStr.trim()); } catch (NumberFormatException e) { return null; } }) .filter(Objects::nonNull) .collect(Collectors.toSet()); // 使ç¨SQLæ¹éæ¥è¯¢ç¨æ·ä¿¡æ¯ Map<Long, String> userIdToNameMap = allUserIds.isEmpty() ? Collections.emptyMap() : sysUserMapper.selectUsersByIds(new ArrayList<>(allUserIds)) .stream() .collect(Collectors.toMap( SysUser::getUserId, SysUser::getNickName, (existing, replacement) -> existing)); //å¤çéä»¶ Map<Long, List<StorageAttachment>> attachmentsMap = storageAttachmentMapper.selectList(new LambdaQueryWrapper<StorageAttachment>().in(StorageAttachment::getRecordId, ids) .eq(StorageAttachment::getRecordType, InspectionTasks.ordinal())) .stream() @@ -82,6 +126,27 @@ List<InspectionTaskDto> dtoList = entityPage.getRecords().stream().map(inspectionTask -> { InspectionTaskDto dto = new InspectionTaskDto(); BeanUtils.copyProperties(inspectionTask, dto); // å¤å¶ä¸»å¯¹è±¡å±æ§ // 设置ç»è®°äºº SysUser sysUser = sysUserMap.get(inspectionTask.getRegistrantId()); if (sysUser != null) { dto.setRegistrant(sysUser.getNickName()); } // å¤çå·¡æ£äººåç§° if (StringUtils.isNotBlank(inspectionTask.getInspectorId())) { String inspectorNames = Arrays.stream(inspectionTask.getInspectorId().split(",")) .map(String::trim) .map(idStr -> { try { Long userId = Long.parseLong(idStr); return userIdToNameMap.getOrDefault(userId, "æªç¥ç¨æ·(" + idStr + ")"); } catch (NumberFormatException e) { return "æ æID(" + idStr + ")"; } }) .collect(Collectors.joining(",")); dto.setInspector(inspectorNames); } // åå§åä¸ä¸ªéä»¶å表 dto.setBeforeProduction(new ArrayList<>()); @@ -149,7 +214,6 @@ @Override public int addOrEditInspectionTask(InspectionTaskDto inspectionTaskDto) { SecurityUtils.getLoginUser().getUserId(); InspectionTask inspectionTask = new InspectionTask(); BeanUtils.copyProperties(inspectionTaskDto, inspectionTask); inspectionTask.setRegistrantId(SecurityUtils.getLoginUser().getUserId()); @@ -184,6 +248,6 @@ if (ids == null || ids.length == 0) { return 0; } return inspectionTaskMapper.deleteByIds(Arrays.asList(ids)); return inspectionTaskMapper.deleteByIds(Arrays.asList(ids)); } } main-business/src/main/java/com/ruoyi/business/service/impl/ProductionMasterServiceImpl.java
@@ -5,12 +5,14 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.basic.entity.CoalInfo; import com.ruoyi.basic.mapper.CoalInfoMapper; import com.ruoyi.business.dto.ProductionMasterDto; import com.ruoyi.business.entity.*; import com.ruoyi.business.mapper.*; import com.ruoyi.business.service.ProductionMasterService; import com.ruoyi.common.exception.base.BaseException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.bean.BeanUtils; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -49,11 +51,32 @@ public IPage<ProductionMasterDto> selectPMList(Page page, ProductionMasterDto productionMasterDto) { // 1. æå»ºä¸»è¡¨æ¥è¯¢æ¡ä»¶ LambdaQueryWrapper<ProductionMaster> masterQueryWrapper = new LambdaQueryWrapper<>(); String keyword = productionMasterDto.getSearchAll(); if (StringUtils.isNotBlank(keyword)) { // æ¥è¯¢ç ¤ç§åç§°ä¸æ¨¡ç³å¹é çcoalIdå表 List<Long> matchedCoalIds = coalInfoMapper.selectList( new LambdaQueryWrapper<CoalInfo>().like(CoalInfo::getCoal, keyword) ).stream() .map(CoalInfo::getId) .toList(); // ç»è£ æ¥è¯¢æ¡ä»¶ï¼ç ¤ç§IDå¨å¹é çåè¡¨ä¸ // 妿 matchedCoalIds 为空ï¼ç´æ¥è¿å 0 æ¡æ°æ®ï¼æé ä¸ä¸ªä¸å¯è½æç«çæ¡ä»¶ï¼ if (matchedCoalIds.isEmpty()) { masterQueryWrapper.apply("1 = 0"); // 强å¶è¿åç©ºç»æ } // 妿æå¹é ç coalIdï¼åæ coalId æ¥è¯¢ else { String ids = matchedCoalIds.stream() .map(String::valueOf) .collect(Collectors.joining(",")); masterQueryWrapper.apply( "{0} = ANY(string_to_array(coal_id, ','))", ids ); } } // 2. æ§è¡ä¸»è¡¨å页æ¥è¯¢ IPage<ProductionMaster> entityPage = productionMasterMapper.selectPage(page, masterQueryWrapper); main-business/src/main/java/com/ruoyi/business/service/impl/PurchaseRegistrationServiceImpl.java
@@ -62,7 +62,7 @@ .map(CoalInfo::getId) .collect(Collectors.toList()); // ç»è£ æ¥è¯¢æ¡ä»¶ï¼ç ¤ç§IDå¨å¹é çåè¡¨ä¸ æ ä¾åºååç§°å¹é // ç»è£ æ¥è¯¢æ¡ä»¶ï¼ç ¤ç§IDå¨å¹é çåè¡¨ä¸ queryWrapper.and(w -> { if (!matchedCoalIds.isEmpty()) { w.in(PurchaseRegistration::getCoalId, matchedCoalIds).or(); main-business/src/main/java/com/ruoyi/business/service/impl/TimingTaskScheduler.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,238 @@ package com.ruoyi.business.service.impl; import com.ruoyi.business.entity.TimingTask; import com.ruoyi.business.task.TimingTaskJob; import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.time.DayOfWeek; import java.time.LocalTime; import java.time.ZoneId; import java.time.format.DateTimeParseException; import java.util.Arrays; import java.util.Date; import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; @Service public class TimingTaskScheduler { @Autowired private Scheduler scheduler; /** * æ·»å æ°ä»»å¡å°è°åº¦å¨ */ public void scheduleTimingTask(TimingTask task) throws SchedulerException { JobDetail jobDetail = buildJobDetail(task); Trigger trigger = buildJobTrigger(task, jobDetail); scheduler.scheduleJob(jobDetail, trigger); } /** * æ´æ°å·²æä»»å¡ */ public void rescheduleTimingTask(TimingTask task) throws SchedulerException { TriggerKey triggerKey = new TriggerKey("trigger_" + task.getId()); // è·åç°æè§¦åå¨å¹¶è½¬æ¢ä¸º CronTrigger Trigger oldTrigger = scheduler.getTrigger(triggerKey); if (!(oldTrigger instanceof CronTrigger)) { throw new SchedulerException("Existing trigger is not a CronTrigger"); } // æå»ºæ°è§¦åå¨ Trigger newTrigger = TriggerBuilder.newTrigger() .withIdentity(triggerKey) .withDescription(task.getTaskName()) .withSchedule(CronScheduleBuilder.cronSchedule(convertToCronExpression(task))) .startAt(Date.from(task.getNexExecutionTime().atZone(ZoneId.systemDefault()).toInstant())) .forJob(oldTrigger.getJobKey()) .build(); scheduler.rescheduleJob(triggerKey, newTrigger); } /** * æåä»»å¡ */ public void pauseTimingTask(Long taskId) throws SchedulerException { JobKey jobKey = new JobKey("timingTask_" + taskId); scheduler.pauseJob(jobKey); } /** * æ¢å¤ä»»å¡ */ public void resumeTimingTask(Long taskId) throws SchedulerException { JobKey jobKey = new JobKey("timingTask_" + taskId); scheduler.resumeJob(jobKey); } /** * å é¤ä»»å¡ */ public void unscheduleTimingTask(Long taskId) throws SchedulerException { JobKey jobKey = new JobKey("timingTask_" + taskId); scheduler.deleteJob(jobKey); } private JobDetail buildJobDetail(TimingTask task) { JobDataMap jobDataMap = new JobDataMap(); jobDataMap.put("taskId", task.getId()); return JobBuilder.newJob(TimingTaskJob.class) .withIdentity("timingTask_" + task.getId()) .withDescription(task.getTaskName()) .usingJobData(jobDataMap) .storeDurably() .build(); } private Trigger buildJobTrigger(TimingTask task, JobDetail jobDetail) { String cronExpression = convertToCronExpression(task); TriggerBuilder<CronTrigger> triggerBuilder = TriggerBuilder.newTrigger() .withIdentity("trigger_" + task.getId()) .withDescription(task.getTaskName()) .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)); if (jobDetail != null) { triggerBuilder.forJob(jobDetail); } if (task.getNexExecutionTime() != null) { triggerBuilder.startAt(Date.from(task.getNexExecutionTime().atZone(ZoneId.systemDefault()).toInstant())); } return triggerBuilder.build(); } private String convertToCronExpression(TimingTask task) { // åæ°æ ¡éª if (task == null || task.getFrequencyType() == null || task.getFrequencyDetail() == null) { throw new IllegalArgumentException("ä»»å¡åæ°ä¸è½ä¸ºç©º"); } // 使ç¨switchç¡®ä¿æ¡ä»¶äºæ¥ return switch (task.getFrequencyType().toUpperCase()) { // ç»ä¸è½¬ä¸ºå¤§åæ¯è¾ case "DAILY" -> convertDailyToCron(task.getFrequencyDetail()); case "WEEKLY" -> convertWeeklyToCron(task.getFrequencyDetail()); case "MONTHLY" -> convertMonthlyToCron(task.getFrequencyDetail()); case "QUARTERLY" -> convertQuarterlyToCron(task.getFrequencyDetail()); default -> throw new IllegalArgumentException("䏿¯æçé¢çç±»å: " + task.getFrequencyType()); }; } // æ¯æ¥ä»»å¡è½¬æ¢ private String convertDailyToCron(String frequencyDetail) { LocalTime time = parseTime(frequencyDetail); return String.format("0 %d %d * * ?", time.getMinute(), time.getHour()); } // æ¯å¨ä»»å¡è½¬æ¢ private String convertWeeklyToCron(String frequencyDetail) { String[] parts = validateAndSplit(frequencyDetail, ",", 2); String daysOfWeek = convertDayNamesToCron(parts[0]); LocalTime time = parseTime(parts[1]); return String.format("0 %d %d ? * %s", time.getMinute(), time.getHour(), daysOfWeek); } // æ¯æä»»å¡è½¬æ¢ private String convertMonthlyToCron(String frequencyDetail) { String[] parts = validateAndSplit(frequencyDetail, ",", 2); int day = validateDayOfMonth(parts[0]); LocalTime time = parseTime(parts[1]); return String.format("0 %d %d %d * ?", time.getMinute(), time.getHour(), day); } // æ¯å£åº¦ä»»å¡è½¬æ¢ private String convertQuarterlyToCron(String frequencyDetail) { String[] parts = validateAndSplit(frequencyDetail, ",", 3); int month = validateMonth(parts[0]); // éªè¯æä»½(1-12) int day = validateDayOfMonth(parts[1]); // éªè¯æ¥æ LocalTime time = parseTime(parts[2]); // è§£ææ¶é´ // 计ç®å£åº¦èµ·å§æä»½(1æ=1, 4æ=4, 7æ=7, 10æ=10) int quarterStartMonth = ((month - 1) / 3) * 3 + 1; return String.format("0 %d %d %d %d/3 ?", time.getMinute(), time.getHour(), day, quarterStartMonth); } // æ°å¢éªè¯æä»½çæ¹æ³(1-12) private int validateMonth(String monthStr) { try { int month = Integer.parseInt(monthStr); if (month < 1 || month > 12) { throw new IllegalArgumentException("æä»½å¿ é¡»å¨1-12ä¹é´"); } return month; } catch (NumberFormatException e) { throw new IllegalArgumentException("æ æçæä»½æ ¼å¼"); } } // è¾ å©æ¹æ³ï¼è§£ææ¶é´ private LocalTime parseTime(String timeStr) { try { return LocalTime.parse(timeStr); } catch (DateTimeParseException e) { throw new IllegalArgumentException("æ¶é´æ ¼å¼å¿ 须为HH:mm", e); } } // è¾ å©æ¹æ³ï¼éªè¯å¹¶åå²å符串 private String[] validateAndSplit(String input, String delimiter, int expectedParts) { String[] parts = input.split(delimiter); if (parts.length != expectedParts) { throw new IllegalArgumentException( String.format("æ ¼å¼é误ï¼åºä¸º%dé¨åç¨'%s'åé", expectedParts, delimiter)); } return parts; } // è¾ å©æ¹æ³ï¼éªè¯æä»½ä¸çæ¥ private int validateDayOfMonth(String dayStr) { int day = Integer.parseInt(dayStr); if (day < 1 || day > 31) { throw new IllegalArgumentException("æ¥æå¿ é¡»å¨1-31ä¹é´"); } return day; } // è¾ å©æ¹æ³ï¼éªè¯å£åº¦ä¸çæ private int validateMonthInQuarter(String monthStr) { int month = Integer.parseInt(monthStr); if (month < 1 || month > 3) { throw new IllegalArgumentException("å£åº¦æä»½å¿ é¡»æ¯1ã2æ3"); } return month; } // è½¬æ¢ææå åç§° private String convertDayNamesToCron(String dayNames) { return Arrays.stream(dayNames.split("\\|")) .map(this::convertSingleDayName) .collect(Collectors.joining(",")); } // 转æ¢å个ææå åç§° private String convertSingleDayName(String dayName) { switch (dayName.toUpperCase()) { case "MON": return "MON"; case "TUE": return "TUE"; case "WED": return "WED"; case "THU": return "THU"; case "FRI": return "FRI"; case "SAT": return "SAT"; case "SUN": return "SUN"; default: throw new IllegalArgumentException("æ æçææå : " + dayName); } } } main-business/src/main/java/com/ruoyi/business/service/impl/TimingTaskServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,405 @@ package com.ruoyi.business.service.impl; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.business.dto.TimingTaskDto; import com.ruoyi.business.entity.TimingTask; import com.ruoyi.business.mapper.InspectionTaskMapper; import com.ruoyi.business.mapper.TimingTaskMapper; import com.ruoyi.business.service.TimingTaskService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.system.mapper.SysUserMapper; import lombok.extern.slf4j.Slf4j; import org.quartz.SchedulerException; import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; import org.springframework.transaction.annotation.Transactional; import java.time.*; import java.util.*; import java.util.stream.Collectors; /** * <p> * 宿¶å·¡æ£ä»»å¡è¡¨ æå¡å®ç°ç±» * </p> * * @author ld * @since 2025-06-30 */ @Service @Slf4j @RequiredArgsConstructor public class TimingTaskServiceImpl extends ServiceImpl<TimingTaskMapper, TimingTask> implements TimingTaskService { private final TimingTaskMapper timingTaskMapper; private final InspectionTaskMapper inspectionTaskMapper; private final TimingTaskScheduler timingTaskScheduler; private final SysUserMapper sysUserMapper; @Override public IPage<TimingTaskDto> selectTimingTaskList(Page<TimingTask> page, TimingTask timingTask) { // 1. å å页æ¥è¯¢å®æ¶ä»»å¡æ°æ® IPage<TimingTask> taskPage = timingTaskMapper.selectPage(page, null); // 2. å¦ææ²¡ææ°æ®ï¼ç´æ¥è¿å空å页 if (taskPage.getRecords().isEmpty()) { return new Page<>(taskPage.getCurrent(), taskPage.getSize(), taskPage.getTotal()); } // 3. æ¶éææéè¦æ¥è¯¢çç¨æ·ID Set<Long> userIds = new HashSet<>(); // æ¶éç»è®°äººID taskPage.getRecords().forEach(task -> { if (task.getRegistrantId() != null) { userIds.add(task.getRegistrantId()); } }); // æ¶éå·¡æ£äººIDï¼å¤ä¸ªID以éå·åéï¼ taskPage.getRecords().forEach(task -> { if (StringUtils.isNotBlank(task.getInspectorIds())) { Arrays.stream(task.getInspectorIds().split(",")) .filter(StringUtils::isNotBlank) .map(Long::valueOf) .forEach(userIds::add); } }); // 4. æ¹éæ¥è¯¢ç¨æ·ä¿¡æ¯ Map<Long, String> userNickNameMap = new HashMap<>(); if (!userIds.isEmpty()) { List<SysUser> users = sysUserMapper.selectBatchIds(userIds); users.forEach(user -> userNickNameMap.put(user.getUserId(), user.getNickName())); } // 5. 转æ¢ä¸ºDTO List<TimingTaskDto> dtoList = taskPage.getRecords().stream().map(task -> { TimingTaskDto dto = new TimingTaskDto(); // å¤å¶åºæ¬å±æ§ BeanUtils.copyProperties(task, dto); // 设置ç»è®°äººæµç§° if (task.getRegistrantId() != null) { dto.setRegistrant(userNickNameMap.getOrDefault(task.getRegistrantId(), "æªç¥ç¨æ·")); } // 设置巡æ£äººæµç§°å表 if (StringUtils.isNotBlank(task.getInspectorIds())) { List<String> inspectorNickNames = Arrays.stream(task.getInspectorIds().split(",")) .filter(StringUtils::isNotBlank) .map(idStr -> { Long id = Long.valueOf(idStr); return userNickNameMap.getOrDefault(id, "æªç¥ç¨æ·"); }) .toList(); dto.setInspector(inspectorNickNames.toString()); } return dto; }).collect(Collectors.toList()); // 6. æå»ºè¿åçå页对象 Page<TimingTaskDto> resultPage = new Page<>(taskPage.getCurrent(), taskPage.getSize(), taskPage.getTotal()); resultPage.setRecords(dtoList); return resultPage; } @Override @Transactional public int addOrEditTimingTask(TimingTaskDto timingTaskDto) throws SchedulerException { TimingTask timingTask = new TimingTask(); BeanUtils.copyProperties(timingTaskDto, timingTask); // 设置å建人信æ¯åé»è®¤å¼ if (Objects.isNull(timingTaskDto.getId())) { timingTask.setRegistrationDate(LocalDate.now()); timingTask.setActive(true); // 计ç®é¦æ¬¡æ§è¡æ¶é´ LocalDateTime firstExecutionTime = calculateFirstExecutionTime(timingTask); timingTask.setNexExecutionTime(firstExecutionTime); int result = timingTaskMapper.insert(timingTask); if (result > 0) { // æ°å¢æååæ·»å å°è°åº¦å¨ timingTaskScheduler.scheduleTimingTask(timingTask); } return result; } else { int result = timingTaskMapper.updateById(timingTask); if (result > 0) { // æ´æ°æååéæ°è°åº¦ä»»å¡ timingTaskScheduler.rescheduleTimingTask(timingTask); } return result; } } private LocalDateTime calculateFirstExecutionTime(TimingTask task) { // æ ¹æ®é¢çç±»åå详æ 计ç®é¦æ¬¡æ§è¡æ¶é´ return switch (task.getFrequencyType()) { case "DAILY" -> // å¦ææ¯æ¯å¤©æ§è¡ï¼è®¡ç®ä»å¤©ææå¤©çå ·ä½æ¶é´ calculateDailyFirstExecution(task.getFrequencyDetail()); case "WEEKLY" -> // å¦ææ¯æ¯å¨æ§è¡ï¼è®¡ç®ä¸å¨çå ·ä½ææå calculateWeeklyFirstExecution(task.getFrequencyDetail()); case "MONTHLY" -> // å¦ææ¯æ¯ææ§è¡ï¼è®¡ç®ä¸ä¸ªæçå ·ä½æ¥æ calculateMonthlyFirstExecution(task.getFrequencyDetail()); case "QUARTERLY" -> // èªå®ä¹é¢çï¼å¦æ¯å°æ¶ãæ¯30åéç calculateCustomFirstExecution(task.getFrequencyDetail()); default -> throw new IllegalArgumentException("䏿¯æçé¢çç±»å: " + task.getFrequencyType()); }; } private LocalDateTime calculateDailyFirstExecution(String frequencyDetail) { // frequencyDetailå¯è½æ¯å ·ä½æ¶é´ï¼å¦ "14:30" LocalTime executionTime = LocalTime.parse(frequencyDetail); LocalDateTime now = LocalDateTime.now(); LocalDateTime todayExecution = LocalDateTime.of(now.toLocalDate(), executionTime); // 妿ä»å¤©çæ¶é´å·²è¿ï¼å宿æå¤©æ§è¡ return now.isBefore(todayExecution) ? todayExecution : todayExecution.plusDays(1); } private LocalDateTime calculateWeeklyFirstExecution(String frequencyDetail) { return null; } private LocalDateTime calculateMonthlyFirstExecution(String frequencyDetail) { return null; } private LocalDateTime calculateCustomFirstExecution(String frequencyDetail) { return null; } @Override @Transactional public void updateTaskExecutionTime(Long taskId) { TimingTask task = timingTaskMapper.selectById(taskId); if (task == null) { throw new RuntimeException("宿¶ä»»å¡ä¸åå¨ï¼ID: " + taskId); } // æ´æ°æåæ§è¡æ¶é´ä¸ºå½åæ¶é´ task.setLastExecuteTime(LocalDateTime.now()); // 计ç®ä¸æ¬¡æ§è¡æ¶é´ LocalDateTime nextExecutionTime = calculateNextExecutionTime( task.getFrequencyType(), task.getFrequencyDetail(), LocalDateTime.now() ); task.setNexExecutionTime(nextExecutionTime); // æ´æ°æ°æ®åº timingTaskMapper.updateById(task); } /** * 计ç®ä¸æ¬¡æ§è¡æ¶é´ */ private LocalDateTime calculateNextExecutionTime(String frequencyType, String frequencyDetail, LocalDateTime currentTime) { try { return switch (frequencyType) { case "DAILY" -> calculateDailyNextTime(frequencyDetail, currentTime); case "WEEKLY" -> calculateWeeklyNextTime(frequencyDetail, currentTime); case "MONTHLY" -> calculateMonthlyNextTime(frequencyDetail, currentTime); case "QUARTERLY" -> calculateQuarterlyNextTime(frequencyDetail, currentTime); default -> throw new IllegalArgumentException("䏿¯æçé¢çç±»å: " + frequencyType); }; } catch (Exception e) { throw new RuntimeException("计ç®ä¸æ¬¡æ§è¡æ¶é´å¤±è´¥: " + e.getMessage(), e); } } /** * è®¡ç®æ¯æ¥ä»»å¡ç䏿¬¡æ§è¡æ¶é´ */ private LocalDateTime calculateDailyNextTime(String timeStr, LocalDateTime current) { LocalTime executionTime = LocalTime.parse(timeStr); // è§£ææ ¼å¼ "HH:mm" LocalDateTime nextTime = LocalDateTime.of(current.toLocalDate(), executionTime); // 妿ä»å¤©çæ¶é´å·²è¿ï¼å宿æå¤© return current.isBefore(nextTime) ? nextTime : nextTime.plusDays(1); } /** * è®¡ç®æ¯å¨ä»»å¡ç䏿¬¡æ§è¡æ¶é´ */ private LocalDateTime calculateWeeklyNextTime(String detail, LocalDateTime current) { String[] parts = detail.split(","); String dayOfWeekStr = parts[0]; // å¦ "MON" æ "MON|WED|FRI" LocalTime time = LocalTime.parse(parts[1]); // æ¶é´é¨å // è§£æææå (æ¯æå¤ä¸ªææ) Set<DayOfWeek> targetDays = parseDayOfWeeks(dayOfWeekStr); // ä»å½åæ¶é´å¼å§æ¾ä¸ä¸ä¸ªç¬¦åæ¡ä»¶çææå LocalDateTime nextTime = current; while (true) { nextTime = nextTime.plusDays(1); if (targetDays.contains(nextTime.getDayOfWeek())) { return LocalDateTime.of(nextTime.toLocalDate(), time); } // 鲿¢æ é循ç¯(ç论ä¸ä¸ä¼åç) if (nextTime.isAfter(current.plusYears(1))) { throw new RuntimeException("æ æ³æ¾å°ä¸æ¬¡æ§è¡æ¶é´"); } } } /** * è®¡ç®æ¯æä»»å¡ç䏿¬¡æ§è¡æ¶é´ */ private LocalDateTime calculateMonthlyNextTime(String detail, LocalDateTime current) { String[] parts = detail.split(","); int dayOfMonth = Integer.parseInt(parts[0]); LocalTime time = LocalTime.parse(parts[1]); // ä»ä¸ä¸ªæå¼å§è®¡ç® LocalDateTime nextTime = current.plusMonths(1) .withDayOfMonth(Math.min(dayOfMonth, current.plusMonths(1).toLocalDate().lengthOfMonth())) .with(time); return nextTime; } /** * è®¡ç®æ¯å£åº¦ä»»å¡ç䏿¬¡æ§è¡æ¶é´ */ private LocalDateTime calculateQuarterlyNextTime(String detail, LocalDateTime current) { String[] parts = detail.split(","); int quarterMonth = Integer.parseInt(parts[0]); // 1=第1个æï¼2=第2个æï¼3=第3个æ int dayOfMonth = Integer.parseInt(parts[1]); LocalTime time = LocalTime.parse(parts[2]); // 计ç®å½åå£åº¦ int currentQuarter = (current.getMonthValue() - 1) / 3 + 1; int currentMonthInQuarter = (current.getMonthValue() - 1) % 3 + 1; YearMonth targetYearMonth; if (currentMonthInQuarter < quarterMonth) { // æ¬å£åº¦å è¿ææ§è¡æºä¼ targetYearMonth = YearMonth.from(current) .plusMonths(quarterMonth - currentMonthInQuarter); } else { // éè¦å°ä¸ä¸ªå£åº¦ targetYearMonth = YearMonth.from(current) .plusMonths(3 - currentMonthInQuarter + quarterMonth); } // å¤çææ«æ¥æ int adjustedDay = Math.min(dayOfMonth, targetYearMonth.lengthOfMonth()); return LocalDateTime.of( targetYearMonth.getYear(), targetYearMonth.getMonthValue(), adjustedDay, time.getHour(), time.getMinute() ); } /** * è§£æææå å符串 */ private Set<DayOfWeek> parseDayOfWeeks(String dayOfWeekStr) { Set<DayOfWeek> days = new HashSet<>(); String[] dayStrs = dayOfWeekStr.split("\\|"); for (String dayStr : dayStrs) { switch (dayStr) { case "MON": days.add(DayOfWeek.MONDAY); break; case "TUE": days.add(DayOfWeek.TUESDAY); break; case "WED": days.add(DayOfWeek.WEDNESDAY); break; case "THU": days.add(DayOfWeek.THURSDAY); break; case "FRI": days.add(DayOfWeek.FRIDAY); break; case "SAT": days.add(DayOfWeek.SATURDAY); break; case "SUN": days.add(DayOfWeek.SUNDAY); break; default: throw new IllegalArgumentException("æ æçææå : " + dayStr); } } return days; } // /** // * æ¯å¤©17:40åæ¶è§¦åï¼æ§è¡å°æä»»å¡ // */ // @Scheduled(cron = "0 55 17 * * ?", zone = "Asia/Shanghai") // @Transactional // public void executeDueTasks() { // LocalDateTime now = LocalDateTime.now(); // log.info("宿¶ä»»å¡è§¦åï¼å½åæ¶é´: {}", now); // // // 1. æ¥è¯¢ææéè¦ç«å³æ§è¡çä»»å¡ // List<TimingTask> dueTasks = timingTaskMapper.selectActiveTasks(now); // // // 2. å¤çæ¯ä¸ªä»»å¡ // dueTasks.forEach(task -> { // // 2.1 转æ¢ä¸ºå·¡æ£ä»»å¡å¹¶ä¿å // InspectionTask inspectionTask = convertToInspectionTask(task); // inspectionTaskMapper.insert(inspectionTask); // // // 2.2 计ç®å¹¶æ´æ°ä¸æ¬¡æ§è¡æ¶é´ // updateNextExecutionTime(task, now); // // log.info("ä»»å¡[{}]å·²æ§è¡ï¼ä¸æ¬¡æ§è¡æ¶é´: {}", // task.getTaskName(), // task.getNexExecutionTime()); // }); // } // // private InspectionTask convertToInspectionTask(TimingTask timingTask) { // InspectionTask inspectionTask = new InspectionTask(); // // // å¤å¶åºæ¬å±æ§ // inspectionTask.setTaskName(timingTask.getTaskName()); // inspectionTask.setInspectorId(timingTask.getInspectorIds()); // inspectionTask.setPort(timingTask.getInspectionLocation()); // inspectionTask.setRemarks("èªå¨çæèªå®æ¶ä»»å¡ID: " + timingTask.getId()); // inspectionTask.setRegistrantId(timingTask.getRegistrantId()); // inspectionTask.setFrequency(timingTask.getFrequencyType()); // return inspectionTask; // } // // private void updateNextExecutionTime(TimingTask task, LocalDateTime currentExecutionTime) { // switch (task.getFrequencyType()) { // case "DAILY": // task.setNexExecutionTime(currentExecutionTime.plusDays(1)); // break; // case "WEEKLY": // task.setNexExecutionTime(currentExecutionTime.plusWeeks(1)); // break; // case "MONTHLY": // task.setNexExecutionTime(currentExecutionTime.plusMonths(1)); // break; // default: // task.setNexExecutionTime(null); // 忬¡ä»»å¡ // } // timingTaskMapper.updateById(task); // } @Override public int delByIds(Long[] ids) { return timingTaskMapper.deleteByIds(Arrays.asList(ids)); } } main-business/src/main/java/com/ruoyi/business/task/TimingTaskJob.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,66 @@ package com.ruoyi.business.task; import com.ruoyi.business.entity.InspectionTask; import com.ruoyi.business.entity.TimingTask; import com.ruoyi.business.mapper.InspectionTaskMapper; import com.ruoyi.business.service.TimingTaskService; import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.time.LocalDateTime; @Component @DisallowConcurrentExecution // ç¦æ¢å¹¶åæ§è¡åä¸ä¸ªJob public class TimingTaskJob implements Job { @Autowired private TimingTaskService timingTaskService; @Autowired private InspectionTaskMapper inspectionTaskMapper; @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); Long taskId = jobDataMap.getLong("taskId"); try { // 1. è·å宿¶ä»»å¡è¯¦æ TimingTask timingTask = timingTaskService.getById(taskId); if (timingTask == null || !timingTask.isActive()) { return; } // 2. å建并ä¿åå·¡æ£ä»»å¡è®°å½ - è¿å°±æ¯æ¨æä¾ç代ç åºè¯¥æ¾çä½ç½® InspectionTask inspectionTask = createInspectionTask(timingTask); inspectionTaskMapper.insert(inspectionTask); // 3. æ´æ°å®æ¶ä»»å¡çæ§è¡æ¶é´ timingTaskService.updateTaskExecutionTime(taskId); // 4. è®°å½æ§è¡æ¥å¿ // timingTaskService.recordExecutionLog(taskId, true, "任塿§è¡æåï¼çæå·¡æ£ä»»å¡ID: " + inspectionTask.getId()); } catch (Exception e) { // timingTaskService.recordExecutionLog(taskId, false, "任塿§è¡å¤±è´¥: " + e.getMessage()); throw new JobExecutionException(e); } } // è¿å°±æ¯æ¨æä¾ç代ç å°è£ æçæ¹æ³ private InspectionTask createInspectionTask(TimingTask timingTask) { InspectionTask inspectionTask = new InspectionTask(); // å¤å¶åºæ¬å±æ§ inspectionTask.setTaskName(timingTask.getTaskName()); inspectionTask.setInspectorId(timingTask.getInspectorIds()); inspectionTask.setInspectionLocation(timingTask.getInspectionLocation()); inspectionTask.setRemarks("èªå¨çæèªå®æ¶ä»»å¡ID: " + timingTask.getId()); inspectionTask.setRegistrantId(timingTask.getRegistrantId()); inspectionTask.setFrequencyType(timingTask.getFrequencyType()); return inspectionTask; } } main-business/src/main/resources/db/migration/postgresql/V20250614134700__create_table_inspection_task.sql
@@ -9,6 +9,7 @@ remarks TEXT, -- 夿³¨è¯´æ registrant_id BIGINT, -- ç»è®°äººåid registrant VARCHAR(100), -- ç»è®°äººå frequency VARCHAR(100), -- 颿¬¡ deleted INT NOT NULL DEFAULT 0, -- 软å 餿 å¿ï¼0=æªå é¤ï¼1=å·²å é¤ create_by VARCHAR(255), -- åå»ºäººç¨æ·å @@ -17,18 +18,30 @@ update_time TIMESTAMP WITHOUT TIME ZONE -- æåæ´æ°æ¶é´ï¼é»è®¤å½åæ¶é´ ); -- æ·»å 表注é COMMENT ON TABLE inspection_task IS 'å·¡æ£ä»»å¡è¡¨'; COMMENT ON TABLE inspection_task IS 'å·¡æ£ä»»å¡è¡¨'; -- æ·»å åæ®µæ³¨é COMMENT ON COLUMN inspection_task.id IS 'å·¡æ£ä»»å¡å¯ä¸æ è¯'; COMMENT ON COLUMN inspection_task.task_name IS 'å·¡æ£ä»»å¡åç§°'; COMMENT ON COLUMN inspection_task.inspector IS 'æ§è¡å·¡æ£ç人åå§å'; COMMENT ON COLUMN inspection_task.port IS 'å·¡æ£å°ç¹è¯¦ç»æè¿°'; COMMENT ON COLUMN inspection_task.remarks IS 'ä»»å¡éå 说ææç¹æ®æ åµè®°å½'; COMMENT ON COLUMN inspection_task.registrant IS 'ä»»å¡ç»è®°äººå§å'; COMMENT ON COLUMN inspection_task.id IS 'å·¡æ£ä»»å¡å¯ä¸æ è¯'; COMMENT ON COLUMN inspection_task.task_name IS 'å·¡æ£ä»»å¡åç§°'; COMMENT ON COLUMN inspection_task.inspector IS 'æ§è¡å·¡æ£ç人åå§å'; COMMENT ON COLUMN inspection_task.port IS 'å·¡æ£å°ç¹è¯¦ç»æè¿°'; COMMENT ON COLUMN inspection_task.remarks IS 'ä»»å¡éå 说ææç¹æ®æ åµè®°å½'; COMMENT ON COLUMN inspection_task.registrant IS 'ä»»å¡ç»è®°äººå§å'; COMMENT ON COLUMN inspection_task.deleted IS '软å 餿 å¿ï¼0=æªå é¤ï¼1=å·²å é¤'; COMMENT ON COLUMN inspection_task.create_by IS 'å建该记å½çç¨æ·'; COMMENT ON COLUMN inspection_task.create_time IS 'è®°å½å建æ¶é´'; COMMENT ON COLUMN inspection_task.update_by IS 'æåä¿®æ¹è¯¥è®°å½çç¨æ·'; COMMENT ON COLUMN inspection_task.update_time IS 'è®°å½æåæ´æ°æ¶é´'; COMMENT ON COLUMN inspection_task.deleted IS '软å 餿 å¿ï¼0=æªå é¤ï¼1=å·²å é¤'; COMMENT ON COLUMN inspection_task.create_by IS 'å建该记å½çç¨æ·'; COMMENT ON COLUMN inspection_task.create_time IS 'è®°å½å建æ¶é´'; COMMENT ON COLUMN inspection_task.update_by IS 'æåä¿®æ¹è¯¥è®°å½çç¨æ·'; COMMENT ON COLUMN inspection_task.update_time IS 'è®°å½æåæ´æ°æ¶é´'; main-business/src/main/resources/db/migration/postgresql/V20250630153900__create_table_timing_task.sql
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,63 @@ CREATE TABLE timing_task ( id BIGSERIAL PRIMARY KEY, -- 主é®IDï¼èªå¨éå¢ task_name VARCHAR(255) NOT NULL, -- ä»»å¡åç§°ï¼ä¸å 许为空 inspector_ids VARCHAR(255) NOT NULL, -- å·¡æ£äººidsï¼ä¸å 许为空 inspection_location VARCHAR(255) NOT NULL, -- å·¡æ£å°ç¹ï¼ä¸å 许为空 -- 宿¶é ç½® frequency_type VARCHAR(20) NOT NULL CHECK (frequency_type IN ('DAILY', 'WEEKLY', 'MONTHLY', 'QUARTERLY')), frequency_detail VARCHAR(100), -- å ·ä½æ¶é´é ç½® -- æ¯æ¥ä»»å¡é 置示ä¾ï¼frequency_type='DAILY', frequency_detail='14:30' -- æ¯å¨ä»»å¡é 置示ä¾ï¼frequency_type='WEEKLY', frequency_detail='MON;14:30' -- æ¯æä»»å¡é 置示ä¾ï¼frequency_type='MONTHLY', frequency_detail='15;14:30' (æ¯æ15æ¥14:30) -- æ¯å£åº¦ä»»å¡é 置示ä¾ï¼frequency_type='QUARTERLY', frequency_detail='15;14:30' (æ¯å£åº¦ç¬¬ä¸ä¸ªæ15æ¥14:30) next_execution_time TIMESTAMP, -- 䏿¬¡æ§è¡æ¶é´ last_execution_time TIMESTAMP, -- æåæ§è¡æ¶é´ is_active BOOLEAN DEFAULT TRUE, -- æ¯å¦æ¿æ´» remarks TEXT, -- 夿³¨ registrant_id BIGINT, -- ç»è®°äººidï¼ä¸å 许为空 registrant VARCHAR(255) NOT NULL, -- ç»è®°äººï¼ä¸å 许为空 registration_date DATE NOT NULL, -- ç»è®°æ¥æï¼ä¸å 许为空 deleted INT NOT NULL DEFAULT 0, -- 软å 餿 å¿ï¼0=æªå é¤ï¼1=å·²å é¤ create_by VARCHAR(255), -- åå»ºäººç¨æ·å create_time TIMESTAMP WITHOUT TIME ZONE, -- å建æ¶é´ï¼é»è®¤å½åæ¶é´ update_by VARCHAR(255), -- æåæ´æ°äººç¨æ·å update_time TIMESTAMP WITHOUT TIME ZONE -- æåæ´æ°æ¶é´ï¼é»è®¤å½åæ¶é´ ); -- ä¸ºè¡¨æ·»å æ³¨é COMMENT ON TABLE timing_task IS '宿¶å·¡æ£ä»»å¡è¡¨'; -- ä¸ºåæ®µæ·»å 注é COMMENT ON COLUMN timing_task.id IS '主é®ID'; COMMENT ON COLUMN timing_task.task_name IS 'ä»»å¡åç§°'; COMMENT ON COLUMN timing_task.inspector_ids IS 'å·¡æ£äºº'; COMMENT ON COLUMN timing_task.inspection_location IS 'å·¡æ£å°ç¹'; COMMENT ON COLUMN timing_task.frequency IS '颿¬¡'; COMMENT ON COLUMN timing_task.remarks IS '夿³¨'; COMMENT ON COLUMN timing_task.registrant_id IS 'ç»è®°äººid'; COMMENT ON COLUMN timing_task.registrant IS 'ç»è®°äºº'; COMMENT ON COLUMN timing_task.registration_date IS 'ç»è®°æ¥æ'; COMMENT ON COLUMN timing_task.deleted IS '软å 餿 å¿ï¼0=æªå é¤ï¼1=å·²å é¤'; COMMENT ON COLUMN timing_task.create_by IS 'å建该记å½çç¨æ·'; COMMENT ON COLUMN timing_task.create_time IS 'è®°å½å建æ¶é´'; COMMENT ON COLUMN timing_task.update_by IS 'æåä¿®æ¹è¯¥è®°å½çç¨æ·'; COMMENT ON COLUMN timing_task.update_time IS 'è®°å½æåæ´æ°æ¶é´'; main-business/src/main/resources/db/migration/postgresql/V20250701142700__create_table_equipment_management.sql
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,59 @@ DROP TABLE IF EXISTS equipment_management; -- å建设å¤ç®¡ç表 CREATE TABLE equipment_management ( id BIGSERIAL PRIMARY KEY, -- ä¸»é® ID equipment_id VARCHAR(50) NOT NULL, -- 设å¤ç¼å· equipment_name VARCHAR(100) NOT NULL, -- 设å¤åç§° quantity INT NOT NULL DEFAULT 0, -- æ°é specification VARCHAR(50) NOT NULL, -- è§æ ¼åå· usage_status VARCHAR(20) NOT NULL, -- 使ç¨ç¶æ using_department VARCHAR(50) NOT NULL, -- 使ç¨é¨é¨ user_id BIGINT, -- 使ç¨äºº storage_location VARCHAR(100) NOT NULL, -- åæ¾ä½ç½® purchase_date DATE, -- éè´æ¥æ purchase_price DECIMAL(10, 2), -- éè´ä»·æ ¼ deleted INT NOT NULL DEFAULT 0, -- 软å 餿 å¿ï¼0=æªå é¤ï¼1=å·²å é¤ create_by VARCHAR(255), -- åå»ºäººç¨æ·å create_time TIMESTAMP WITHOUT TIME ZONE, -- å建æ¶é´ï¼é»è®¤å½åæ¶é´ update_by VARCHAR(255), -- æåæ´æ°äººç¨æ·å update_time TIMESTAMP WITHOUT TIME ZONE -- æåæ´æ°æ¶é´ï¼é»è®¤å½åæ¶é´ ); -- æ·»å 表注é COMMENT ON TABLE equipment_management IS ' 设å¤ç®¡ç表 '; -- æ·»å åæ®µæ³¨é COMMENT ON COLUMN equipment_management.id IS ' ä¸»é® ID'; COMMENT ON COLUMN equipment_management.equipment_id IS ' 设å¤ç¼å· '; COMMENT ON COLUMN equipment_management.equipment_name IS ' 设å¤åç§° '; COMMENT ON COLUMN equipment_management.quantity IS ' æ°é '; COMMENT ON COLUMN equipment_management.specification IS ' è§æ ¼åå· '; COMMENT ON COLUMN equipment_management.usage_status IS ' 使ç¨ç¶æ '; COMMENT ON COLUMN equipment_management.using_department IS ' 使ç¨é¨é¨ '; COMMENT ON COLUMN equipment_management.user_id IS ' 使ç¨äººID '; COMMENT ON COLUMN equipment_management.storage_location IS ' åæ¾ä½ç½® '; COMMENT ON COLUMN equipment_management.purchase_date IS ' éè´æ¥æ '; COMMENT ON COLUMN equipment_management.purchase_price IS ' éè´ä»·æ ¼ '; COMMENT ON COLUMN inspection_task.deleted IS '软å 餿 å¿ï¼0=æªå é¤ï¼1=å·²å é¤'; COMMENT ON COLUMN inspection_task.create_by IS 'å建该记å½çç¨æ·'; COMMENT ON COLUMN inspection_task.create_time IS 'è®°å½å建æ¶é´'; COMMENT ON COLUMN inspection_task.update_by IS 'æåä¿®æ¹è¯¥è®°å½çç¨æ·'; COMMENT ON COLUMN inspection_task.update_time IS 'è®°å½æåæ´æ°æ¶é´'; main-business/src/main/resources/mapper/EquipmentManagementMapper.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,35 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.business.mapper.EquipmentManagementMapper"> <!-- éç¨æ¥è¯¢æ å°ç»æ --> <resultMap id="BaseResultMap" type="com.ruoyi.business.entity.EquipmentManagement"> <id column="id" property="id" /> <result column="deleted" property="deleted" /> <result column="create_by" property="createBy" /> <result column="create_time" property="createTime" /> <result column="update_by" property="updateBy" /> <result column="update_time" property="updateTime" /> <result column="equipment_id" property="equipmentId" /> <result column="equipment_name" property="equipmentName" /> <result column="quantity" property="quantity" /> <result column="specification" property="specification" /> <result column="usage_status" property="usageStatus" /> <result column="using_department" property="usingDepartment" /> <result column="user_id" property="userId" /> <result column="storage_location" property="storageLocation" /> <result column="purchase_date" property="purchaseDate" /> <result column="purchase_price" property="purchasePrice" /> </resultMap> <!-- éç¨æ¥è¯¢ç»æå --> <sql id="Base_Column_List"> deleted, create_by, create_time, update_by, update_time, id, equipment_id, equipment_name, quantity, specification, usage_status, using_department, user_id, storage_location, purchase_date, purchase_price </sql> </mapper> main-business/src/main/resources/mapper/TimingTaskMapper.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,33 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.business.mapper.TimingTaskMapper"> <!-- éç¨æ¥è¯¢æ å°ç»æ --> <resultMap id="BaseResultMap" type="com.ruoyi.business.entity.TimingTask"> <id column="id" property="id" /> <result column="deleted" property="deleted" /> <result column="create_by" property="createBy" /> <result column="create_time" property="createTime" /> <result column="update_by" property="updateBy" /> <result column="update_time" property="updateTime" /> <result column="task_name" property="taskName" /> <result column="inspector_ids" property="inspectorIds" /> <result column="inspection_location" property="inspectionLocation" /> <result column="frequency" property="frequency" /> <result column="remarks" property="remarks" /> <result column="registrant_id" property="registrantId" /> <result column="registrant" property="registrant" /> <result column="registration_date" property="registrationDate" /> </resultMap> <!-- éç¨æ¥è¯¢ç»æå --> <sql id="Base_Column_List"> deleted, create_by, create_time, update_by, update_time, id, task_name, inspector_ids, inspection_location, frequency, remarks, registrant_id, registrant, registration_date </sql> </mapper> main-business/src/main/resources/mapper/TreeMapper.xml
@@ -23,5 +23,14 @@ update_time, id, name, parent_id </sql> <select id="listRecursiveSubNodeIds" resultType="java.lang.Long"> WITH RECURSIVE sub_nodes AS ( SELECT id FROM tree WHERE parent_id = #{treeId} UNION ALL SELECT t.id FROM tree t JOIN sub_nodes s ON t.parent_id = s.id ) SELECT id FROM sub_nodes </select> </mapper> ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
@@ -1,9 +1,13 @@ package com.ruoyi.system.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.common.core.domain.entity.SysUser; import org.apache.ibatis.annotations.Param; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; /** * ç¨æ·è¡¨ æ°æ®å± @@ -131,4 +135,13 @@ List<SysUser> selectUserListAll(); List<SysUser> selectList(List<Long> registrantIds); List<SysUser> selectUsersByIds(@Param("userIds") List<Long> userIds); /** * æ¹éæ¥è¯¢ç¨æ·ä¿¡æ¯ * @param userIds ç¨æ·IDéå * @return ç¨æ·å表 */ List<SysUser> selectBatchIds(@Param("userIds") Set<Long> userIds); } ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -158,8 +158,38 @@ </if> </where> </select> <select id="selectUsersByIds" resultType="com.ruoyi.common.core.domain.entity.SysUser"> SELECT user_id, nick_name FROM sys_user WHERE user_id IN <foreach collection="userIds" item="id" open="(" separator="," close=")"> #{id} </foreach> </select> <select id="selectBatchIds" resultType="com.ruoyi.common.core.domain.entity.SysUser"> SELECT * FROM sys_user <!-- å¤ç空éåï¼è¥ userIds 为空ï¼ä¸æ§è¡ WHERE æ¡ä»¶ï¼é¿å SQL è¯æ³éè¯¯ï¼ --> <where> <if test="userIds != null and userIds.size() > 0"> user_id = ANY( <foreach collection="userIds" item="id" open="ARRAY[" separator="," close="]"> #{id} </foreach> ) </if> </where> <!-- æåºï¼æä¼ å ¥ç userIds 顺åºè¿åç»æï¼PostgreSQL ä¸ç¨ï¼ --> <if test="userIds != null and userIds.size() > 0"> ORDER BY array_position( <foreach collection="userIds" item="id" open="ARRAY[" separator="," close="]" index="index"> #{id} </foreach>, user_id -- 表ä¸ç id åæ®µï¼ä¸æ°ç»ä¸çå ç´ å¹é ) </if> </select> <insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId"> <insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId"> insert into sys_user( <if test="userId != null and userId != 0">user_id,</if> <if test="deptId != null and deptId != 0">dept_id,</if>