From 2f07589b54d56085af77b50d580890cd4130b444 Mon Sep 17 00:00:00 2001
From: 吴羡 <16976746+Xian-TT3@user.noreply.gitee.com>
Date: 星期一, 19 十月 2026 15:19:53 +0800
Subject: [PATCH] 设备模块后端业务规则、计划接口与日期联动

---
 cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenancePlanServiceImpl.java |  165 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 163 insertions(+), 2 deletions(-)

diff --git a/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenancePlanServiceImpl.java b/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenancePlanServiceImpl.java
index 81c5582..656bb10 100644
--- a/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenancePlanServiceImpl.java
+++ b/cnas-device/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenancePlanServiceImpl.java
@@ -2,6 +2,7 @@
 
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -18,6 +19,8 @@
 import com.ruoyi.device.dto.DeviceMaintenancePlanDto;
 import com.ruoyi.device.mapper.DeviceMaintenancePlanDetailsMapper;
 import com.ruoyi.device.mapper.DeviceMaintenancePlanMapper;
+import com.ruoyi.device.mapper.DeviceMapper;
+import com.ruoyi.device.pojo.Device;
 import com.ruoyi.device.pojo.DeviceMaintenancePlan;
 import com.ruoyi.device.pojo.DeviceMaintenancePlanDetails;
 import com.ruoyi.device.service.DeviceMaintenancePlanDetailsService;
@@ -30,13 +33,16 @@
 import org.springframework.beans.BeanUtils;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletResponse;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URLEncoder;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.HashMap;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -50,6 +56,7 @@
  * @since 2024-12-16 06:10:52
  */
 @Service
