feat(后端): 联调修改2
parent
6cf65aeb83
commit
cccfb7bd86
|
@ -0,0 +1,20 @@
|
||||||
|
package com.unisinsight.project.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description:
|
||||||
|
* @author: rdpnr_puzhi
|
||||||
|
* @create: 2025/08/12
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class RestTemplateConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RestTemplate restTemplate() {
|
||||||
|
return new RestTemplate();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,8 @@
|
||||||
package com.unisinsight.project.controller;
|
package com.unisinsight.project.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.unisinsight.project.entity.dao.Image;
|
import com.unisinsight.project.entity.dao.Image;
|
||||||
import com.unisinsight.project.exception.BaseErrorCode;
|
import com.unisinsight.project.exception.BaseErrorCode;
|
||||||
import com.unisinsight.project.exception.Result;
|
import com.unisinsight.project.exception.Result;
|
||||||
|
@ -10,8 +13,11 @@ import lombok.Data;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
@ -21,10 +27,8 @@ import java.io.OutputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Comparator;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,6 +48,14 @@ public class FileChunkController {
|
||||||
@Value("${file.upload.dir:${user.home}/uploads}")
|
@Value("${file.upload.dir:${user.home}/uploads}")
|
||||||
private String uploadDir;
|
private String uploadDir;
|
||||||
|
|
||||||
|
// 请求bt配置
|
||||||
|
@Value("${file.upload.bt-url}")
|
||||||
|
private String btUrl;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
|
||||||
// 存储每个文件的分片信息
|
// 存储每个文件的分片信息
|
||||||
private final Map<String, FileUploadInfo> fileUploadMap = new ConcurrentHashMap<>();
|
private final Map<String, FileUploadInfo> fileUploadMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@ -95,13 +107,20 @@ public class FileChunkController {
|
||||||
log.info("分片文件md5校验失败,chunkMd5:{},md5:{}", chunkMd5, md5);
|
log.info("分片文件md5校验失败,chunkMd5:{},md5:{}", chunkMd5, md5);
|
||||||
throw new RuntimeException("分片文件md5校验失败");
|
throw new RuntimeException("分片文件md5校验失败");
|
||||||
}
|
}
|
||||||
|
QueryWrapper<Image> wrapper = new QueryWrapper<>();
|
||||||
|
wrapper.lambda().eq(Image::getImageName, fileName);
|
||||||
|
List<Image> imageList = imageMapper.selectList(wrapper);
|
||||||
|
if (CollectionUtil.isNotEmpty(imageList)) {
|
||||||
|
response.put("success", false);
|
||||||
|
response.put("status", "error");
|
||||||
|
response.put("message", "当前文件已经上传");
|
||||||
|
return ResponseEntity.status(200).body(response);
|
||||||
|
}
|
||||||
// 创建临时目录
|
// 创建临时目录
|
||||||
Path fileTempDir = Paths.get(tempDir, fileId);
|
Path fileTempDir = Paths.get(tempDir, fileId);
|
||||||
if (!Files.exists(fileTempDir)) {
|
if (!Files.exists(fileTempDir)) {
|
||||||
Files.createDirectories(fileTempDir);
|
Files.createDirectories(fileTempDir);
|
||||||
}
|
}
|
||||||
log.info("创建临时目录: {}", fileTempDir);
|
|
||||||
log.info("上传分片文件: {}", fileName);
|
|
||||||
// 保存分片文件
|
// 保存分片文件
|
||||||
String chunkFileName = String.format("%05d.part", chunkNumber);
|
String chunkFileName = String.format("%05d.part", chunkNumber);
|
||||||
log.info("保存分片文件: {}", chunkFileName);
|
log.info("保存分片文件: {}", chunkFileName);
|
||||||
|
@ -120,9 +139,8 @@ public class FileChunkController {
|
||||||
if (!Files.exists(finalDir)) {
|
if (!Files.exists(finalDir)) {
|
||||||
Files.createDirectories(finalDir);
|
Files.createDirectories(finalDir);
|
||||||
}
|
}
|
||||||
log.info("合并文件: {}", finalDir);
|
|
||||||
Path finalFilePath = finalDir.resolve(fileName);
|
Path finalFilePath = finalDir.resolve(fileName);
|
||||||
log.info("合并所有分片文件: {}", finalFilePath.getFileName());
|
log.info("合并所有分片文件: {}", finalFilePath);
|
||||||
mergeChunks(fileId, finalFilePath, totalChunks);
|
mergeChunks(fileId, finalFilePath, totalChunks);
|
||||||
|
|
||||||
// 清理临时文件
|
// 清理临时文件
|
||||||
|
@ -134,11 +152,41 @@ public class FileChunkController {
|
||||||
|
|
||||||
Image image = new Image();
|
Image image = new Image();
|
||||||
image.setImageName(fileName);
|
image.setImageName(fileName);
|
||||||
image.setStoragePath(uploadDir);
|
image.setStoragePath(String.valueOf(finalFilePath));
|
||||||
image.setImageStatus(1);
|
image.setImageStatus(1);
|
||||||
int insert = imageMapper.insert(image);
|
int insert = imageMapper.insert(image);
|
||||||
log.info("镜像新增insert:{}", insert);
|
log.info("镜像新增insert:{}", insert);
|
||||||
if (insert == 1) {
|
if (insert == 1) {
|
||||||
|
|
||||||
|
// 异步执行创建和做种操作
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
try {
|
||||||
|
String url = btUrl + "/test/start?sourceFile=%s&torrentFile=%s";
|
||||||
|
url = String.format(url, finalFilePath, finalFilePath + ".torrent");
|
||||||
|
log.info("请求bt创建接口参数: {}", url);
|
||||||
|
ResponseEntity<Boolean> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, Boolean.class);
|
||||||
|
log.info("请求bt创建接口返回: {}", JSONUtil.toJsonStr(responseEntity));
|
||||||
|
HttpStatus statusCode = responseEntity.getStatusCode();
|
||||||
|
if (statusCode != HttpStatus.OK) {
|
||||||
|
boolean result = Boolean.TRUE.equals(responseEntity.getBody());
|
||||||
|
if (result) {
|
||||||
|
log.info("请求bt创建接口成功");
|
||||||
|
QueryWrapper<Image> imageQueryWrapper = new QueryWrapper<>();
|
||||||
|
imageQueryWrapper.lambda().eq(Image::getImageName, fileName);
|
||||||
|
Image imageBt = imageMapper.selectOne(imageQueryWrapper);
|
||||||
|
if (ObjectUtils.isNotEmpty(imageBt)) {
|
||||||
|
imageBt.setBtPath(finalFilePath + ".torrent");
|
||||||
|
int update = imageMapper.updateById(imageBt);
|
||||||
|
log.info("镜像bt更新insert:{}", update);
|
||||||
|
} else {
|
||||||
|
log.info("镜像bt更新查询失败:{}", fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("请求bt创建接口失败: {}", e.getMessage(), e);
|
||||||
|
}
|
||||||
|
});
|
||||||
response.put("status", "completed");
|
response.put("status", "completed");
|
||||||
response.put("message", "文件上传并合并完成");
|
response.put("message", "文件上传并合并完成");
|
||||||
response.put("filePath", finalFilePath.toString());
|
response.put("filePath", finalFilePath.toString());
|
||||||
|
@ -159,8 +207,8 @@ public class FileChunkController {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
response.put("success", false);
|
response.put("success", false);
|
||||||
response.put("status", "error");
|
response.put("status", "error");
|
||||||
response.put("message", "上传失败: " + e.getMessage());
|
response.put("message", "上传失败");
|
||||||
log.info("上次失败清理临时文件: {}", fileId);
|
log.info("上次失败清理临时文件: {},error:{}", fileId, e.getMessage(), e);
|
||||||
try {
|
try {
|
||||||
cleanupTempFiles(fileId);
|
cleanupTempFiles(fileId);
|
||||||
cleanUploadFile(fileName);
|
cleanUploadFile(fileName);
|
||||||
|
@ -179,6 +227,8 @@ public class FileChunkController {
|
||||||
}
|
}
|
||||||
log.info("取消上传,清理临时文件: {}", fileId);
|
log.info("取消上传,清理临时文件: {}", fileId);
|
||||||
try {
|
try {
|
||||||
|
// 从上传映射中移除
|
||||||
|
fileUploadMap.remove(fileId);
|
||||||
cleanupTempFiles(fileId);
|
cleanupTempFiles(fileId);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
log.error("清理临时文件失败,fileId:{}, {}", fileId, ex.getMessage(), ex);
|
log.error("清理临时文件失败,fileId:{}, {}", fileId, ex.getMessage(), ex);
|
||||||
|
|
|
@ -2,21 +2,21 @@ package com.unisinsight.project.controller;
|
||||||
|
|
||||||
import com.unisinsight.project.util.BtTorrentUtils;
|
import com.unisinsight.project.util.BtTorrentUtils;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import java.io.*;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@RestController("test")
|
@RestController("test")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TestController {
|
public class TestController {
|
||||||
|
|
||||||
@GetMapping("/start")
|
@GetMapping("/start")
|
||||||
public String start(@RequestParam("sourceFile") String sourceFile,
|
public boolean start(@RequestParam("sourceFile") String sourceFile,
|
||||||
@RequestParam("torrentFile") String torrentFile) {
|
@RequestParam("torrentFile") String torrentFile) {
|
||||||
System.out.println("开始做种...");
|
System.out.println("开始做种...");
|
||||||
boolean seedResult = BtTorrentUtils.createAndSeed(sourceFile, torrentFile);
|
boolean seedResult = BtTorrentUtils.createAndSeed(sourceFile, torrentFile);
|
||||||
System.out.println("做种结果: " + (seedResult ? "成功" : "失败"));
|
System.out.println("做种结果: " + (seedResult ? "成功" : "失败"));
|
||||||
return "success";
|
return seedResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/stop")
|
@GetMapping("/stop")
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class Image implements Serializable {
|
||||||
private Integer imageType;
|
private Integer imageType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 镜像状态: 1-成功,2-失败
|
* 镜像状态: 1-成功,2-失败,3-做种中
|
||||||
*/
|
*/
|
||||||
@TableField(value = "image_status")
|
@TableField(value = "image_status")
|
||||||
private Integer imageStatus;
|
private Integer imageStatus;
|
||||||
|
|
|
@ -154,8 +154,10 @@ public class DeviceUserMappingServiceImpl extends ServiceImpl<DeviceUserMappingM
|
||||||
if (CollectionUtil.isEmpty(users)) {
|
if (CollectionUtil.isEmpty(users)) {
|
||||||
return Result.errorResultMessage(BaseErrorCode.PARAMS_CHK_ERROR, "用户不存在,请重试");
|
return Result.errorResultMessage(BaseErrorCode.PARAMS_CHK_ERROR, "用户不存在,请重试");
|
||||||
}
|
}
|
||||||
users = users.stream().distinct().collect(Collectors.toList());
|
users = users.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
|
||||||
|
if (CollectionUtil.isEmpty(users)) {
|
||||||
|
return Result.errorResultMessage(BaseErrorCode.PARAMS_CHK_ERROR, "用户不存在,请重试");
|
||||||
|
}
|
||||||
if (!users.get(0).getPassword().equals(deviceUserReq.getPassword())) {
|
if (!users.get(0).getPassword().equals(deviceUserReq.getPassword())) {
|
||||||
return Result.errorResultMessage(BaseErrorCode.PARAMS_CHK_ERROR, "密码错误,请重新输入");
|
return Result.errorResultMessage(BaseErrorCode.PARAMS_CHK_ERROR, "密码错误,请重新输入");
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,12 @@ import com.unisinsight.project.service.ImageService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -39,6 +44,14 @@ public class ImageServiceImpl extends ServiceImpl<ImageMapper, Image>
|
||||||
@Resource
|
@Resource
|
||||||
private ImageMapper imageMapper;
|
private ImageMapper imageMapper;
|
||||||
|
|
||||||
|
// 请求bt配置
|
||||||
|
@Value("${file.upload.bt-url}")
|
||||||
|
private String btUrl;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<?> selectPage(ImageReq imageReq) {
|
public Result<?> selectPage(ImageReq imageReq) {
|
||||||
Page<Image> page = new Page<>(imageReq.getPageNum(), imageReq.getPageSize());
|
Page<Image> page = new Page<>(imageReq.getPageNum(), imageReq.getPageSize());
|
||||||
|
@ -67,7 +80,23 @@ public class ImageServiceImpl extends ServiceImpl<ImageMapper, Image>
|
||||||
Image image = imageMapper.selectById(deleteIdReq.getId());
|
Image image = imageMapper.selectById(deleteIdReq.getId());
|
||||||
if (ObjectUtils.isNotEmpty(image)) {
|
if (ObjectUtils.isNotEmpty(image)) {
|
||||||
try {
|
try {
|
||||||
Path filePath = Paths.get(image.getStoragePath(), image.getImageName());
|
try {
|
||||||
|
String url = btUrl + "/test/stop?sourceFile=%s";
|
||||||
|
url = String.format(url, image.getStoragePath());
|
||||||
|
log.info("请求bt停止接口参数: {}", url);
|
||||||
|
ResponseEntity<Boolean> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, Boolean.class);
|
||||||
|
log.info("请求bt停止接口返回: {}", JSONUtil.toJsonStr(responseEntity));
|
||||||
|
HttpStatus statusCode = responseEntity.getStatusCode();
|
||||||
|
if (statusCode != HttpStatus.OK) {
|
||||||
|
boolean result = responseEntity.getBody();
|
||||||
|
if (result) {
|
||||||
|
log.info("请求bt停止接口成功");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("请求bt停止接口失败: {}", e.getMessage(), e);
|
||||||
|
}
|
||||||
|
Path filePath = Paths.get(image.getStoragePath());
|
||||||
if (Files.exists(filePath)) {
|
if (Files.exists(filePath)) {
|
||||||
// 删除文件
|
// 删除文件
|
||||||
Files.delete(filePath);
|
Files.delete(filePath);
|
||||||
|
|
Loading…
Reference in New Issue