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