From 089964a497c2528e88ddc610af5f88f631303431 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期一, 18 五月 2026 15:28:16 +0800
Subject: [PATCH] feat: 设备保养新增任务状态,启动/停止与调度器关联

---
 src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceFileServiceImpl.java |  186 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 184 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceFileServiceImpl.java b/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceFileServiceImpl.java
index 09e8df1..ac5cd66 100644
--- a/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceFileServiceImpl.java
+++ b/src/main/java/com/ruoyi/device/service/impl/DeviceMaintenanceFileServiceImpl.java
@@ -1,10 +1,31 @@
 package com.ruoyi.device.service.impl;
 
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.device.mapper.DeviceMaintenanceFileMapper;
 import com.ruoyi.device.pojo.DeviceMaintenanceFile;
 import com.ruoyi.device.service.DeviceMaintenanceFileService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.framework.config.RuoYiConfig;
+import com.ruoyi.other.mapper.TempFileMapper;
+import com.ruoyi.other.pojo.TempFile;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FilenameUtils;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.UUID;
 
 /**
  * <p>
@@ -15,6 +36,167 @@
  * @since 2026-01-27 09:48:09
  */
 @Service
-public class DeviceMaintenanceFileServiceImpl extends ServiceImpl<DeviceMaintenanceFileMapper, DeviceMaintenanceFile> implements DeviceMaintenanceFileService {
+@Slf4j
+public class DeviceMaintenanceFileServiceImpl extends ServiceImpl<DeviceMaintenanceFileMapper, DeviceMaintenanceFile>
+        implements DeviceMaintenanceFileService {
 
+    @Resource
+    private TempFileMapper tempFileMapper;
+
+    @Value("${file.upload-dir}")
+    private String uploadDir;
+
+    @Value("${file.temp-dir}")
+    private String tempDir;
+
+    @Override
+    public DeviceMaintenanceFile uploadFile(MultipartFile file, Integer deviceMaintenanceId) throws IOException {
+        if (deviceMaintenanceId == null || deviceMaintenanceId <= 0) {
+            throw new ServiceException("璁惧淇濆吇璁板綍ID涓嶈兘涓虹┖");
+        }
+        if (file == null || file.isEmpty()) {
+            throw new ServiceException("涓婁紶澶辫触锛屾枃浠朵笉鑳戒负绌�");
+        }
+        Path formalPath = storeMultipartFile(file, deviceMaintenanceId);
+        return insertFileRecord(deviceMaintenanceId, file.getOriginalFilename(), formalPath, (int) file.getSize());
+    }
+
+    @Override
+    public DeviceMaintenanceFile bindFromTemp(String tempId, Integer deviceMaintenanceId, String name) throws IOException {
+        if (!StringUtils.hasText(tempId)) {
+            throw new ServiceException("涓存椂鏂囦欢ID涓嶈兘涓虹┖");
+        }
+        if (deviceMaintenanceId == null || deviceMaintenanceId <= 0) {
+            throw new ServiceException("璁惧淇濆吇璁板綍ID涓嶈兘涓虹┖");
+        }
+        TempFile tempFile = tempFileMapper.selectById(tempId);
+        if (tempFile == null) {
+            throw new ServiceException("涓存椂鏂囦欢涓嶅瓨鍦ㄦ垨宸茶繃鏈�");
+        }
+        Path source = Paths.get(tempFile.getTempPath());
+        if (!Files.exists(source)) {
+            tempFileMapper.deleteById(tempId);
+            throw new ServiceException("涓存椂鏂囦欢宸插け鏁堬紝璇烽噸鏂颁笂浼�");
+        }
+        Path formalPath = copyToFormalDir(source, deviceMaintenanceId, tempFile.getOriginalName());
+        Files.deleteIfExists(source);
+        tempFileMapper.deleteById(tempId);
+        String fileName = StringUtils.hasText(name) ? name : tempFile.getOriginalName();
+        return insertFileRecord(deviceMaintenanceId, fileName, formalPath, null);
+    }
+
+    @Override
+    public DeviceMaintenanceFile saveRecord(DeviceMaintenanceFile deviceMaintenanceFile) throws IOException {
+        if (deviceMaintenanceFile == null) {
+            throw new ServiceException("闄勪欢淇℃伅涓嶈兘涓虹┖");
+        }
+        if (StringUtils.hasText(deviceMaintenanceFile.getTempId())) {
+            return bindFromTemp(
+                    deviceMaintenanceFile.getTempId(),
+                    deviceMaintenanceFile.getDeviceMaintenanceId(),
+                    deviceMaintenanceFile.getName());
+        }
+        String url = deviceMaintenanceFile.getUrl();
+        if (isTempStoragePath(url)) {
+            throw new ServiceException("璇峰嬁鐩存帴淇濆瓨涓存椂鐩綍鏂囦欢锛岃浣跨敤涓婁紶鎺ュ彛鎴栦紶閫� tempId");
+        }
+        if (StringUtils.hasText(url) && !url.startsWith(Constants.RESOURCE_PREFIX)) {
+            deviceMaintenanceFile.setUrl(buildAccessLink(Paths.get(url)));
+        }
+        save(deviceMaintenanceFile);
+        enrichAccessUrl(deviceMaintenanceFile);
+        return deviceMaintenanceFile;
+    }
+
+    @Override
+    public void enrichAccessUrl(List<DeviceMaintenanceFile> files) {
+        if (files == null) {
+            return;
+        }
+        files.forEach(this::enrichAccessUrl);
+    }
+
+    private void enrichAccessUrl(DeviceMaintenanceFile file) {
+        if (file == null || !StringUtils.hasText(file.getUrl())) {
+            return;
+        }
+        String url = file.getUrl().trim();
+        if (url.startsWith(Constants.RESOURCE_PREFIX) || url.startsWith("http://") || url.startsWith("https://")) {
+            return;
+        }
+        try {
+            file.setUrl(buildAccessLink(Paths.get(url)));
+        } catch (Exception e) {
+            log.warn("闄勪欢URL杞崲澶辫触 id={} url={}", file.getId(), url);
+        }
+    }
+
+    private Path storeMultipartFile(MultipartFile file, Integer deviceMaintenanceId) throws IOException {
+        Path formalDirPath = resolveFormalDirPath();
+        Files.createDirectories(formalDirPath);
+        String originalFilename = file.getOriginalFilename();
+        if (!StringUtils.hasText(originalFilename)) {
+            throw new ServiceException("鏂囦欢鍚嶄笉鑳戒负绌�");
+        }
+        Path formalPath = formalDirPath.resolve(buildFormalFilename(deviceMaintenanceId, originalFilename));
+        file.transferTo(formalPath.toFile());
+        return formalPath;
+    }
+
+    private Path copyToFormalDir(Path source, Integer deviceMaintenanceId, String originalFilename) throws IOException {
+        Path formalDirPath = resolveFormalDirPath();
+        Files.createDirectories(formalDirPath);
+        String name = StringUtils.hasText(originalFilename) ? originalFilename : source.getFileName().toString();
+        Path formalPath = formalDirPath.resolve(buildFormalFilename(deviceMaintenanceId, name));
+        Files.copy(source, formalPath, StandardCopyOption.REPLACE_EXISTING);
+        return formalPath;
+    }
+
+    private Path resolveFormalDirPath() {
+        String dir = uploadDir;
+        if (!dir.endsWith("/") && !dir.endsWith("\\")) {
+            dir = dir + "/";
+        }
+        return Paths.get(dir + "deviceMaintenance/" + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE));
+    }
+
+    private String buildFormalFilename(Integer deviceMaintenanceId, String originalFilename) {
+        String ext = FilenameUtils.getExtension(originalFilename);
+        String base = deviceMaintenanceId + "_" + System.currentTimeMillis() + "_"
+                + UUID.randomUUID().toString().substring(0, 8);
+        return StringUtils.hasText(ext) ? base + "." + ext : base;
+    }
+
+    private DeviceMaintenanceFile insertFileRecord(Integer deviceMaintenanceId, String name, Path formalPath, Integer fileSize) {
+        DeviceMaintenanceFile record = new DeviceMaintenanceFile();
+        record.setName(name);
+        record.setUrl(buildAccessLink(formalPath));
+        record.setFileSize(fileSize);
+        record.setDeviceMaintenanceId(deviceMaintenanceId);
+        save(record);
+        return record;
+    }
+
+    private boolean isTempStoragePath(String url) {
+        if (!StringUtils.hasText(url)) {
+            return false;
+        }
+        String normalized = url.replace("\\", "/").toLowerCase();
+        return normalized.contains("/temp/") || normalized.contains("temp/uploads");
+    }
+
+    private String buildAccessLink(Path formalFilePath) {
+        String normalizedPath = formalFilePath.toString().replace("\\", "/");
+        String profile = RuoYiConfig.getProfile();
+        String normalizedProfile = profile == null ? "" : profile.replace("\\", "/");
+
+        String relativePath = normalizedPath;
+        if (StringUtils.hasText(normalizedProfile) && normalizedPath.startsWith(normalizedProfile)) {
+            relativePath = normalizedPath.substring(normalizedProfile.length());
+        }
+        if (!relativePath.startsWith("/")) {
+            relativePath = "/" + relativePath;
+        }
+        return Constants.RESOURCE_PREFIX + relativePath;
+    }
 }

--
Gitblit v1.9.3