+@Transactional(rollbackFor = Exception.class)
 public class DeviceMaintenancePlanServiceImpl extends ServiceImpl<DeviceMaintenancePlanMapper, DeviceMaintenancePlan> implements DeviceMaintenancePlanService {
 
     @Resource
@@ -62,6 +69,8 @@
     private InformationNotificationService informationNotificationService;
     @Resource
     private UserMapper userMapper;
+    @Resource
+    private DeviceMapper deviceMapper;
 
     /**
      * 鍒嗛〉鏌ヨ璁惧淇濆吇璁″垝
@@ -181,9 +190,9 @@
                     put("deviceMaintenancePlan", deviceMaintenancePlan);
                     put("deviceMaintenancePlanDetailsDtoList", deviceMaintenancePlanDetailsDtoList);
                     // 缂栧埗浜虹鍚嶅湴鍧�
-                    put("compilerUrl", UserUtils.getFinalUserSignatureUrl(deviceMaintenancePlan.getCompilerId()));
+                    put("compilerUrl", UserUtils.getFinalUserSignatureOrTransparent(deviceMaintenancePlan.getCompilerId()));
                     // 瀹℃牳浜虹鍚嶅湴鍧�
-                    put("auditUrl", UserUtils.getFinalUserSignatureUrl(deviceMaintenancePlan.getAuditId()));
+                    put("auditUrl", UserUtils.getFinalUserSignatureOrTransparent(deviceMaintenancePlan.getAuditId()));
                 }});
 
         try {
@@ -288,5 +297,157 @@
         return Result.success();
     }
 
+    /**
+     * 鎸夊勾浠芥煡璇㈣澶囦繚鍏昏鍒掞紙涓嶅瓨鍦ㄥ垯鑷姩鍒涘缓锛夛紝骞惰嚜鍔ㄨˉ鍏ㄥ凡鍒扮偣鐨勮澶囨槑缁�
+     */
+    @Override
+    public DeviceMaintenancePlanDto getOrCreatePlanByYear(String planYear) {
+        if (StringUtils.isBlank(planYear)) {
+            planYear = String.valueOf(LocalDate.now().getYear());
+        }
+        DeviceMaintenancePlan plan = getOrCreatePlanEntity(planYear);
+        ensureMaintenanceDetails(plan);
+        DeviceMaintenancePlanDto planDto = new DeviceMaintenancePlanDto();
+        BeanUtils.copyProperties(plan, planDto);
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        planDto.setDatePreparationStr(plan.getDatePreparation() == null ? null : plan.getDatePreparation().format(formatter));
+        planDto.setAuditDateStr(plan.getAuditDate() == null ? null : plan.getAuditDate().format(formatter));
+        if (StringUtils.isBlank(planDto.getCompiler()) && plan.getCompilerId() != null) {
+            User compiler = userMapper.selectById(plan.getCompilerId());
+            if (compiler != null) {
+                planDto.setCompiler(compiler.getName());
+            }
+        }
+        if (StringUtils.isBlank(planDto.getAudit()) && plan.getAuditId() != null) {
+            User audit = userMapper.selectById(plan.getAuditId());
+            if (audit != null) {
+                planDto.setAudit(audit.getName());
+            }
+        }
+        return planDto;
+    }
+
+    /**
+     * 璁惧妗f鍙樻洿鍚庯紝鎶婂凡鍒扮偣鐨勮澶囧悓姝ュ埌瀵瑰簲骞翠唤鐨勮澶囦繚鍏昏鍒掓槑缁�
+     */
+    @Override
+    public void syncDeviceMaintenanceDetail(Device device) {
+        LocalDate remind = calcMaintenanceRemindDate(device);
+        if (remind == null || remind.isAfter(LocalDate.now())) {
+            return;
+        }
+        DeviceMaintenancePlan plan = getOrCreatePlanEntity(String.valueOf(remind.getYear()));
+        fillMaintenanceDetailIfAbsent(plan, device);
+    }
+
+    /**
+     * 淇濆吇璁板綍淇濆瓨鍚庯紝婊氬姩璁惧妗f鐨勬渶杩�/涓嬫淇濆吇鏃ユ湡
+     */
+    @Override
+    public void updateDeviceMaintenanceDate(Integer deviceId, LocalDate maintenanceDate) {
+        if (deviceId == null || maintenanceDate == null) {
+            return;
+        }
+        Device device = deviceMapper.selectById(deviceId);
+        if (device == null) {
+            return;
+        }
+        LocalDateTime recordDate = maintenanceDate.atStartOfDay();
+        // 鍙厑璁稿悜鍓嶆粴鍔紝閬垮厤琛ュ綍鏃ц褰曟椂鎶婃棩鏈熸敼鍥炲幓
+        if (device.getLastMaintenanceDate() != null && !recordDate.isAfter(device.getLastMaintenanceDate())) {
+            return;
+        }
+        device.setLastMaintenanceDate(recordDate);
+        if (StringUtils.isNotBlank(device.getMaintenanceCycle())) {
+            try {
+                device.setNextMaintenanceDate(recordDate.plusMonths(Long.parseLong(device.getMaintenanceCycle().trim())));
+            } catch (NumberFormatException ignored) {
+            }
+        }
+        deviceMapper.updateById(device);
+    }
+
+    /**
+     * 鍒嗛〉鏌ヨ璁惧淇濆吇璁″垝璇︽儏锛堝惈鍒扮偣鏍囩孩锛�
+     */
+    @Override
+    public IPage<DeviceMaintenancePlanDetailsDto> pageMaintenancePlanDetail(Page page, Integer planId, String deviceName, String deviceNumber) {
+        if (planId == null) {
+            return new Page<>();
+        }
+        return deviceMaintenancePlanDetailsMapper.pageMaintenancePlanDetail(page, planId, deviceName, deviceNumber);
+    }
+
+    /**
+     * 鏌ヨ骞翠唤瀵瑰簲鐨勮鍒掞紝涓嶅瓨鍦ㄥ垯鍒涘缓
+     */
+    private DeviceMaintenancePlan getOrCreatePlanEntity(String planYear) {
+        DeviceMaintenancePlan plan = baseMapper.selectOne(Wrappers.<DeviceMaintenancePlan>lambdaQuery()
+                .eq(DeviceMaintenancePlan::getPlanYear, planYear)
+                .orderByDesc(DeviceMaintenancePlan::getMaintenancePlanId)
+                .last("limit 1"));
+        if (plan == null) {
+            plan = new DeviceMaintenancePlan();
+            plan.setPlanName(planYear + "骞村害璁惧淇濆吇璁″垝");
+            plan.setPlanYear(planYear);
+            Integer userId = SecurityUtils.getUserId().intValue();
+            User user = userMapper.selectById(userId);
+            plan.setCompilerId(userId);
+            plan.setCompiler(user == null ? null : user.getName());
+            plan.setDatePreparation(LocalDateTime.now());
+            baseMapper.insert(plan);
+        }
+        return plan;
+    }
+
+    /**
+     * 鎵弿鎵�鏈夎澶囷紝鎶婂凡鍒扮偣锛堜笅娆′繚鍏绘棩鏈熷墠1涓湀璧凤紝鍚凡杩囨湡锛夌殑璁惧琛ヨ繘鏈勾搴﹁鍒�
+     */
+    private void ensureMaintenanceDetails(DeviceMaintenancePlan plan) {
+        List<Device> devices = deviceMapper.selectList(null);
+        for (Device device : devices) {
+            fillMaintenanceDetailIfAbsent(plan, device);
+        }
+    }
+
+    /**
+     * 璁惧鎻愰啋璧风偣锛氫笅娆′繚鍏绘棩鏈熷墠1涓湀锛堟病濉笅娆℃棩鏈熸椂鐢ㄦ渶杩戞棩鏈�+淇濆吇鍛ㄦ湡鍏滃簳锛�
+     */
+    private LocalDate calcMaintenanceRemindDate(Device device) {
+        LocalDateTime base = device.getNextMaintenanceDate();
+        if (base == null && device.getLastMaintenanceDate() != null && StringUtils.isNotBlank(device.getMaintenanceCycle())) {
+            try {
+                base = device.getLastMaintenanceDate().plusMonths(Long.parseLong(device.getMaintenanceCycle().trim()));
+            } catch (NumberFormatException ignored) {
+            }
+        }
+        return base == null ? null : base.toLocalDate().minusMonths(1);
+    }
+
+    /**
+     * 宸插埌鐐逛笖璁″垝涓皻鏃犺璁惧鏈疆鏄庣粏鏃惰嚜鍔ㄨˉ涓�鏉�
+     */
+    private void fillMaintenanceDetailIfAbsent(DeviceMaintenancePlan plan, Device device) {
+        LocalDate remind = calcMaintenanceRemindDate(device);
+        if (remind == null || remind.isAfter(LocalDate.now())) {
+            return;
+        }
+        if (plan.getPlanYear() != null && String.valueOf(remind.getYear()).compareTo(plan.getPlanYear()) > 0) {
+            return;
+        }
+        Long exist = deviceMaintenancePlanDetailsMapper.selectCount(Wrappers.<DeviceMaintenancePlanDetails>lambdaQuery()
+                .eq(DeviceMaintenancePlanDetails::getMaintenancePlanId, plan.getMaintenancePlanId())
+                .eq(DeviceMaintenancePlanDetails::getDeviceId, device.getId())
+                .eq(DeviceMaintenancePlanDetails::getMaintenanceDate, remind));
+        if (exist != null && exist > 0) {
+            return;
+        }
+        DeviceMaintenancePlanDetails detail = new DeviceMaintenancePlanDetails();
+        detail.setMaintenancePlanId(plan.getMaintenancePlanId());
+        detail.setDeviceId(device.getId());
+        detail.setMaintenanceIntervals(device.getMaintenanceCycle());
+        detail.setMaintenanceDate(remind);
+        deviceMaintenancePlanDetailsMapper.insert(detail);
+    }
 
 }

--
Gitblit v1.9.3