From 49e1bc66ebaf696ebd3fc3ed33d65c8795fd3cde Mon Sep 17 00:00:00 2001 From: liding <756868258@qq.com> Date: 星期二, 01 七月 2025 18:05:12 +0800 Subject: [PATCH] 1.巡检定时任务 2.设备管理 3.文档查询 --- main-business/src/main/java/com/ruoyi/business/service/impl/EquipmentManagementServiceImpl.java | 57 ++ main-business/src/main/java/com/ruoyi/business/entity/InspectionTask.java | 11 main-business/src/main/java/com/ruoyi/business/mapper/EquipmentManagementMapper.java | 18 main-business/src/main/java/com/ruoyi/business/service/impl/ArchiveServiceImpl.java | 28 main-business/src/main/java/com/ruoyi/business/controller/InputInventoryRecordController.java | 20 ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml | 32 + main-business/pom.xml | 4 main-business/src/main/resources/mapper/EquipmentManagementMapper.xml | 35 + main-business/src/main/java/com/ruoyi/business/service/InspectionTaskService.java | 2 main-business/src/main/java/com/ruoyi/business/service/impl/InspectionTaskServiceImpl.java | 72 ++ main-business/src/main/java/com/ruoyi/business/dto/TimingTaskDto.java | 10 main-business/src/main/java/com/ruoyi/business/dto/ArchiveDto.java | 2 main-business/src/main/java/com/ruoyi/business/mapper/TimingTaskMapper.java | 24 main-business/src/main/resources/mapper/TimingTaskMapper.xml | 33 + main-business/src/main/resources/mapper/TreeMapper.xml | 9 main-business/src/main/java/com/ruoyi/business/controller/TimingTaskController.java | 56 ++ main-business/src/main/java/com/ruoyi/business/service/impl/TimingTaskScheduler.java | 238 ++++++++ main-business/src/main/java/com/ruoyi/business/service/TimingTaskService.java | 27 main-business/src/main/resources/db/migration/postgresql/V20250630153900__create_table_timing_task.sql | 63 ++ ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java | 13 main-business/src/main/java/com/ruoyi/business/service/impl/PurchaseRegistrationServiceImpl.java | 2 main-business/src/main/resources/db/migration/postgresql/V20250614134700__create_table_inspection_task.sql | 37 main-business/src/main/java/com/ruoyi/business/service/EquipmentManagementService.java | 24 main-business/src/main/java/com/ruoyi/business/controller/InspectionTaskController.java | 3 main-business/src/main/java/com/ruoyi/business/entity/TimingTask.java | 96 +++ main-business/src/main/java/com/ruoyi/business/service/impl/ProductionMasterServiceImpl.java | 29 main-business/src/main/java/com/ruoyi/business/mapper/TreeMapper.java | 3 main-business/src/main/java/com/ruoyi/business/service/impl/TimingTaskServiceImpl.java | 405 ++++++++++++++ main-business/src/main/java/com/ruoyi/business/service/ArchiveService.java | 2 main-business/src/main/java/com/ruoyi/business/controller/ArchiveController.java | 3 main-business/src/main/java/com/ruoyi/business/controller/EquipmentManagementController.java | 56 ++ main-business/src/main/resources/db/migration/postgresql/V20250701142700__create_table_equipment_management.sql | 59 ++ main-business/src/main/java/com/ruoyi/business/entity/EquipmentManagement.java | 79 ++ main-business/src/main/java/com/ruoyi/business/task/TimingTaskJob.java | 66 ++ main-business/src/main/java/com/ruoyi/business/dto/EquipmentManagementDto.java | 8 35 files changed, 1,585 insertions(+), 41 deletions(-) diff --git a/main-business/pom.xml b/main-business/pom.xml index c1f56f7..18ff099 100644 --- a/main-business/pom.xml +++ b/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> diff --git a/main-business/src/main/java/com/ruoyi/business/controller/ArchiveController.java b/main-business/src/main/java/com/ruoyi/business/controller/ArchiveController.java index 4e4ca1a..3f934be 100644 --- a/main-business/src/main/java/com/ruoyi/business/controller/ArchiveController.java +++ b/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 @@ * 鏌ヨ妗f淇℃伅琛� */ @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); } diff --git a/main-business/src/main/java/com/ruoyi/business/controller/EquipmentManagementController.java b/main-business/src/main/java/com/ruoyi/business/controller/EquipmentManagementController.java new file mode 100644 index 0000000..1a30f74 --- /dev/null +++ b/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)); + } + + +} diff --git a/main-business/src/main/java/com/ruoyi/business/controller/InputInventoryRecordController.java b/main-business/src/main/java/com/ruoyi/business/controller/InputInventoryRecordController.java index ec8e4f1..14b391e 100644 --- a/main-business/src/main/java/com/ruoyi/business/controller/InputInventoryRecordController.java +++ b/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 { - } +} diff --git a/main-business/src/main/java/com/ruoyi/business/controller/InspectionTaskController.java b/main-business/src/main/java/com/ruoyi/business/controller/InspectionTaskController.java index d085f74..9d092fc 100644 --- a/main-business/src/main/java/com/ruoyi/business/controller/InspectionTaskController.java +++ b/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); } diff --git a/main-business/src/main/java/com/ruoyi/business/controller/TimingTaskController.java b/main-business/src/main/java/com/ruoyi/business/controller/TimingTaskController.java new file mode 100644 index 0000000..ee3e64c --- /dev/null +++ b/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)); + } + +} diff --git a/main-business/src/main/java/com/ruoyi/business/dto/ArchiveDto.java b/main-business/src/main/java/com/ruoyi/business/dto/ArchiveDto.java index dc92a44..52a889a 100644 --- a/main-business/src/main/java/com/ruoyi/business/dto/ArchiveDto.java +++ b/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; } diff --git a/main-business/src/main/java/com/ruoyi/business/dto/EquipmentManagementDto.java b/main-business/src/main/java/com/ruoyi/business/dto/EquipmentManagementDto.java new file mode 100644 index 0000000..858a31a --- /dev/null +++ b/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 { +} diff --git a/main-business/src/main/java/com/ruoyi/business/dto/TimingTaskDto.java b/main-business/src/main/java/com/ruoyi/business/dto/TimingTaskDto.java new file mode 100644 index 0000000..84b0b81 --- /dev/null +++ b/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; +} diff --git a/main-business/src/main/java/com/ruoyi/business/entity/EquipmentManagement.java b/main-business/src/main/java/com/ruoyi/business/entity/EquipmentManagement.java new file mode 100644 index 0000000..4cb21c4 --- /dev/null +++ b/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; + /** + * 浣跨敤浜篒D + */ + @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; +} \ No newline at end of file diff --git a/main-business/src/main/java/com/ruoyi/business/entity/InspectionTask.java b/main-business/src/main/java/com/ruoyi/business/entity/InspectionTask.java index 8c96c92..7354a13 100644 --- a/main-business/src/main/java/com/ruoyi/business/entity/InspectionTask.java +++ b/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; } \ No newline at end of file diff --git a/main-business/src/main/java/com/ruoyi/business/entity/TimingTask.java b/main-business/src/main/java/com/ruoyi/business/entity/TimingTask.java new file mode 100644 index 0000000..3a91e90 --- /dev/null +++ b/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; + /** + * 鐧昏浜篿d + */ + @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绛� +} \ No newline at end of file diff --git a/main-business/src/main/java/com/ruoyi/business/mapper/EquipmentManagementMapper.java b/main-business/src/main/java/com/ruoyi/business/mapper/EquipmentManagementMapper.java new file mode 100644 index 0000000..9f1d438 --- /dev/null +++ b/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> { + +} diff --git a/main-business/src/main/java/com/ruoyi/business/mapper/TimingTaskMapper.java b/main-business/src/main/java/com/ruoyi/business/mapper/TimingTaskMapper.java new file mode 100644 index 0000000..d459f1b --- /dev/null +++ b/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);} diff --git a/main-business/src/main/java/com/ruoyi/business/mapper/TreeMapper.java b/main-business/src/main/java/com/ruoyi/business/mapper/TreeMapper.java index ec9bc03..89ce74e 100644 --- a/main-business/src/main/java/com/ruoyi/business/mapper/TreeMapper.java +++ b/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> * 妗f淇℃伅琛紝璁板綍绯荤粺涓悇绫绘。妗堢殑鍩烘湰淇℃伅 Mapper 鎺ュ彛 @@ -15,4 +17,5 @@ @Mapper public interface TreeMapper extends BaseMapper<Tree> { + List<Long> listRecursiveSubNodeIds(Long treeId); } diff --git a/main-business/src/main/java/com/ruoyi/business/service/ArchiveService.java b/main-business/src/main/java/com/ruoyi/business/service/ArchiveService.java index 8eb6b86..3ba315f 100644 --- a/main-business/src/main/java/com/ruoyi/business/service/ArchiveService.java +++ b/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); diff --git a/main-business/src/main/java/com/ruoyi/business/service/EquipmentManagementService.java b/main-business/src/main/java/com/ruoyi/business/service/EquipmentManagementService.java new file mode 100644 index 0000000..2cbca4b --- /dev/null +++ b/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); +} diff --git a/main-business/src/main/java/com/ruoyi/business/service/InspectionTaskService.java b/main-business/src/main/java/com/ruoyi/business/service/InspectionTaskService.java index f28573b..1fa20e2 100644 --- a/main-business/src/main/java/com/ruoyi/business/service/InspectionTaskService.java +++ b/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); diff --git a/main-business/src/main/java/com/ruoyi/business/service/TimingTaskService.java b/main-business/src/main/java/com/ruoyi/business/service/TimingTaskService.java new file mode 100644 index 0000000..4455d96 --- /dev/null +++ b/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); +} diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/ArchiveServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/ArchiveServiceImpl.java index 09c460c..4866ff5 100644 --- a/main-business/src/main/java/com/ruoyi/business/service/impl/ArchiveServiceImpl.java +++ b/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) { + // 鑾峰彇涓籌D鐨勬墍鏈夐�掑綊瀛愯妭鐐笽D + 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( diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/EquipmentManagementServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/EquipmentManagementServiceImpl.java new file mode 100644 index 0000000..1ac61c9 --- /dev/null +++ b/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)); + } +} diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/InspectionTaskServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/InspectionTaskServiceImpl.java index 414e3f7..2c2400a 100644 --- a/main-business/src/main/java/com/ruoyi/business/service/impl/InspectionTaskServiceImpl.java +++ b/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(); + //鐧昏浜篿ds + 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<>(); + } + //宸℃浜篿ds + List<String> inspectorIds = entityPage.getRecords().stream().map(InspectionTask::getInspectorId).toList(); + //鑾峰彇鎵�鏈変笉閲嶅鐨勭敤鎴稩D + 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)); } } diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/ProductionMasterServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/ProductionMasterServiceImpl.java index c92da97..4157611 100644 --- a/main-business/src/main/java/com/ruoyi/business/service/impl/ProductionMasterServiceImpl.java +++ b/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(); + // 缁勮鏌ヨ鏉′欢锛氱叅绉岻D鍦ㄥ尮閰嶇殑鍒楄〃涓� + // 濡傛灉 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); diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/PurchaseRegistrationServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/PurchaseRegistrationServiceImpl.java index ad63a6c..bbae14c 100644 --- a/main-business/src/main/java/com/ruoyi/business/service/impl/PurchaseRegistrationServiceImpl.java +++ b/main-business/src/main/java/com/ruoyi/business/service/impl/PurchaseRegistrationServiceImpl.java @@ -62,7 +62,7 @@ .map(CoalInfo::getId) .collect(Collectors.toList()); - // 缁勮鏌ヨ鏉′欢锛氱叅绉岻D鍦ㄥ尮閰嶇殑鍒楄〃涓� 鎴� 渚涘簲鍟嗗悕绉板尮閰� + // 缁勮鏌ヨ鏉′欢锛氱叅绉岻D鍦ㄥ尮閰嶇殑鍒楄〃涓� queryWrapper.and(w -> { if (!matchedCoalIds.isEmpty()) { w.in(PurchaseRegistration::getCoalId, matchedCoalIds).or(); diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/TimingTaskScheduler.java b/main-business/src/main/java/com/ruoyi/business/service/impl/TimingTaskScheduler.java new file mode 100644 index 0000000..9927845 --- /dev/null +++ b/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]); // 瑙f瀽鏃堕棿 + + // 璁$畻瀛e害璧峰鏈堜唤(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("鏃堕棿鏍煎紡蹇呴』涓篐H: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("瀛e害鏈堜唤蹇呴』鏄�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); + } + } +} diff --git a/main-business/src/main/java/com/ruoyi/business/service/impl/TimingTaskServiceImpl.java b/main-business/src/main/java/com/ruoyi/business/service/impl/TimingTaskServiceImpl.java new file mode 100644 index 0000000..fe1d77e --- /dev/null +++ b/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<>(); + + // 鏀堕泦鐧昏浜篒D + taskPage.getRecords().forEach(task -> { + if (task.getRegistrantId() != null) { + userIds.add(task.getRegistrantId()); + } + }); + + // 鏀堕泦宸℃浜篒D锛堝涓狪D浠ラ�楀彿鍒嗛殧锛� + 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. 杞崲涓篋TO + 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); // 瑙f瀽鏍煎紡 "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]); // 鏃堕棿閮ㄥ垎 + + // 瑙f瀽鏄熸湡鍑�(鏀寔澶氫釜鏄熸湡) + 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]); + + // 璁$畻褰撳墠瀛e害 + 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 { + // 闇�瑕佸埌涓嬩釜瀛e害 + 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() + ); + } + + /** + * 瑙f瀽鏄熸湡鍑犲瓧绗︿覆 + */ + 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("鑷姩鐢熸垚鑷畾鏃朵换鍔D: " + 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)); + } +} diff --git a/main-business/src/main/java/com/ruoyi/business/task/TimingTaskJob.java b/main-business/src/main/java/com/ruoyi/business/task/TimingTaskJob.java new file mode 100644 index 0000000..bf4d1dc --- /dev/null +++ b/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 // 绂佹骞跺彂鎵ц鍚屼竴涓狫ob +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("鑷姩鐢熸垚鑷畾鏃朵换鍔D: " + timingTask.getId()); + inspectionTask.setRegistrantId(timingTask.getRegistrantId()); + inspectionTask.setFrequencyType(timingTask.getFrequencyType()); + + return inspectionTask; + } +} diff --git a/main-business/src/main/resources/db/migration/postgresql/V20250614134700__create_table_inspection_task.sql b/main-business/src/main/resources/db/migration/postgresql/V20250614134700__create_table_inspection_task.sql index d469e66..68aab45 100644 --- a/main-business/src/main/resources/db/migration/postgresql/V20250614134700__create_table_inspection_task.sql +++ b/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 '璁板綍鏈�鍚庢洿鏂版椂闂�'; \ No newline at end of file +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 '璁板綍鏈�鍚庢洿鏂版椂闂�'; \ No newline at end of file diff --git a/main-business/src/main/resources/db/migration/postgresql/V20250630153900__create_table_timing_task.sql b/main-business/src/main/resources/db/migration/postgresql/V20250630153900__create_table_timing_task.sql new file mode 100644 index 0000000..d5c2107 --- /dev/null +++ b/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, -- 宸℃浜篿ds锛屼笉鍏佽涓虹┖ + inspection_location VARCHAR(255) NOT NULL, -- 宸℃鍦扮偣锛屼笉鍏佽涓虹┖ + -- 瀹氭椂閰嶇疆 + frequency_type VARCHAR(20) NOT NULL CHECK (frequency_type IN ('DAILY', 'WEEKLY', 'MONTHLY', 'QUARTERLY')), + frequency_detail VARCHAR(100), -- 鍏蜂綋鏃堕棿閰嶇疆 + + -- 姣忔棩浠诲姟閰嶇疆绀轰緥锛歠requency_type='DAILY', frequency_detail='14:30' + -- 姣忓懆浠诲姟閰嶇疆绀轰緥锛歠requency_type='WEEKLY', frequency_detail='MON;14:30' + -- 姣忔湀浠诲姟閰嶇疆绀轰緥锛歠requency_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, -- 鐧昏浜篿d锛屼笉鍏佽涓虹┖ + 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 '鐧昏浜篿d'; +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 '璁板綍鏈�鍚庢洿鏂版椂闂�'; \ No newline at end of file diff --git a/main-business/src/main/resources/db/migration/postgresql/V20250701142700__create_table_equipment_management.sql b/main-business/src/main/resources/db/migration/postgresql/V20250701142700__create_table_equipment_management.sql new file mode 100644 index 0000000..0abb2b1 --- /dev/null +++ b/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 ' 浣跨敤浜篒D '; +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 '璁板綍鏈�鍚庢洿鏂版椂闂�'; diff --git a/main-business/src/main/resources/mapper/EquipmentManagementMapper.xml b/main-business/src/main/resources/mapper/EquipmentManagementMapper.xml new file mode 100644 index 0000000..2726016 --- /dev/null +++ b/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> \ No newline at end of file diff --git a/main-business/src/main/resources/mapper/TimingTaskMapper.xml b/main-business/src/main/resources/mapper/TimingTaskMapper.xml new file mode 100644 index 0000000..70fd0ab --- /dev/null +++ b/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> \ No newline at end of file diff --git a/main-business/src/main/resources/mapper/TreeMapper.xml b/main-business/src/main/resources/mapper/TreeMapper.xml index d9c0ef1..fcedc3f 100644 --- a/main-business/src/main/resources/mapper/TreeMapper.xml +++ b/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> \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java index a5063ac..0928434 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java +++ b/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); } diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml index 8cbe2d3..b91baa4 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/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 椤哄簭杩斿洖缁撴灉锛圥ostgreSQL 涓撶敤锛� --> + <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> -- Gitblit v1.9.3