From 55d694aaae4e421b5e55cd941500e08f85cb5d4d Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 27 八月 2026 18:21:33 +0800
Subject: [PATCH] feat(sales): 添加框架合同订单功能并优化销售台账管理

---
 src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskServiceImpl.java |  130 ++++++++++++++++++++++++++++++++++++-------
 1 files changed, 109 insertions(+), 21 deletions(-)

diff --git a/src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskServiceImpl.java b/src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskServiceImpl.java
index 6cf4b7a..02a444b 100644
--- a/src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskServiceImpl.java
+++ b/src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskServiceImpl.java
@@ -1,20 +1,20 @@
 package com.ruoyi.inspectiontask.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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.bean.BeanUtils;
 import com.ruoyi.inspectiontask.dto.TimingTaskDto;
-import com.ruoyi.inspectiontask.mapper.InspectionTaskMapper;
 import com.ruoyi.inspectiontask.mapper.TimingTaskMapper;
 import com.ruoyi.inspectiontask.pojo.TimingTask;
 import com.ruoyi.inspectiontask.service.TimingTaskService;
 import com.ruoyi.project.system.domain.SysUser;
 import com.ruoyi.project.system.mapper.SysUserMapper;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.quartz.SchedulerException;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -29,25 +29,33 @@
  */
 @Service
 @Slf4j
