doc/20261016_É豸Ѳ¼ìÏîÄ¿ÍêÕû½Å±¾.sql
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,71 @@ ALTER TABLE `timing_task` DROP COLUMN `inspection_project`; ALTER TABLE `inspection_task` DROP COLUMN `inspection_project`; CREATE TABLE `inspection_item` ( `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'å·¡æ£å 容主é®', `item_project` VARCHAR(200) NOT NULL COMMENT 'å·¡æ£é¡¹ç®', `item_content` VARCHAR(2000) NOT NULL COMMENT 'å·¡æ£å 容', `device_ledger_id` BIGINT DEFAULT NULL COMMENT 'æå±è®¾å¤ï¼NULL表示éç¨å 容', `frequency_type` VARCHAR(20) NOT NULL COMMENT 'é¢çï¼DAILY/WEEKLY/MONTHLY/QUARTERLY/ALL', `sort_num` INT NOT NULL DEFAULT 0 COMMENT 'æåºå·', `is_active` TINYINT NOT NULL DEFAULT 1 COMMENT 'å¯ç¨ç¶æï¼0åç¨ï¼1å¯ç¨', `remarks` VARCHAR(500) DEFAULT NULL COMMENT '夿³¨', `deleted` TINYINT NOT NULL DEFAULT 0 COMMENT '软å é¤ï¼0æªå é¤ï¼1å·²å é¤', `create_user` INT DEFAULT NULL COMMENT 'å建人', `update_user` INT DEFAULT NULL COMMENT 'ä¿®æ¹äºº', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'ä¿®æ¹æ¶é´', `tenant_id` BIGINT DEFAULT NULL COMMENT 'ç§æ·ID', `dept_id` BIGINT DEFAULT NULL COMMENT 'é¨é¨ID', PRIMARY KEY (`id`), KEY `idx_inspection_item_device_frequency` (`device_ledger_id`, `frequency_type`, `deleted`, `is_active`), KEY `idx_inspection_item_project` (`item_project`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='设å¤å·¡æ£å 容åº'; CREATE TABLE `timing_task_item` ( `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ä»»å¡å å®¹å ³è主é®', `timing_task_id` BIGINT NOT NULL COMMENT '宿¶å·¡æ£ä»»å¡ID', `inspection_item_id` BIGINT DEFAULT NULL COMMENT 'å·¡æ£å 容IDï¼ä¸ºç©ºæ¶è¡¨ç¤ºæ¬ä»»å¡èªå®ä¹å 容', `item_project` VARCHAR(200) NOT NULL COMMENT 'å·¡æ£é¡¹ç®å¿«ç §', `item_content` VARCHAR(2000) NOT NULL COMMENT 'å·¡æ£å å®¹å¿«ç §', `sort_num` INT NOT NULL DEFAULT 0 COMMENT 'ä»»å¡å æåºå·', `create_user` INT DEFAULT NULL COMMENT 'å建人', `update_user` INT DEFAULT NULL COMMENT 'ä¿®æ¹äºº', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'ä¿®æ¹æ¶é´', `tenant_id` BIGINT DEFAULT NULL COMMENT 'ç§æ·ID', `dept_id` BIGINT DEFAULT NULL COMMENT 'é¨é¨ID', PRIMARY KEY (`id`), UNIQUE KEY `uk_timing_task_inspection_item` (`timing_task_id`, `inspection_item_id`), KEY `idx_timing_task_item_content` (`inspection_item_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='宿¶å·¡æ£ä»»å¡å å®¹å ³è'; CREATE TABLE `inspection_task_item` ( `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'å·¡æ£è®°å½å 容主é®', `inspection_task_id` BIGINT NOT NULL COMMENT 'å·¡æ£è®°å½ID', `inspection_item_id` BIGINT DEFAULT NULL COMMENT 'æ¥æºå·¡æ£å 容ID', `item_project` VARCHAR(200) NOT NULL COMMENT 'å·¡æ£é¡¹ç®å¿«ç §', `item_content` VARCHAR(2000) NOT NULL COMMENT 'å·¡æ£å å®¹å¿«ç §', `item_status` TINYINT NOT NULL DEFAULT 0 COMMENT 'å®æç¶æï¼0æªå®æï¼1已宿', `remarks` VARCHAR(500) DEFAULT NULL COMMENT 'å·¡æ£å¤æ³¨', `sort_num` INT NOT NULL DEFAULT 0 COMMENT 'è®°å½å æåºå·', `completed_by` BIGINT DEFAULT NULL COMMENT '宿巡æ£çç¨æ·ID', `completed_time` DATETIME DEFAULT NULL COMMENT '宿æ¶é´', `create_user` INT DEFAULT NULL COMMENT 'å建人', `update_user` INT DEFAULT NULL COMMENT 'ä¿®æ¹äºº', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'ä¿®æ¹æ¶é´', `tenant_id` BIGINT DEFAULT NULL COMMENT 'ç§æ·ID', `dept_id` BIGINT DEFAULT NULL COMMENT 'é¨é¨ID', PRIMARY KEY (`id`), KEY `idx_inspection_record_item` (`inspection_task_id`, `sort_num`), KEY `idx_inspection_record_item_source` (`inspection_item_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='å·¡æ£è®°å½å 容å宿æ åµ'; src/main/java/com/ruoyi/inspectiontask/controller/InspectionItemController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,70 @@ package com.ruoyi.inspectiontask.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.framework.web.domain.R; import com.ruoyi.inspectiontask.pojo.InspectionItem; import com.ruoyi.inspectiontask.service.InspectionItemService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.List; @Tag(name = "设å¤å·¡æ£å 容") @RestController @RequestMapping("/inspectionItem") @RequiredArgsConstructor public class InspectionItemController { private final InspectionItemService inspectionItemService; @GetMapping("/list") @Operation(summary = "å·¡æ£å 容å表") public R<List<InspectionItem>> list( InspectionItem query, @RequestParam(defaultValue = "false") boolean includeCommon ) { return R.ok(inspectionItemService.list(query, includeCommon)); } @GetMapping("/page") @Operation(summary = "å页æ¥è¯¢å·¡æ£å 容") public R<Page<InspectionItem>> page( @RequestParam(defaultValue = "1") long pageNum, @RequestParam(defaultValue = "20") long pageSize, @RequestParam(defaultValue = "false") boolean includeCommon, InspectionItem query ) { return R.ok(inspectionItemService.page(pageNum, pageSize, includeCommon, query)); } @PostMapping @Operation(summary = "æ°å¢å·¡æ£å 容") public R<Void> create(@RequestBody InspectionItem item) { inspectionItemService.create(item); return R.ok(); } @PutMapping @Operation(summary = "ä¿®æ¹å·¡æ£å 容") public R<Void> update(@RequestBody InspectionItem item) { inspectionItemService.update(item); return R.ok(); } @DeleteMapping("/{id}") @Operation(summary = "å é¤å·¡æ£å 容") public R<Void> delete(@PathVariable Long id) { inspectionItemService.delete(id); return R.ok(); } } src/main/java/com/ruoyi/inspectiontask/mapper/InspectionItemMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,7 @@ package com.ruoyi.inspectiontask.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.inspectiontask.pojo.InspectionItem; public interface InspectionItemMapper extends BaseMapper<InspectionItem> { } src/main/java/com/ruoyi/inspectiontask/mapper/InspectionTaskItemMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,7 @@ package com.ruoyi.inspectiontask.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.inspectiontask.pojo.InspectionTaskItem; public interface InspectionTaskItemMapper extends BaseMapper<InspectionTaskItem> { } src/main/java/com/ruoyi/inspectiontask/mapper/TimingTaskItemMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,7 @@ package com.ruoyi.inspectiontask.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.inspectiontask.pojo.TimingTaskItem; public interface TimingTaskItemMapper extends BaseMapper<TimingTaskItem> { } src/main/java/com/ruoyi/inspectiontask/pojo/InspectionItem.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,48 @@ package com.ruoyi.inspectiontask.pojo; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.time.LocalDateTime; @Data @TableName("inspection_item") public class InspectionItem { @TableId(type = IdType.AUTO) private Long id; private String itemProject; private String itemContent; private Long deviceLedgerId; private String frequencyType; private Integer sortNum; private Integer isActive; private String remarks; private Integer deleted; @TableField(fill = FieldFill.INSERT) private Integer createUser; @TableField(fill = FieldFill.INSERT_UPDATE) private Integer updateUser; @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; @TableField(fill = FieldFill.INSERT) private Long tenantId; @TableField(fill = FieldFill.INSERT) private Long deptId; @TableField(exist = false) private String itemKeyword; } src/main/java/com/ruoyi/inspectiontask/pojo/InspectionTask.java
@@ -8,6 +8,7 @@ import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; import java.util.List; /** * @author :yys @@ -30,13 +31,12 @@ @Excel(name = "å·¡æ£ä»»å¡åç§°") private String taskName; @Schema(description = "å·¡æ£é¡¹ç®") @Excel(name = "å·¡æ£é¡¹ç®") private String inspectionProject; @Schema(description = "设å¤id") private Integer taskId; @TableField(exist = false) private List<InspectionTaskItem> inspectionItems; @Schema(description = "å·¡æ£äººID") private String inspectorId; src/main/java/com/ruoyi/inspectiontask/pojo/InspectionTaskItem.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,48 @@ package com.ruoyi.inspectiontask.pojo; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.time.LocalDateTime; @Data @TableName("inspection_task_item") public class InspectionTaskItem { @TableId(type = IdType.AUTO) private Long id; private Long inspectionTaskId; private Long inspectionItemId; private String itemProject; private String itemContent; private Integer itemStatus; private String remarks; private Integer sortNum; private Long completedBy; private LocalDateTime completedTime; @TableField(fill = FieldFill.INSERT) private Integer createUser; @TableField(fill = FieldFill.INSERT_UPDATE) private Integer updateUser; @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; @TableField(fill = FieldFill.INSERT) private Long tenantId; @TableField(fill = FieldFill.INSERT) private Long deptId; } src/main/java/com/ruoyi/inspectiontask/pojo/TimingTask.java
@@ -11,6 +11,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; /** * @author :yys @@ -33,12 +34,17 @@ @Excel(name = "å·¡æ£ä»»å¡åç§°") private String taskName; @Schema(description = "å·¡æ£é¡¹ç®") @Excel(name = "å·¡æ£é¡¹ç®") private String inspectionProject; @Schema(description = "设å¤id") private Integer taskId; @TableField(exist = false) private List<Long> inspectionItemIds; @TableField(exist = false) private List<TimingTaskItem> inspectionItems; @TableField(exist = false) private List<TimingTaskItem> customItems; @Schema(description = "å·¡æ£äºº") @Excel(name = "æ§è¡å·¡æ£äºº") @@ -93,17 +99,17 @@ private String dateStr; @Schema(description = "å建该记å½çç¨æ·") @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT) @TableField(fill = FieldFill.INSERT) private Integer createUser; @Schema(description = "è®°å½å建æ¶é´") @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT) @TableField(fill = FieldFill.INSERT) // @JsonFormat(pattern = "yyyy-MM-dd") // @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDateTime createTime; @Schema(description = "æåä¿®æ¹è¯¥è®°å½çç¨æ·") @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT_UPDATE) @TableField(fill = FieldFill.INSERT_UPDATE) private Integer updateUser; @Schema(description = "è®°å½æåæ´æ°æ¶é´") @@ -111,7 +117,7 @@ private LocalDateTime updateTime; @Schema(description = "ç§æ·ID") @TableField(fill = com.baomidou.mybatisplus.annotation.FieldFill.INSERT) @TableField(fill = FieldFill.INSERT) private Long tenantId; src/main/java/com/ruoyi/inspectiontask/pojo/TimingTaskItem.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,42 @@ package com.ruoyi.inspectiontask.pojo; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.time.LocalDateTime; @Data @TableName("timing_task_item") public class TimingTaskItem { @TableId(type = IdType.AUTO) private Long id; private Long timingTaskId; private Long inspectionItemId; private String itemProject; private String itemContent; private Integer sortNum; @TableField(fill = FieldFill.INSERT) private Integer createUser; @TableField(fill = FieldFill.INSERT_UPDATE) private Integer updateUser; @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; @TableField(fill = FieldFill.INSERT) private Long tenantId; @TableField(fill = FieldFill.INSERT) private Long deptId; } src/main/java/com/ruoyi/inspectiontask/service/InspectionItemService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,19 @@ package com.ruoyi.inspectiontask.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.inspectiontask.pojo.InspectionItem; import java.util.List; public interface InspectionItemService { List<InspectionItem> list(InspectionItem query, boolean includeCommon); Page<InspectionItem> page(long pageNum, long pageSize, boolean includeCommon, InspectionItem query); void create(InspectionItem item); void update(InspectionItem item); void delete(Long id); } src/main/java/com/ruoyi/inspectiontask/service/impl/InspectionItemServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,177 @@ package com.ruoyi.inspectiontask.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.inspectiontask.mapper.InspectionItemMapper; import com.ruoyi.inspectiontask.pojo.InspectionItem; import com.ruoyi.inspectiontask.service.InspectionItemService; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service @RequiredArgsConstructor public class InspectionItemServiceImpl implements InspectionItemService { private static final List<String> VALID_FREQUENCIES = List.of( "DAILY", "WEEKLY", "MONTHLY", "QUARTERLY", "ALL" ); private final InspectionItemMapper inspectionItemMapper; @Override public List<InspectionItem> list(InspectionItem query, boolean includeCommon) { return inspectionItemMapper.selectList(buildQuery(query, includeCommon) .orderByAsc(InspectionItem::getSortNum) .orderByAsc(InspectionItem::getId)); } @Override public Page<InspectionItem> page(long pageNum, long pageSize, boolean includeCommon, InspectionItem query) { long safePageNum = Math.max(pageNum, 1); long safePageSize = Math.min(Math.max(pageSize, 1), 100); return inspectionItemMapper.selectPage(new Page<>(safePageNum, safePageSize), buildQuery(query, includeCommon) .orderByAsc(InspectionItem::getSortNum) .orderByAsc(InspectionItem::getId)); } @Override @Transactional(rollbackFor = Exception.class) public void create(InspectionItem item) { validate(item); normalize(item); item.setDeleted(0); if (existsDuplicate(item, null)) { throw new ServiceException("该设å¤åé¢çä¸å·²åå¨ååå·¡æ£å 容"); } if (inspectionItemMapper.insert(item) <= 0) { throw new ServiceException("æ°å¢å·¡æ£å 容失败"); } } @Override @Transactional(rollbackFor = Exception.class) public void update(InspectionItem item) { if (item == null || item.getId() == null) { throw new ServiceException("å·¡æ£å 容ç¼å·ä¸è½ä¸ºç©º"); } validate(item); InspectionItem existing = inspectionItemMapper.selectById(item.getId()); if (existing == null || Integer.valueOf(1).equals(existing.getDeleted())) { throw new ServiceException("å·¡æ£å 容ä¸åå¨"); } normalize(item); if (existsDuplicate(item, item.getId())) { throw new ServiceException("该设å¤åé¢çä¸å·²åå¨ååå·¡æ£å 容"); } existing.setItemProject(item.getItemProject()); existing.setItemContent(item.getItemContent()); existing.setDeviceLedgerId(item.getDeviceLedgerId()); existing.setFrequencyType(item.getFrequencyType()); existing.setSortNum(item.getSortNum()); existing.setIsActive(item.getIsActive()); existing.setRemarks(item.getRemarks()); if (inspectionItemMapper.updateById(existing) <= 0) { throw new ServiceException("ä¿®æ¹å·¡æ£å 容失败"); } } @Override @Transactional(rollbackFor = Exception.class) public void delete(Long id) { if (id == null) { throw new ServiceException("å·¡æ£å 容ç¼å·ä¸è½ä¸ºç©º"); } InspectionItem item = inspectionItemMapper.selectById(id); if (item == null || Integer.valueOf(1).equals(item.getDeleted())) { throw new ServiceException("å·¡æ£å 容ä¸åå¨"); } item.setDeleted(1); item.setIsActive(0); if (inspectionItemMapper.updateById(item) <= 0) { throw new ServiceException("å é¤å·¡æ£å 容失败"); } } private LambdaQueryWrapper<InspectionItem> buildQuery(InspectionItem query, boolean includeCommon) { InspectionItem filter = query == null ? new InspectionItem() : query; LambdaQueryWrapper<InspectionItem> wrapper = new LambdaQueryWrapper<InspectionItem>() .eq(InspectionItem::getDeleted, 0); if (StringUtils.isNotBlank(filter.getItemProject())) { wrapper.like(InspectionItem::getItemProject, filter.getItemProject().trim()); } if (StringUtils.isNotBlank(filter.getItemContent())) { wrapper.like(InspectionItem::getItemContent, filter.getItemContent().trim()); } if (StringUtils.isNotBlank(filter.getItemKeyword())) { String keyword = filter.getItemKeyword().trim(); wrapper.and(condition -> condition .like(InspectionItem::getItemProject, keyword) .or() .like(InspectionItem::getItemContent, keyword)); } if (filter.getIsActive() != null) { wrapper.eq(InspectionItem::getIsActive, filter.getIsActive()); } if (filter.getDeviceLedgerId() != null) { if (includeCommon) { wrapper.and(condition -> condition .eq(InspectionItem::getDeviceLedgerId, filter.getDeviceLedgerId()) .or() .isNull(InspectionItem::getDeviceLedgerId)); } else { wrapper.eq(InspectionItem::getDeviceLedgerId, filter.getDeviceLedgerId()); } } if (StringUtils.isNotBlank(filter.getFrequencyType())) { if (includeCommon) { wrapper.and(condition -> condition .eq(InspectionItem::getFrequencyType, filter.getFrequencyType()) .or() .eq(InspectionItem::getFrequencyType, "ALL")); } else { wrapper.eq(InspectionItem::getFrequencyType, filter.getFrequencyType()); } } return wrapper; } private void validate(InspectionItem item) { if (item == null || StringUtils.isBlank(item.getItemProject()) || StringUtils.isBlank(item.getItemContent()) || StringUtils.isBlank(item.getFrequencyType()) || !VALID_FREQUENCIES.contains(item.getFrequencyType())) { throw new ServiceException("å·¡æ£é¡¹ç®ãå·¡æ£å 容åé¢çä¸è½ä¸ºç©ºææ æ"); } } private void normalize(InspectionItem item) { item.setItemProject(item.getItemProject().trim()); item.setItemContent(item.getItemContent().trim()); item.setSortNum(item.getSortNum() == null ? 0 : item.getSortNum()); item.setIsActive(item.getIsActive() == null ? 1 : item.getIsActive()); } private boolean existsDuplicate(InspectionItem item, Long excludedId) { LambdaQueryWrapper<InspectionItem> wrapper = new LambdaQueryWrapper<InspectionItem>() .eq(InspectionItem::getDeleted, 0) .eq(InspectionItem::getItemProject, item.getItemProject()) .eq(InspectionItem::getItemContent, item.getItemContent()) .eq(InspectionItem::getFrequencyType, item.getFrequencyType()); if (item.getDeviceLedgerId() == null) { wrapper.isNull(InspectionItem::getDeviceLedgerId); } else { wrapper.eq(InspectionItem::getDeviceLedgerId, item.getDeviceLedgerId()); } if (excludedId != null) { wrapper.ne(InspectionItem::getId, excludedId); } return inspectionItemMapper.selectCount(wrapper) > 0; } } src/main/java/com/ruoyi/inspectiontask/service/impl/InspectionTaskServiceImpl.java
@@ -17,8 +17,10 @@ import com.ruoyi.device.pojo.DeviceLedger; import com.ruoyi.device.pojo.DeviceRepair; import com.ruoyi.inspectiontask.dto.InspectionTaskDto; import com.ruoyi.inspectiontask.mapper.InspectionTaskItemMapper; import com.ruoyi.inspectiontask.mapper.InspectionTaskMapper; import com.ruoyi.inspectiontask.pojo.InspectionTask; import com.ruoyi.inspectiontask.pojo.InspectionTaskItem; import com.ruoyi.inspectiontask.service.InspectionTaskService; import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.mapper.SysUserMapper; @@ -27,9 +29,18 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.*; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -40,10 +51,12 @@ @Service @Slf4j @RequiredArgsConstructor public class InspectionTaskServiceImpl extends ServiceImpl<InspectionTaskMapper, InspectionTask> implements InspectionTaskService { public class InspectionTaskServiceImpl extends ServiceImpl<InspectionTaskMapper, InspectionTask> implements InspectionTaskService { private final InspectionTaskMapper inspectionTaskMapper; private final InspectionTaskItemMapper inspectionTaskItemMapper; private final SysUserMapper sysUserMapper; @@ -64,17 +77,22 @@ if (StringUtils.isNotBlank(inspectionTaskDto.getTaskName())) { queryWrapper.like(InspectionTask::getTaskName, inspectionTaskDto.getTaskName()); } if (StringUtils.isNotBlank(inspectionTaskDto.getInspectionProject())) { queryWrapper.like(InspectionTask::getInspectionProject, inspectionTaskDto.getInspectionProject()); } IPage<InspectionTask> entityPage = inspectionTaskMapper.selectPage(page, queryWrapper); // æ æ°æ®æåè¿å if (CollectionUtils.isEmpty(entityPage.getRecords())) { return new Page<>(entityPage.getCurrent(), entityPage.getSize(), entityPage.getTotal()); } List<Long> inspectionTaskIds = entityPage.getRecords().stream().map(InspectionTask::getId).toList(); Map<Long, List<InspectionTaskItem>> recordItemsByTask = inspectionTaskItemMapper.selectList( new LambdaQueryWrapper<InspectionTaskItem>() .in(InspectionTaskItem::getInspectionTaskId, inspectionTaskIds) .orderByAsc(InspectionTaskItem::getSortNum)) .stream().collect(Collectors.groupingBy(InspectionTaskItem::getInspectionTaskId)); //ç»è®°äººids List<Long> registrantIds = entityPage.getRecords().stream().map(InspectionTask::getRegistrantId).collect(Collectors.toList()); List<Long> registrantIds = entityPage.getRecords().stream() .map(InspectionTask::getRegistrantId) .collect(Collectors.toList()); // æ¹éæ¥è¯¢ç»è®°äºº Map<Long, SysUser> sysUserMap; if (!registrantIds.isEmpty()) { @@ -101,8 +119,7 @@ // 使ç¨SQLæ¹éæ¥è¯¢ç¨æ·ä¿¡æ¯ Map<Long, String> userIdToNameMap = allUserIds.isEmpty() ? Collections.emptyMap() : sysUserMapper.selectUsersByIds(new ArrayList<>(allUserIds)) .stream() : sysUserMapper.selectUsersByIds(new ArrayList<>(allUserIds)).stream() .collect(Collectors.toMap( SysUser::getUserId, SysUser::getNickName, @@ -110,6 +127,7 @@ List<InspectionTaskDto> dtoList = entityPage.getRecords().stream().map(inspectionTask -> { InspectionTaskDto dto = new InspectionTaskDto(); BeanUtils.copyProperties(inspectionTask, dto); // å¤å¶ä¸»å¯¹è±¡å±æ§ dto.setInspectionItems(recordItemsByTask.getOrDefault(inspectionTask.getId(), Collections.emptyList())); // 设置ç»è®°äºº SysUser sysUser = sysUserMap.get(inspectionTask.getRegistrantId()); @@ -134,10 +152,12 @@ dto.setDateStr(inspectionTask.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); // åå§åä¸ä¸ªéä»¶å表 dto.setCommonFileListVO(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.FILE, RecordTypeEnum.INSPECTION_TASK, inspectionTask.getId())); dto.setCommonFileListAfterVO(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.AFTER_FILE, RecordTypeEnum.INSPECTION_TASK, inspectionTask.getId())); dto.setCommonFileListBeforeVO(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.BEFORE_FILE, RecordTypeEnum.INSPECTION_TASK, inspectionTask.getId())); dto.setCommonFileListVO(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId( ApplicationTypeEnum.FILE, RecordTypeEnum.INSPECTION_TASK, inspectionTask.getId())); dto.setCommonFileListAfterVO(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId( ApplicationTypeEnum.AFTER_FILE, RecordTypeEnum.INSPECTION_TASK, inspectionTask.getId())); dto.setCommonFileListBeforeVO(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId( ApplicationTypeEnum.BEFORE_FILE, RecordTypeEnum.INSPECTION_TASK, inspectionTask.getId())); return dto; }).collect(Collectors.toList()); @@ -175,6 +195,9 @@ if (i <= 0) { return i; } if (inspectionTaskDto.getInspectionItems() != null) { updateInspectionItemStatuses(inspectionTask.getId(), inspectionTaskDto); } Long linkedRepairId = syncRepairOrderIfAbnormal(inspectionTask, oldInspectionTask); if (linkedRepairId != null && !Objects.equals(linkedRepairId, inspectionTask.getDeviceRepairId())) { InspectionTask relationUpdate = new InspectionTask(); @@ -187,6 +210,33 @@ saveInspectionAttachments(inspectionTask.getId(), inspectionTaskDto); return i; } private void updateInspectionItemStatuses(Long inspectionTaskId, InspectionTaskDto request) { List<InspectionTaskItem> requestedItems = request.getInspectionItems(); List<InspectionTaskItem> currentItems = inspectionTaskItemMapper.selectList( new LambdaQueryWrapper<InspectionTaskItem>() .eq(InspectionTaskItem::getInspectionTaskId, inspectionTaskId)); Map<Long, InspectionTaskItem> currentById = currentItems.stream() .collect(Collectors.toMap(InspectionTaskItem::getId, Function.identity())); Set<Long> seenIds = new HashSet<>(); for (InspectionTaskItem requested : requestedItems) { if (requested == null || requested.getId() == null || requested.getItemStatus() == null || (requested.getItemStatus() != 0 && requested.getItemStatus() != 1) || !seenIds.add(requested.getId())) { throw new IllegalArgumentException("å·¡æ£å å®¹ç¶ææ æ"); } InspectionTaskItem current = currentById.get(requested.getId()); if (current == null) { throw new IllegalArgumentException("å·¡æ£å å®¹æ¸ åå·²ååï¼è¯·å·æ°åéè¯"); } current.setItemStatus(requested.getItemStatus()); current.setRemarks(requested.getRemarks()); current.setCompletedBy(requested.getItemStatus() == 1 ? SecurityUtils.getUserId() : null); current.setCompletedTime(requested.getItemStatus() == 1 ? LocalDateTime.now() : null); inspectionTaskItemMapper.updateById(current); } } private void validateInspectionInput(InspectionTaskDto inspectionTaskDto, InspectionTask oldInspectionTask) { @@ -222,19 +272,24 @@ private boolean hasAnyInspectionPhotoAfterSave(InspectionTaskDto inspectionTaskDto, InspectionTask oldInspectionTask) { Long recordId = oldInspectionTask == null ? null : oldInspectionTask.getId(); return hasApplicationPhotoAfterSave(inspectionTaskDto.getCommonFileListDTO(), ApplicationTypeEnum.FILE, recordId) || hasApplicationPhotoAfterSave(inspectionTaskDto.getCommonFileListAfterDTO(), ApplicationTypeEnum.AFTER_FILE, recordId) || hasApplicationPhotoAfterSave(inspectionTaskDto.getCommonFileListBeforeDTO(), ApplicationTypeEnum.BEFORE_FILE, recordId); return hasApplicationPhotoAfterSave( inspectionTaskDto.getCommonFileListDTO(), ApplicationTypeEnum.FILE, recordId) || hasApplicationPhotoAfterSave( inspectionTaskDto.getCommonFileListAfterDTO(), ApplicationTypeEnum.AFTER_FILE, recordId) || hasApplicationPhotoAfterSave( inspectionTaskDto.getCommonFileListBeforeDTO(), ApplicationTypeEnum.BEFORE_FILE, recordId); } private boolean hasApplicationPhotoAfterSave(List<StorageBlobDTO> requestPhotos, ApplicationTypeEnum applicationType, Long recordId) { private boolean hasApplicationPhotoAfterSave( List<StorageBlobDTO> requestPhotos, ApplicationTypeEnum applicationType, Long recordId) { if (requestPhotos != null) { return !requestPhotos.isEmpty(); } if (recordId == null) { return false; } return CollectionUtils.isNotEmpty(fileUtil.getStorageAttachmentsByApplicationAndRecordTypeAndRecordId(applicationType, RecordTypeEnum.INSPECTION_TASK, recordId)); return CollectionUtils.isNotEmpty(fileUtil.getStorageAttachmentsByApplicationAndRecordTypeAndRecordId( applicationType, RecordTypeEnum.INSPECTION_TASK, recordId)); } private void fillAcceptanceInfo(InspectionTask inspectionTask, InspectionTask oldInspectionTask) { @@ -383,6 +438,8 @@ if (ids == null || ids.length == 0) { return 0; } inspectionTaskItemMapper.delete(new LambdaQueryWrapper<InspectionTaskItem>() .in(InspectionTaskItem::getInspectionTaskId, Arrays.asList(ids))); // å 餿件 fileUtil.deleteStorageAttachmentsByApplicationAndRecordTypeAndRecordIds(ApplicationTypeEnum.FILE, RecordTypeEnum.INSPECTION_TASK, Arrays.asList(ids)); fileUtil.deleteStorageAttachmentsByApplicationAndRecordTypeAndRecordIds(ApplicationTypeEnum.AFTER_FILE, RecordTypeEnum.INSPECTION_TASK, Arrays.asList(ids)); src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskJob.java
@@ -1,10 +1,19 @@ package com.ruoyi.inspectiontask.service.impl; import com.ruoyi.inspectiontask.mapper.InspectionTaskMapper; import com.ruoyi.inspectiontask.pojo.InspectionTask; import com.ruoyi.inspectiontask.pojo.TimingTask; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.utils.StringUtils; import org.quartz.*; import com.ruoyi.inspectiontask.mapper.InspectionTaskItemMapper; import com.ruoyi.inspectiontask.mapper.InspectionTaskMapper; import com.ruoyi.inspectiontask.mapper.TimingTaskItemMapper; import com.ruoyi.inspectiontask.pojo.InspectionTask; import com.ruoyi.inspectiontask.pojo.InspectionTaskItem; import com.ruoyi.inspectiontask.pojo.TimingTask; import com.ruoyi.inspectiontask.pojo.TimingTaskItem; import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; @@ -22,10 +31,14 @@ @Component @DisallowConcurrentExecution // ç¦æ¢å¹¶åæ§è¡åä¸ä¸ªJob public class TimingTaskJob implements Job, Serializable { private static final long serialVersionUID = 1L; // å¿ é¡»å®ä¹åºååID private static final long serialVersionUID = 1L; @Autowired private InspectionTaskMapper inspectionTaskMapper; @Autowired private TimingTaskItemMapper timingTaskItemMapper; @Autowired private InspectionTaskItemMapper inspectionTaskItemMapper; @Autowired private JdbcTemplate jdbcTemplate; @@ -38,7 +51,7 @@ try { // 3. å°è¯æ¥è¯¢ä½ çä¸å¡æ°æ® // éè¿JDBCæ¨¡æ¿æ¥è¯¢å®æ¶ä»»å¡ä¿¡æ¯ï¼ä½¿ç¨åæ°åæ¥è¯¢é²æ¢SQLæ³¨å ¥ String yourSql = "SELECT * FROM timing_task where id = ?"; String yourSql = "SELECT * FROM timing_task WHERE id = ?"; List<TimingTask> tasks = jdbcTemplate.query( yourSql, new BeanPropertyRowMapper<>(TimingTask.class), @@ -59,6 +72,7 @@ // 2. å建并ä¿åå·¡æ£ä»»å¡è®°å½ - è¿å°±æ¯æ¨æä¾ç代ç åºè¯¥æ¾çä½ç½® InspectionTask inspectionTask = createInspectionTask(timingTask); inspectionTaskMapper.insert(inspectionTask); copyTaskItemsToRecord(timingTask.getId(), inspectionTask.getId()); // 3. æ´æ°å®æ¶ä»»å¡çæ§è¡æ¶é´ if (!tasks.isEmpty()) { @@ -75,9 +89,9 @@ ); // æ§è¡æ´æ°æä½ String updateSql = "UPDATE timing_task " + "SET last_execution_time = ?, next_execution_time = ? " + "WHERE id = ?"; String updateSql = "UPDATE timing_task " + "SET last_execution_time = ?, next_execution_time = ? " + "WHERE id = ?"; jdbcTemplate.update( updateSql, @@ -103,7 +117,6 @@ // å¤å¶åºæ¬å±æ§ inspectionTask.setTaskName(timingTask.getTaskName()); inspectionTask.setInspectionProject(timingTask.getInspectionProject()); inspectionTask.setTaskId(timingTask.getTaskId()); inspectionTask.setInspectorId(timingTask.getInspectorIds()); inspectionTask.setInspectionLocation(timingTask.getInspectionLocation()); @@ -118,6 +131,25 @@ inspectionTask.setTenantId(timingTask.getTenantId()); return inspectionTask; } private void copyTaskItemsToRecord(Long timingTaskId, Long inspectionTaskId) { List<TimingTaskItem> taskItems = timingTaskItemMapper.selectList( new LambdaQueryWrapper<TimingTaskItem>() .eq(TimingTaskItem::getTimingTaskId, timingTaskId) .orderByAsc(TimingTaskItem::getSortNum)); for (TimingTaskItem source : taskItems) { InspectionTaskItem recordItem = new InspectionTaskItem(); recordItem.setInspectionTaskId(inspectionTaskId); recordItem.setInspectionItemId(source.getInspectionItemId()); recordItem.setItemProject(source.getItemProject()); recordItem.setItemContent(source.getItemContent()); recordItem.setItemStatus(0); recordItem.setSortNum(source.getSortNum()); recordItem.setTenantId(source.getTenantId()); recordItem.setDeptId(source.getDeptId()); inspectionTaskItemMapper.insert(recordItem); } } @@ -243,13 +275,27 @@ 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; 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); } } src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskServiceImpl.java
@@ -4,11 +4,16 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.inspectiontask.dto.TimingTaskDto; import com.ruoyi.inspectiontask.mapper.InspectionItemMapper; import com.ruoyi.inspectiontask.mapper.TimingTaskItemMapper; import com.ruoyi.inspectiontask.mapper.TimingTaskMapper; import com.ruoyi.inspectiontask.pojo.InspectionItem; import com.ruoyi.inspectiontask.pojo.TimingTask; import com.ruoyi.inspectiontask.pojo.TimingTaskItem; import com.ruoyi.inspectiontask.service.TimingTaskService; import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.mapper.SysUserMapper; @@ -18,9 +23,24 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.*; import java.time.DayOfWeek; import java.time.DateTimeException; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Year; import java.time.YearMonth; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; /** @@ -35,9 +55,11 @@ private final TimingTaskMapper timingTaskMapper; private final TimingTaskScheduler timingTaskScheduler; private final SysUserMapper sysUserMapper; private final InspectionItemMapper inspectionItemMapper; private final TimingTaskItemMapper timingTaskItemMapper; private static final int ENABLED = 1; private static final int DISABLED = 0; @Override public IPage<TimingTaskDto> selectTimingTaskList(Page<TimingTask> page, TimingTask timingTask) { @@ -47,9 +69,7 @@ if (StringUtils.isNotBlank(timingTask.getTaskName())) { queryWrapper.like(TimingTask::getTaskName, timingTask.getTaskName()); } if (StringUtils.isNotBlank(timingTask.getInspectionProject())) { queryWrapper.like(TimingTask::getInspectionProject, timingTask.getInspectionProject()); } queryWrapper.eq(TimingTask::getDeleted, 0); if (timingTask.getIsEnabled() != null) { queryWrapper.eq(TimingTask::getIsEnabled, timingTask.getIsEnabled()); } @@ -113,6 +133,16 @@ dto.setInspector(inspectorNickNames); } List<TimingTaskItem> taskItems = timingTaskItemMapper.selectList( new LambdaQueryWrapper<TimingTaskItem>() .eq(TimingTaskItem::getTimingTaskId, task.getId()) .orderByAsc(TimingTaskItem::getSortNum)); dto.setInspectionItems(taskItems); dto.setInspectionItemIds(taskItems.stream() .map(TimingTaskItem::getInspectionItemId) .filter(Objects::nonNull) .collect(Collectors.toList())); return dto; }).collect(Collectors.toList()); @@ -131,6 +161,11 @@ if (oldTimingTask == null) { throw new IllegalArgumentException("宿¶ä»»å¡ä¸åå¨"); } } List<InspectionItem> selectedItems = resolveSelectedItems(timingTaskDto, oldTimingTask); List<TimingTaskItem> customItems = normalizeCustomItems(timingTaskDto.getCustomItems()); if (selectedItems.isEmpty() && customItems.isEmpty()) { throw new ServiceException("è¯·éæ©ææ·»å è³å°ä¸ä¸ªå·¡æ£å 容"); } TimingTask timingTask = new TimingTask(); BeanUtils.copyProperties(timingTaskDto, timingTask); @@ -156,17 +191,23 @@ LocalDateTime firstExecutionTime = calculateFirstExecutionTime(timingTask); timingTask.setNextExecutionTime(firstExecutionTime); int result = timingTaskMapper.insert(timingTask); if (result > 0) { saveTaskItems(timingTask, selectedItems, customItems); } if (result > 0 && isEnabled(timingTask.getIsEnabled(), timingTask.isActive())) { // æ°å¢æååæ·»å å°è°åº¦å¨ timingTaskScheduler.scheduleTimingTask(timingTask); } return result; } else { int result = timingTaskMapper.updateById(timingTask); if (result > 0) { boolean oldEnabled = isEnabled(oldTimingTask == null ? null : oldTimingTask.getIsEnabled(), oldTimingTask != null && oldTimingTask.isActive()); timingTaskItemMapper.delete(new LambdaQueryWrapper<TimingTaskItem>() .eq(TimingTaskItem::getTimingTaskId, timingTask.getId())); saveTaskItems(timingTask, selectedItems, customItems); boolean oldEnabled = isEnabled( oldTimingTask == null ? null : oldTimingTask.getIsEnabled(), oldTimingTask != null && oldTimingTask.isActive()); boolean newEnabled = isEnabled(timingTask.getIsEnabled(), timingTask.isActive()); if (!newEnabled) { timingTaskScheduler.unscheduleTimingTask(timingTask.getId()); @@ -182,8 +223,94 @@ } } private List<InspectionItem> resolveSelectedItems(TimingTask request, TimingTask oldTask) { List<Long> itemIds = request.getInspectionItemIds(); if (itemIds == null && oldTask != null) { itemIds = timingTaskItemMapper.selectList(new LambdaQueryWrapper<TimingTaskItem>() .eq(TimingTaskItem::getTimingTaskId, oldTask.getId())) .stream().map(TimingTaskItem::getInspectionItemId).filter(Objects::nonNull).toList(); } if (request.getTaskId() == null || StringUtils.isBlank(request.getFrequencyType())) { throw new ServiceException("设å¤åå·¡æ£é¢çä¸è½ä¸ºç©º"); } if (itemIds == null || itemIds.isEmpty()) { return new ArrayList<>(); } if (new HashSet<>(itemIds).size() != itemIds.size()) { throw new ServiceException("å·¡æ£å 容ä¸è½éå¤éæ©"); } List<InspectionItem> items = inspectionItemMapper.selectBatchIds(itemIds); if (items.size() != itemIds.size()) { throw new ServiceException("æéå·¡æ£å 容ä¸åå¨"); } Long deviceId = request.getTaskId().longValue(); String frequency = request.getFrequencyType(); Set<Long> oldItemIds = oldTask == null ? Collections.emptySet() : new HashSet<>(timingTaskItemMapper.selectList(new LambdaQueryWrapper<TimingTaskItem>() .eq(TimingTaskItem::getTimingTaskId, oldTask.getId())) .stream().map(TimingTaskItem::getInspectionItemId).filter(Objects::nonNull).toList()); boolean invalid = items.stream().anyMatch(item -> (item.getDeviceLedgerId() != null && !deviceId.equals(item.getDeviceLedgerId())) || !(frequency.equals(item.getFrequencyType()) || "ALL".equals(item.getFrequencyType())) || (item.getDeleted() != null && item.getDeleted() == 1 || item.getIsActive() == null || item.getIsActive() != 1) && !oldItemIds.contains(item.getId())); if (invalid) { throw new ServiceException("æéå·¡æ£å 容ä¸è®¾å¤æé¢çä¸å¹é "); } Map<Long, InspectionItem> itemMap = items.stream() .collect(Collectors.toMap(InspectionItem::getId, Function.identity())); return itemIds.stream().map(itemMap::get).toList(); } private List<TimingTaskItem> normalizeCustomItems(List<TimingTaskItem> customItems) { if (customItems == null) { return new ArrayList<>(); } return customItems.stream() .filter(Objects::nonNull) .filter(item -> StringUtils.isNotBlank(item.getItemProject()) && StringUtils.isNotBlank(item.getItemContent())) .peek(item -> { item.setItemProject(item.getItemProject().trim()); item.setItemContent(item.getItemContent().trim()); }) .toList(); } private void saveTaskItems( TimingTask task, List<InspectionItem> selectedItems, List<TimingTaskItem> customItems) { for (int index = 0; index < selectedItems.size(); index++) { InspectionItem source = selectedItems.get(index); TimingTaskItem taskItem = new TimingTaskItem(); taskItem.setTimingTaskId(task.getId()); taskItem.setInspectionItemId(source.getId()); taskItem.setItemProject(source.getItemProject()); taskItem.setItemContent(source.getItemContent()); taskItem.setSortNum(index); taskItem.setTenantId(task.getTenantId()); taskItem.setDeptId(task.getDeptId()); timingTaskItemMapper.insert(taskItem); } for (int index = 0; index < customItems.size(); index++) { TimingTaskItem source = customItems.get(index); TimingTaskItem taskItem = new TimingTaskItem(); taskItem.setTimingTaskId(task.getId()); taskItem.setItemProject(source.getItemProject()); taskItem.setItemContent(source.getItemContent()); taskItem.setSortNum(selectedItems.size() + index); taskItem.setTenantId(task.getTenantId()); taskItem.setDeptId(task.getDeptId()); timingTaskItemMapper.insert(taskItem); } } public LocalDateTime calculateFirstExecutionTime(TimingTask task) { // æ ¹æ®é¢çç±»åå详æ 计ç®é¦æ¬¡æ§è¡æ¶é´ if (task == null || StringUtils.isBlank(task.getFrequencyDetail())) { throw new IllegalArgumentException("请填å任塿§è¡æ¥æåæ¶é´"); } String frequencyType = task.getFrequencyType(); if ("DAILY".equals(frequencyType)) { // å¦ææ¯æ¯å¤©æ§è¡ï¼è®¡ç®ä»å¤©ææå¤©çå ·ä½æ¶é´ @@ -214,6 +341,7 @@ // æ å°ææç®åä¸DayOfWeek private static final Map<String, DayOfWeek> WEEK_DAY_MAP = new HashMap<>(); static { WEEK_DAY_MAP.put("MON", DayOfWeek.MONDAY); WEEK_DAY_MAP.put("TUE", DayOfWeek.TUESDAY); @@ -316,7 +444,31 @@ } private LocalDateTime calculateCustomFirstExecution(String frequencyDetail) { return null; String[] parts = frequencyDetail.split(","); if (parts.length != 3) { throw new IllegalArgumentException("å£åº¦é¢çæ ¼å¼é误ï¼åºä¸º'å£åº¦å æä»½,æ¥æ,æ¶é´'"); } int monthInQuarter = Integer.parseInt(parts[0]); int dayOfMonth = Integer.parseInt(parts[1]); LocalTime time = LocalTime.parse(parts[2], DateTimeFormatter.ofPattern("HH:mm")); if (monthInQuarter < 1 || monthInQuarter > 3 || dayOfMonth < 1 || dayOfMonth > 31) { throw new IllegalArgumentException("å£åº¦é¢çæ¥ææ æ"); } LocalDateTime now = LocalDateTime.now(); int currentMonthInQuarter = (now.getMonthValue() - 1) % 3 + 1; int monthsUntilTarget = monthInQuarter - currentMonthInQuarter; if (monthsUntilTarget < 0) { monthsUntilTarget += 3; } YearMonth targetMonth = YearMonth.from(now).plusMonths(monthsUntilTarget); int targetDay = Math.min(dayOfMonth, targetMonth.lengthOfMonth()); LocalDateTime target = targetMonth.atDay(targetDay).atTime(time); if (!target.isAfter(now)) { targetMonth = targetMonth.plusMonths(3); target = targetMonth.atDay(Math.min(dayOfMonth, targetMonth.lengthOfMonth())).atTime(time); } return target; } @Override @@ -464,13 +616,27 @@ 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; 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); } } @@ -498,12 +664,15 @@ return activeFallback; } @Override public int delByIds(Long[] ids) { if (ids == null || ids.length == 0) { return 0; } int i = timingTaskMapper.deleteBatchIds(Arrays.asList(ids)); if(i > 0){ timingTaskItemMapper.delete(new LambdaQueryWrapper<TimingTaskItem>() .in(TimingTaskItem::getTimingTaskId, Arrays.asList(ids))); for (Long id : ids) { timingTaskScheduler.unscheduleTimingTask(id); }