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.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>
|
* 设备保养附件 服务实现类
|
* </p>
|
*
|
* @author 芯导软件(江苏)有限公司
|
* @since 2026-01-27 09:48:09
|
*/
|
@Service
|
@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;
|
}
|
}
|