+@RequiredArgsConstructor
 public class TimingTaskServiceImpl extends ServiceImpl<TimingTaskMapper, TimingTask> implements TimingTaskService {
 
-    @Autowired
-    private TimingTaskMapper timingTaskMapper;
-
-    @Autowired
-    private InspectionTaskMapper inspectionTaskMapper;
-
-    @Autowired
-    private TimingTaskScheduler timingTaskScheduler;
-
-    @Autowired
-    private SysUserMapper sysUserMapper;
+    private final TimingTaskMapper timingTaskMapper;
+    private final TimingTaskScheduler timingTaskScheduler;
+    private final SysUserMapper sysUserMapper;
+    private final com.ruoyi.device.mapper.DeviceLedgerMapper deviceLedgerMapper;
+    private static final int ENABLED = 1;
+    private static final int DISABLED = 0;
 
 
     @Override
     public IPage<TimingTaskDto> selectTimingTaskList(Page<TimingTask> page, TimingTask timingTask) {
         // 1. 鍏堝垎椤垫煡璇㈠畾鏃朵换鍔℃暟鎹�
-        IPage<TimingTask> taskPage = timingTaskMapper.selectPage(page, null);
+        // 鏋勫缓鏌ヨ鏉′欢
+        LambdaQueryWrapper<TimingTask> queryWrapper = new LambdaQueryWrapper<>();
+        if (StringUtils.isNotBlank(timingTask.getTaskName())) {
+            queryWrapper.like(TimingTask::getTaskName, timingTask.getTaskName());
+        }
+        if (StringUtils.isNotBlank(timingTask.getInspectionProject())) {
+            queryWrapper.like(TimingTask::getInspectionProject, timingTask.getInspectionProject());
+        }
+        if (timingTask.getIsEnabled() != null) {
+            queryWrapper.eq(TimingTask::getIsEnabled, timingTask.getIsEnabled());
+        }
+        queryWrapper.orderByDesc(TimingTask::getCreateTime);
+        IPage<TimingTask> taskPage = timingTaskMapper.selectPage(page, queryWrapper);
 
         // 2. 濡傛灉娌℃湁鏁版嵁锛岀洿鎺ヨ繑鍥炵┖鍒嗛〉
         if (taskPage.getRecords().isEmpty()) {
@@ -117,12 +125,24 @@
     @Override
     @Transactional
     public int addOrEditTimingTask(TimingTaskDto timingTaskDto) throws SchedulerException {
+        TimingTask oldTimingTask = null;
+        if (Objects.nonNull(timingTaskDto.getId())) {
+            oldTimingTask = timingTaskMapper.selectById(timingTaskDto.getId());
+            if (oldTimingTask == null) {
+                throw new IllegalArgumentException("瀹氭椂浠诲姟涓嶅瓨鍦�");
+            }
+        }
+        validateDeviceExists(timingTaskDto, oldTimingTask);
         TimingTask timingTask = new TimingTask();
         BeanUtils.copyProperties(timingTaskDto, timingTask);
+        timingTask.setIsEnabled(resolveEnabledValue(timingTask.getIsEnabled(), oldTimingTask));
+        timingTask.setActive(ENABLED == timingTask.getIsEnabled());
         // 1. 瑙f瀽瀛楃涓蹭负 LocalDate锛堝彧鍖呭惈骞存湀鏃ワ級
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-        LocalDate localDate = LocalDate.parse(timingTaskDto.getDateStr(), formatter);
-
+        LocalDate localDate = LocalDate.now();
+        if(StringUtils.isNotEmpty(timingTaskDto.getDateStr())){
+            localDate = LocalDate.parse(timingTaskDto.getDateStr(), formatter);
+        }
         // 2. 鑾峰彇褰撳墠绯荤粺鐨� LocalTime锛堝寘鍚椂鍒嗙锛�
         LocalTime currentTime = LocalTime.now();
 
@@ -132,13 +152,12 @@
         // 璁剧疆鍒涘缓浜轰俊鎭拰榛樿鍊�
         if (Objects.isNull(timingTaskDto.getId())) {
             timingTask.setRegistrationDate(LocalDate.now());
-            timingTask.setActive(true);
 
             // 璁$畻棣栨鎵ц鏃堕棿
             LocalDateTime firstExecutionTime = calculateFirstExecutionTime(timingTask);
             timingTask.setNextExecutionTime(firstExecutionTime);
             int result = timingTaskMapper.insert(timingTask);
-            if (result > 0) {
+            if (result > 0 && isEnabled(timingTask.getIsEnabled(), timingTask.isActive())) {
                 // 鏂板鎴愬姛鍚庢坊鍔犲埌璋冨害鍣�
                 timingTaskScheduler.scheduleTimingTask(timingTask);
             }
@@ -148,10 +167,32 @@
 
             int result = timingTaskMapper.updateById(timingTask);
             if (result > 0) {
-                // 鏇存柊鎴愬姛鍚庨噸鏂拌皟搴︿换鍔�
-                timingTaskScheduler.rescheduleTimingTask(timingTask);
+                boolean oldEnabled = isEnabled(oldTimingTask == null ? null : oldTimingTask.getIsEnabled(), oldTimingTask != null && oldTimingTask.isActive());
+                boolean newEnabled = isEnabled(timingTask.getIsEnabled(), timingTask.isActive());
+                if (!newEnabled) {
+                    timingTaskScheduler.unscheduleTimingTask(timingTask.getId());
+                } else if (oldEnabled) {
+                    // 鏇存柊鎴愬姛鍚庨噸鏂拌皟搴︿换鍔�
+                    timingTaskScheduler.rescheduleTimingTask(timingTask);
+                } else {
+                    // 浠庣鐢ㄦ敼涓哄惎鐢ㄦ椂閲嶆柊鍒涘缓璋冨害浠诲姟
+                    timingTaskScheduler.scheduleTimingTask(timingTask);
+                }
             }
             return result;
+        }
+    }
+
+    private void validateDeviceExists(TimingTaskDto timingTaskDto, TimingTask oldTimingTask) {
+        Integer taskId = timingTaskDto.getTaskId();
+        if (taskId == null && oldTimingTask != null) {
+            taskId = oldTimingTask.getTaskId();
+        }
+        if (taskId == null || taskId <= 0) {
+            return;
+        }
+        if (deviceLedgerMapper.selectById(taskId.longValue()) == null) {
+            throw new IllegalArgumentException("鎵�閫夎澶囦笉瀛樺湪锛岃閲嶆柊閫夋嫨");
         }
     }
 
@@ -168,8 +209,9 @@
             // 濡傛灉鏄瘡鏈堟墽琛岋紝璁$畻涓嬩釜鏈堢殑鍏蜂綋鏃ユ湡
             return calculateMonthlyFirstExecution(task.getFrequencyDetail());
         } else if ("QUARTERLY".equals(frequencyType)) {
-            // 鑷畾涔夐鐜囷紝濡傛瘡灏忔椂銆佹瘡30鍒嗛挓绛�
             return calculateCustomFirstExecution(task.getFrequencyDetail());
+        } else if ("YEARLY".equals(frequencyType)) {
+            return calculateAnnualFirstExecution(task.getFrequencyDetail());
         } else {
             throw new IllegalArgumentException("涓嶆敮鎸佺殑棰戠巼绫诲瀷: " + task.getFrequencyType());
         }
@@ -286,6 +328,32 @@
         }
 
         return targetDateTime;
+    }
+
+    private LocalDateTime calculateAnnualFirstExecution(String frequencyDetail) {
+        String[] parts = frequencyDetail.split(",");
+        if (parts.length != 3) {
+            throw new IllegalArgumentException("鍙傛暟鏍煎紡閿欒锛屽簲涓�'12,31,09:00'鏍煎紡");
+        }
+
+        int month;
+        int day;
+        try {
+            month = Integer.parseInt(parts[0].trim());
+            day = Integer.parseInt(parts[1].trim());
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException("鏈堜唤鎴栨棩鏈熸牸寮忛敊璇�", e);
+        }
+        if (month < 1 || month > 12 || day < 1 || day > 31) {
+            throw new IllegalArgumentException("鏈堜唤蹇呴』鍦�1-12涔嬮棿锛屾棩鏈熷繀椤诲湪1-31涔嬮棿");
+        }
+
+        LocalTime time = LocalTime.parse(parts[2].trim(), DateTimeFormatter.ofPattern("HH:mm"));
+        LocalDateTime now = LocalDateTime.now();
+        int year = now.getYear();
+        LocalDateTime target = LocalDateTime.of(LocalDate.of(year, month, Math.min(day, YearMonth.of(year, month).lengthOfMonth())), time);
+        return target.isAfter(now) ? target : LocalDateTime.of(LocalDate.of(year + 1, month,
+                Math.min(day, YearMonth.of(year + 1, month).lengthOfMonth())), time);
     }
 
     private LocalDateTime calculateCustomFirstExecution(String frequencyDetail) {
@@ -451,6 +519,26 @@
         return days;
     }
 
+    private Integer resolveEnabledValue(Integer requestEnabled, TimingTask oldTimingTask) {
+        if (requestEnabled != null) {
+            return requestEnabled;
+        }
+        if (oldTimingTask != null) {
+            if (oldTimingTask.getIsEnabled() != null) {
+                return oldTimingTask.getIsEnabled();
+            }
+            return oldTimingTask.isActive() ? ENABLED : DISABLED;
+        }
+        return ENABLED;
+    }
+
+    private boolean isEnabled(Integer enabledValue, boolean activeFallback) {
+        if (enabledValue != null) {
+            return ENABLED == enabledValue;
+        }
+        return activeFallback;
+    }
+
 
 
     @Override

--
Gitblit v1.9.3