|
@@ -0,0 +1,140 @@
|
|
|
|
+package com.ruoyi.file.service;
|
|
|
|
+
|
|
|
|
+import com.ruoyi.file.model.FileUpdateInfo;
|
|
|
|
+import com.ruoyi.file.repository.FileUpdateInfoRepository;
|
|
|
|
+import org.apache.commons.codec.digest.DigestUtils;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
+
|
|
|
|
+import java.io.*;
|
|
|
|
+import java.net.HttpURLConnection;
|
|
|
|
+import java.net.URL;
|
|
|
|
+import java.nio.file.Files;
|
|
|
|
+import java.nio.file.Path;
|
|
|
|
+import java.nio.file.Paths;
|
|
|
|
+import java.nio.file.StandardCopyOption;
|
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.Arrays;
|
|
|
|
+import java.util.Date;
|
|
|
|
+import java.util.List;
|
|
|
|
+
|
|
|
|
+@Service
|
|
|
|
+public class FileUpdateService {
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private FileUpdateInfoRepository fileUpdateInfoRepository;
|
|
|
|
+
|
|
|
|
+ public void addFileToDatabase(FileUpdateRequest request) throws Exception {
|
|
|
|
+ String fileName = request.getFileName();
|
|
|
|
+ String filePath = request.getFilePath();
|
|
|
|
+
|
|
|
|
+ File file = new File(filePath);
|
|
|
|
+ if (!file.exists()) {
|
|
|
|
+ throw new FileNotFoundException("文件不存在:" + filePath);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String fileMd5 = DigestUtils.md5Hex(new FileInputStream(file));
|
|
|
|
+ FileUpdateInfo fileUpdateInfo = new FileUpdateInfo();
|
|
|
|
+ fileUpdateInfo.setFileName(fileName);
|
|
|
|
+ fileUpdateInfo.setFilePath(filePath);
|
|
|
|
+ fileUpdateInfo.setFileMd5(fileMd5);
|
|
|
|
+ fileUpdateInfo.setUpdateTime(new Date());
|
|
|
|
+ fileUpdateInfo.setUpdateStatus("待检查文件版本");
|
|
|
|
+ fileUpdateInfoRepository.save(fileUpdateInfo);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 检查文件是否需要更新
|
|
|
|
+ public boolean checkFileUpdate(Long id) throws Exception {
|
|
|
|
+ FileUpdateInfo fileUpdateInfo = fileUpdateInfoRepository.findById(id).orElse(null);
|
|
|
|
+ if (fileUpdateInfo == null) {
|
|
|
|
+ throw new FileNotFoundException("文件信息未找到:id=" + id);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String localFilePath = fileUpdateInfo.getFilePath();
|
|
|
|
+ String localFileMd5 = fileUpdateInfo.getFileMd5();
|
|
|
|
+ String fileName = fileUpdateInfo.getFileName(); // 获取文件名
|
|
|
|
+ String remoteFileMd5 = getRemoteFileMd5(fileName); // 获取远程文件的 MD5 值
|
|
|
|
+
|
|
|
|
+ boolean isUpdateRequired = !localFileMd5.equals(remoteFileMd5);
|
|
|
|
+ fileUpdateInfo.setRemoteMd5(remoteFileMd5); // 更新远程文件的 MD5 值
|
|
|
|
+ fileUpdateInfo.setUpdateTime(new Date());
|
|
|
|
+ fileUpdateInfo.setUpdateStatus(isUpdateRequired ? "待更新" : "无需更新");
|
|
|
|
+ fileUpdateInfoRepository.save(fileUpdateInfo);
|
|
|
|
+
|
|
|
|
+ return isUpdateRequired;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 执行文件更新
|
|
|
|
+ public void performFileUpdate(Long id) throws Exception {
|
|
|
|
+ FileUpdateInfo fileUpdateInfo = fileUpdateInfoRepository.findById(id).orElse(null);
|
|
|
|
+ if (fileUpdateInfo == null) {
|
|
|
|
+ throw new FileNotFoundException("文件信息未找到:id=" + id);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String localFilePath = fileUpdateInfo.getFilePath();
|
|
|
|
+ String fileName = fileUpdateInfo.getFileName(); // 获取文件名
|
|
|
|
+ String remoteUrl = "https://file.usky.cn/uskycloud/" + fileName; // 替换为实际的远程文件 URL
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ // 检查并创建备份目录
|
|
|
|
+ String backupDirPath = localFilePath + "-backup";
|
|
|
|
+ File backupDir = new File(backupDirPath);
|
|
|
|
+ if (!backupDir.exists()) {
|
|
|
|
+ boolean created = backupDir.mkdirs();
|
|
|
|
+ if (!created) {
|
|
|
|
+ throw new IOException("无法创建备份目录: " + backupDirPath);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 为旧文件添加时间戳并移动到备份目录
|
|
|
|
+ File originalFile = new File(localFilePath);
|
|
|
|
+ if (originalFile.exists()) {
|
|
|
|
+ String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
|
|
|
|
+ String backupFilePath = backupDirPath + File.separator + fileName + "." + timestamp;
|
|
|
|
+ Files.move(originalFile.toPath(), Paths.get(backupFilePath), StandardCopyOption.REPLACE_EXISTING);
|
|
|
|
+ System.out.println("旧文件已备份到: " + backupFilePath);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 下载远程文件
|
|
|
|
+ downloadFileFromRemote(remoteUrl, localFilePath);
|
|
|
|
+
|
|
|
|
+ // 更新数据库中的文件信息
|
|
|
|
+ String newFileMd5 = DigestUtils.md5Hex(new FileInputStream(localFilePath));
|
|
|
|
+ fileUpdateInfo.setFileMd5(newFileMd5);
|
|
|
|
+ fileUpdateInfo.setUpdateTime(new Date());
|
|
|
|
+ fileUpdateInfo.setUpdateStatus("已更新");
|
|
|
|
+ fileUpdateInfoRepository.save(fileUpdateInfo);
|
|
|
|
+ } catch (FileNotFoundException e) {
|
|
|
|
+ throw new Exception("文件未找到: " + localFilePath + ",原因: " + e.getMessage(), e);
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ throw new Exception("文件写入失败: " + localFilePath + ",原因: " + e.getMessage(), e);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new Exception("文件更新失败: " + localFilePath + ",原因: " + e.getMessage(), e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void downloadFileFromRemote(String remoteUrl, String localFilePath) throws Exception {
|
|
|
|
+ URL url = new URL(remoteUrl);
|
|
|
|
+ Path path = Paths.get(localFilePath);
|
|
|
|
+ try {
|
|
|
|
+ Files.copy(url.openStream(), path, StandardCopyOption.REPLACE_EXISTING);
|
|
|
|
+ System.out.println("文件下载成功: " + localFilePath);
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ System.err.println("文件下载失败: " + localFilePath + ",原因: " + e.getMessage());
|
|
|
|
+ throw new Exception("文件下载失败: " + localFilePath, e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ private String getRemoteFileMd5(String fileName) throws Exception {
|
|
|
|
+ String remoteUrl = "https://file.usky.cn/uskycloud/" + fileName;
|
|
|
|
+ System.out.println("远程文件 URL: " + remoteUrl);
|
|
|
|
+ URL url = new URL(remoteUrl);
|
|
|
|
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
|
|
|
+ connection.setRequestProperty("Cache-Control", "no-cache");
|
|
|
|
+ try (InputStream in = connection.getInputStream()) {
|
|
|
|
+ return DigestUtils.md5Hex(in);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|