移除文件管理与文件分享,接口范围收敛到订阅与用户管理
- 删除 /personal/files、uploadFile、private/**、compress、delete 与对应服务实现,
连同压缩线程池、TAR 打包与 PersonalArchiveTest
- 删除 /personal/share、extendShareTime、cancelShare 与 /GetFile/{path},
以及 ShareFile 实体、ShareFileMapper、PublicService.GetFile、每天四点的
checkShareCode 定时任务和分享码失败黑名单
- CustomBean 去掉 ShareFile 的 Native 反射登记
- 同步收敛 PersonalServiceTest、PublicServiceTest、PersonalControllerTest、
PublicControllerTest、LocalServiceTest 与三个画廊测试
- 文档同步,并附上 /login 方案 docs/login-command-plan.md
测试:mvn -o test 410 项通过
This commit is contained in:
@@ -22,7 +22,7 @@ import java.util.Random;
|
||||
@Configuration
|
||||
@RegisterReflectionForBinding(classes = {CustomConfiguration.class, GidToKey.class, ImageKeyCache.class,
|
||||
GalleryForQuery.class, Gallery.class, GalleryTask.class, HikariConfig.class,
|
||||
PageNameCache.class, ShareFile.class, User.class,
|
||||
PageNameCache.class, User.class,
|
||||
SendResponse.class, Message.class, com.pengrad.telegrambot.model.User.class,
|
||||
Chat.class, MessageEntity.class,
|
||||
AbstractMethodError.class, DeleteGalleryMessage.class, DownloadPostMessage.class, DownloadStatusMessage.class,
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.lion.lionwebsite.Controller;
|
||||
import com.lion.lionwebsite.Service.LocalService;
|
||||
import com.lion.lionwebsite.Service.PersonalService;
|
||||
import com.lion.lionwebsite.Util.Response;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -11,7 +10,6 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -31,46 +29,6 @@ public class PersonalController {
|
||||
resp.sendRedirect("/index");
|
||||
}
|
||||
|
||||
@GetMapping("/files")
|
||||
public String file(String path){
|
||||
return personalService.getFiles(path);
|
||||
}
|
||||
|
||||
@PostMapping("/uploadFile")
|
||||
public String uploadFile(String path, String fileName, MultipartFile file){
|
||||
return personalService.uploadFile(path, fileName, file);
|
||||
}
|
||||
|
||||
@GetMapping("/private/**")
|
||||
public void getFile(HttpServletRequest request, HttpServletResponse response, String path){
|
||||
personalService.download(request, response, path);
|
||||
}
|
||||
|
||||
@PostMapping("/share")
|
||||
public String shareFile(String path, Integer expireHour) {
|
||||
return personalService.shareFile(path, expireHour);
|
||||
}
|
||||
|
||||
@PostMapping("/compress")
|
||||
public String compress(String path){
|
||||
return personalService.compress(path);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public String deleteFile(String path){
|
||||
return personalService.deleteFile(path);
|
||||
}
|
||||
|
||||
@PostMapping("/extendShareTime")
|
||||
public String extendShareTime(String path, Integer extendHour) {
|
||||
return personalService.extendShareTime(path, extendHour);
|
||||
}
|
||||
|
||||
@PostMapping("/cancelShare")
|
||||
public String cancelShare(String path){
|
||||
return personalService.cancelShare(path);
|
||||
}
|
||||
|
||||
@PostMapping("/updateSub")
|
||||
public String updateSub() throws IOException {
|
||||
Response response = Response.generateResponse();
|
||||
|
||||
@@ -16,16 +16,12 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class PublicController {
|
||||
|
||||
final List<String> black_share_codes = new LinkedList<>();
|
||||
|
||||
final PublicService publicService;
|
||||
|
||||
final RemoteService remoteService;
|
||||
@@ -60,24 +56,6 @@ public class PublicController {
|
||||
subService.updateSub(response, request, client, key);
|
||||
}
|
||||
|
||||
@GetMapping("/GetFile/{path}")
|
||||
public void getFile(HttpServletRequest request, HttpServletResponse response, String ShareCode, @PathVariable("path") String path) throws IOException {
|
||||
synchronized (black_share_codes) {
|
||||
if (black_share_codes.contains(ShareCode))
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("ShareCode:{}", ShareCode);
|
||||
log.info("Path:{}", path);
|
||||
boolean result = publicService.GetFile(request, response, ShareCode);
|
||||
|
||||
if(!result)
|
||||
black_share_codes.add(ShareCode);
|
||||
|
||||
if(black_share_codes.size() > 100)
|
||||
black_share_codes.removeFirst();
|
||||
}
|
||||
|
||||
@PostMapping("/validate")
|
||||
public String validate(String AuthCode){
|
||||
Response response = Response.generateResponse();
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.lion.lionwebsite.Dao.normal;
|
||||
|
||||
import com.lion.lionwebsite.Domain.ShareFile;
|
||||
import org.apache.ibatis.annotations.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
@Mapper
|
||||
public interface ShareFileMapper {
|
||||
@Insert("insert into ShareFile (ShareCode, FilePath, ExpireTime) values (#{ShareCode}, #{FilePath}, #{ExpireTime})")
|
||||
void insertShareFile(@Param("ShareCode")String ShareCode, @Param("FilePath")String FilePath, @Param("ExpireTime") Date ExpireTime);
|
||||
|
||||
@Select("select * from ShareFile where ShareCode=#{ShareCode}")
|
||||
ShareFile selectShareFileByShareCode(String ShareCode);
|
||||
|
||||
@Select("select * from ShareFile where FilePath=#{FilePath}")
|
||||
ShareFile selectShareFileByFilePath(String FilePath);
|
||||
|
||||
@Select("select * from ShareFile where FilePath like '%' || #{FilePath} || '%'")
|
||||
ArrayList<ShareFile> selectShareFilesByFilePath(String FilePath);
|
||||
|
||||
@Delete("delete from ShareFile where ShareCode=#{ShareCode}")
|
||||
void deleteShareFile(String ShareCode);
|
||||
|
||||
@Select("select * from ShareFile")
|
||||
ShareFile[] selectAllShareFile();
|
||||
|
||||
@Update("update ShareFile set ExpireTime=#{ExpireTime}, ShareCode=#{ShareCode} where FilePath=#{FilePath}")
|
||||
void updateShareFile(ShareFile ShareFile);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.lion.lionwebsite.Domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class ShareFile {
|
||||
String ShareCode;
|
||||
String FilePath;
|
||||
Date ExpireTime;
|
||||
}
|
||||
@@ -42,8 +42,6 @@ public class GalleryManageService {
|
||||
|
||||
final UserMapper userMapper;
|
||||
|
||||
final ShareFileMapper shareFileMapper;
|
||||
|
||||
final ImageCacheMapper imageCacheMapper;
|
||||
|
||||
final RemoteService remoteService;
|
||||
|
||||
@@ -2,9 +2,7 @@ package com.lion.lionwebsite.Service;
|
||||
|
||||
import com.lion.lionwebsite.Dao.normal.CustomConfigurationMapper;
|
||||
import com.lion.lionwebsite.Dao.normal.GalleryMapper;
|
||||
import com.lion.lionwebsite.Dao.normal.ShareFileMapper;
|
||||
import com.lion.lionwebsite.Domain.CustomConfiguration;
|
||||
import com.lion.lionwebsite.Domain.ShareFile;
|
||||
import com.lion.lionwebsite.Util.CustomUtil;
|
||||
import com.lion.lionwebsite.Util.GalleryUtil;
|
||||
import lombok.Data;
|
||||
@@ -45,8 +43,6 @@ public class LocalService{
|
||||
|
||||
final CustomConfigurationMapper configurationMapper;
|
||||
|
||||
final ShareFileMapper shareFileMapper;
|
||||
|
||||
final GalleryMapper galleryMapper;
|
||||
|
||||
final PushService pushService;
|
||||
@@ -150,23 +146,6 @@ public class LocalService{
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 每天四点,清理过期分享码
|
||||
*/
|
||||
@Scheduled(cron = "0 0 4 * * *")
|
||||
public void checkShareCode(){
|
||||
ShareFile[] shareFiles = shareFileMapper.selectAllShareFile();
|
||||
Calendar now;
|
||||
Calendar expireTime;
|
||||
for(ShareFile shareFile: shareFiles){
|
||||
now = Calendar.getInstance();
|
||||
expireTime = Calendar.getInstance();
|
||||
expireTime.setTime(shareFile.getExpireTime());
|
||||
if(now.after(expireTime))
|
||||
shareFileMapper.deleteShareFile(shareFile.getShareCode());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 每周,查看缩略图数量,按照访问时间排序,删除超出1w的部分
|
||||
*/
|
||||
|
||||
@@ -1,43 +1,17 @@
|
||||
package com.lion.lionwebsite.Service;
|
||||
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.lion.lionwebsite.Dao.normal.CustomConfigurationMapper;
|
||||
import com.lion.lionwebsite.Dao.normal.ShareFileMapper;
|
||||
import com.lion.lionwebsite.Dao.normal.UserMapper;
|
||||
import com.lion.lionwebsite.Domain.CustomConfiguration;
|
||||
import com.lion.lionwebsite.Domain.ShareFile;
|
||||
import com.lion.lionwebsite.Interceptor.TaskHandlerInterceptor;
|
||||
import com.lion.lionwebsite.Util.CustomUtil;
|
||||
import com.lion.lionwebsite.Util.FileDownload;
|
||||
import com.lion.lionwebsite.Util.Response;
|
||||
import tools.jackson.databind.ObjectMapper;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
|
||||
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Service
|
||||
@@ -46,221 +20,8 @@ import java.util.concurrent.Executors;
|
||||
public class PersonalService{
|
||||
final CustomConfigurationMapper configurationMapper;
|
||||
|
||||
final UserMapper userMapper;
|
||||
|
||||
final ShareFileMapper shareFileMapper;
|
||||
|
||||
final TaskHandlerInterceptor taskHandlerInterceptor;
|
||||
|
||||
String StoragePath = "/storage/";
|
||||
|
||||
DateTimeFormatter dateTimeFormatter = CustomUtil.dateTimeFormatter();
|
||||
|
||||
ExecutorService compressThreadPool = Executors.newFixedThreadPool(1);
|
||||
|
||||
final PushService pushService;
|
||||
|
||||
/**
|
||||
* 获取文件列表,同时带上分享码以及过期时间
|
||||
* @param path 路径
|
||||
* @return 文件列表
|
||||
*/
|
||||
public String getFiles(String path) {
|
||||
Response response = Response.generateResponse();
|
||||
path = URLDecoder.decode(path, StandardCharsets.UTF_8);
|
||||
File root_file = new File(StoragePath + path);
|
||||
Calendar now = Calendar.getInstance();
|
||||
Calendar expireTime = Calendar.getInstance();
|
||||
|
||||
//如果目标路径是文件夹
|
||||
if(root_file.isDirectory()) {
|
||||
ArrayList<Map<String, String>> fileMaps = new ArrayList<>();
|
||||
File[] originalFiles = root_file.listFiles();
|
||||
|
||||
//如果文件夹里的文件不为空
|
||||
if (originalFiles != null) {
|
||||
originalFiles = Arrays.stream(originalFiles).sorted(Comparator.comparing(File::getName)).toArray(File[]::new);
|
||||
ArrayList<ShareFile> shareFiles = shareFileMapper.selectShareFilesByFilePath(root_file.getAbsolutePath());
|
||||
|
||||
//遍历文件,放入文件信息以及查询对应的分享码
|
||||
for (File file : originalFiles) {
|
||||
Map<String, String> fileMap = new LinkedHashMap<>();
|
||||
fileMap.put("name", file.getName());
|
||||
fileMap.put("path", file.getAbsolutePath());
|
||||
|
||||
if (file.isDirectory()) {
|
||||
fileMap.put("type", "FOLDER");
|
||||
} else if (file.isFile()) {
|
||||
fileMap.put("type", "FILE"); //处理文件大小单位
|
||||
String fileSize = CustomUtil.fileSizeToString(file.length());
|
||||
fileMap.put("size", fileSize);
|
||||
|
||||
Iterator<ShareFile> iterator = shareFiles.iterator();
|
||||
while(iterator.hasNext()){
|
||||
ShareFile shareFile = iterator.next();
|
||||
if(shareFile.getFilePath().equals(file.getAbsolutePath())){
|
||||
expireTime.setTime(shareFile.getExpireTime());
|
||||
if(now.after(expireTime)){
|
||||
shareFileMapper.deleteShareFile(shareFile.getShareCode());
|
||||
}
|
||||
else {
|
||||
fileMap.put("shareCode", shareFile.getShareCode());
|
||||
fileMap.put("expireTime", dateTimeFormatter.format(shareFile.getExpireTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime()));
|
||||
}
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fileMaps.add(fileMap);
|
||||
}
|
||||
response.success(new ObjectMapper().valueToTree(fileMaps).toString());
|
||||
}
|
||||
else
|
||||
// listFiles() 只在 I/O 出错时返回 null(可读空目录返回长度为 0 的数组),
|
||||
// 报「文件夹为空」会掩盖权限/磁盘问题,这里如实提示。
|
||||
response.failure("读取文件夹失败");
|
||||
}
|
||||
return response.toJSONString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
* @param request 请求对象
|
||||
* @param response 响应对象
|
||||
* @param path 目标路径
|
||||
*/
|
||||
public void download(HttpServletRequest request, HttpServletResponse response, String path){
|
||||
path = URLDecoder.decode(path, StandardCharsets.UTF_8);
|
||||
File file = new File(path);
|
||||
if(file.exists())
|
||||
FileDownload.export(request, response, path);
|
||||
|
||||
else
|
||||
try{
|
||||
response.getWriter().print("404 NOT FOUND");
|
||||
}catch (IOException e){
|
||||
log.warn("输出404失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
* @param path 目标路径
|
||||
* @param fileName 文件名称
|
||||
* @param file 文件对象
|
||||
* @return 上传结果
|
||||
*/
|
||||
public String uploadFile(String path, String fileName, MultipartFile file) {
|
||||
Response response = Response.generateResponse();
|
||||
log.info("上传文件:{}, 目标路径:{}", fileName, path);
|
||||
|
||||
if(path == null || fileName == null || file == null){
|
||||
response.failure("参数不完整");
|
||||
return response.toJSONString();
|
||||
}
|
||||
|
||||
File directory = new File(StoragePath + path);
|
||||
if(directory.isDirectory()){
|
||||
File targetFile = new File(StoragePath + path, fileName);
|
||||
|
||||
if(targetFile.exists())
|
||||
response.failure("目标文件已存在");
|
||||
else
|
||||
try {
|
||||
file.transferTo(Path.of(StoragePath + path, fileName));
|
||||
response.success("上传成功");
|
||||
} catch (IOException e) {
|
||||
response.failure("上传失败");
|
||||
log.error("上传失败: {}", fileName, e);
|
||||
}
|
||||
}
|
||||
else
|
||||
response.failure("该路径不存在或者不是文件夹");
|
||||
|
||||
return response.toJSONString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建分享码
|
||||
* @param path 目标路径
|
||||
* @param expireHour 过期时间
|
||||
* @return 如果成功则是分享码以及过期时间,失败则是失败原因
|
||||
*/
|
||||
public String shareFile(String path, Integer expireHour) {
|
||||
Response response = Response.generateResponse();
|
||||
path = URLDecoder.decode(path, StandardCharsets.UTF_8);
|
||||
Map<String, String> jsonObject = new HashMap<>();
|
||||
File file = new File(path);
|
||||
if(file.isFile()){ //如果是文件,则生成分享码,调用此接口时不需要考虑分享已分享文件以及分享已过期文件
|
||||
String ShareCode;
|
||||
ShareCode = RandomUtil.randomString(8);
|
||||
Calendar expireTime = Calendar.getInstance();
|
||||
|
||||
expireTime.add(Calendar.HOUR, expireHour);
|
||||
shareFileMapper.insertShareFile(ShareCode, path, expireTime.getTime());
|
||||
jsonObject.put("shareCode", ShareCode);
|
||||
jsonObject.put("expireTime", dateTimeFormatter.format(expireTime.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime()));
|
||||
response.success(new ObjectMapper().valueToTree(jsonObject).toString());
|
||||
}
|
||||
else
|
||||
response.failure("此路径为文件夹或不存在");
|
||||
|
||||
return response.toJSONString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 延长分享时间
|
||||
* @param path 目标文件路径
|
||||
* @param extendHour 延长小时数
|
||||
* @return 延长结果
|
||||
*/
|
||||
public String extendShareTime(String path, Integer extendHour) {
|
||||
Response response = Response.generateResponse();
|
||||
path = URLDecoder.decode(path, StandardCharsets.UTF_8);
|
||||
Map<String, String> data = new LinkedHashMap<>();
|
||||
ShareFile shareFile = shareFileMapper.selectShareFileByFilePath(path);
|
||||
|
||||
if(shareFile != null){
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(shareFile.getExpireTime());
|
||||
|
||||
calendar.add(Calendar.HOUR, extendHour);
|
||||
shareFile.setExpireTime(calendar.getTime());
|
||||
shareFileMapper.updateShareFile(shareFile);
|
||||
data.put("expireTime", dateTimeFormatter.format(shareFile.getExpireTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime()));
|
||||
data.put("path", shareFile.getFilePath());
|
||||
|
||||
response.success(new ObjectMapper().valueToTree(data).toString());
|
||||
}
|
||||
else{
|
||||
response.failure("该文件未被分享");
|
||||
}
|
||||
|
||||
return response.toJSONString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消分享
|
||||
* @param path 目标路径
|
||||
* @return 取消结果
|
||||
*/
|
||||
public String cancelShare(String path) {
|
||||
Response response = Response.generateResponse();
|
||||
path = URLDecoder.decode(path, StandardCharsets.UTF_8);
|
||||
ShareFile shareFile = shareFileMapper.selectShareFileByFilePath(path);
|
||||
|
||||
if(shareFile != null){
|
||||
shareFileMapper.deleteShareFile(shareFile.getShareCode());
|
||||
response.success("取消分享成功");
|
||||
}
|
||||
else{
|
||||
response.failure("该文件未被分享");
|
||||
}
|
||||
|
||||
return response.toJSONString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订阅文件上次更新时间
|
||||
* @return 订阅文件上次更新时间
|
||||
@@ -289,90 +50,6 @@ public class PersonalService{
|
||||
return response.toJSONString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 打包文件
|
||||
* @param path 目标路径
|
||||
* @return 响应提交成功,因为该方法为异步执行,未完成时后辍为undone
|
||||
*/
|
||||
public String compress(String path) {
|
||||
Response response = Response.generateResponse();
|
||||
path = URLDecoder.decode(path, StandardCharsets.UTF_8);
|
||||
File file = new File(path);
|
||||
String finalPath = path;
|
||||
|
||||
if(!file.isDirectory() || !file.exists()){
|
||||
response.failure("选中的路径不是文件夹");
|
||||
return response.toJSONString();
|
||||
}
|
||||
|
||||
compressThreadPool.submit(() -> {
|
||||
Path temporary = Paths.get(finalPath + ".tar***undone");
|
||||
try {
|
||||
writeTar(Paths.get(finalPath), temporary);
|
||||
// writeTar closes the archive (including its trailer) before publication.
|
||||
try {
|
||||
Files.move(temporary, Paths.get(finalPath + ".tar"), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (AtomicMoveNotSupportedException e) {
|
||||
Files.move(temporary, Paths.get(finalPath + ".tar"), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
log.info("打包成功: {}.tar", finalPath);
|
||||
} catch (IOException e) {
|
||||
log.error("打包失败", e);
|
||||
} finally {
|
||||
try { Files.deleteIfExists(temporary); }
|
||||
catch (IOException e) { log.warn("清理打包临时文件失败", e); }
|
||||
}
|
||||
});
|
||||
response.success("加入队列成功");
|
||||
return response.toJSONString();
|
||||
}
|
||||
|
||||
static void writeTar(Path directory, Path output) throws IOException {
|
||||
try (OutputStream stream = new BufferedOutputStream(Files.newOutputStream(output));
|
||||
TarArchiveOutputStream archive = new TarArchiveOutputStream(stream)) {
|
||||
archive.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
|
||||
Files.walkFileTree(directory, new SimpleFileVisitor<>() {
|
||||
@Override public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attrs) throws IOException {
|
||||
if (!path.equals(directory)) {
|
||||
archive.putArchiveEntry(new TarArchiveEntry(path.toFile(), directory.relativize(path).toString()));
|
||||
archive.closeArchiveEntry();
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
@Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
|
||||
archive.putArchiveEntry(new TarArchiveEntry(path.toFile(), directory.relativize(path).toString()));
|
||||
try (InputStream input = Files.newInputStream(path)) {
|
||||
IOUtils.copy(input, archive);
|
||||
}
|
||||
archive.closeArchiveEntry();
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
* @param path 目标路径
|
||||
* @return 删除结果
|
||||
*/
|
||||
public String deleteFile(String path) {
|
||||
Response response = Response.generateResponse();
|
||||
path = URLDecoder.decode(path, StandardCharsets.UTF_8);
|
||||
File file = new File(path);
|
||||
|
||||
// hutool 的 FileUtil.del 对不存在的目标返回 true(幂等语义),
|
||||
// 直接据此报成功会让「路径写错/文件已不存在」也回「删除成功」,前端误以为已删除。
|
||||
if (!file.exists())
|
||||
response.failure("文件不存在");
|
||||
else if (FileUtil.del(file))
|
||||
response.success("删除成功");
|
||||
else
|
||||
response.failure("删除失败");
|
||||
|
||||
return response.toJSONString();
|
||||
}
|
||||
|
||||
public String message2me(String message){
|
||||
Response response = Response.generateResponse();
|
||||
pushService.sendToMe(message);
|
||||
|
||||
@@ -2,35 +2,23 @@ package com.lion.lionwebsite.Service;
|
||||
|
||||
import com.lion.lionwebsite.Dao.normal.CustomConfigurationMapper;
|
||||
|
||||
import com.lion.lionwebsite.Dao.normal.ShareFileMapper;
|
||||
import com.lion.lionwebsite.Dao.normal.UserMapper;
|
||||
import com.lion.lionwebsite.Domain.CustomConfiguration;
|
||||
import com.lion.lionwebsite.Domain.ShareFile;
|
||||
import com.lion.lionwebsite.Domain.User;
|
||||
import com.lion.lionwebsite.Interceptor.TaskHandlerInterceptor;
|
||||
import com.lion.lionwebsite.Util.CustomUtil;
|
||||
import com.lion.lionwebsite.Util.FileDownload;
|
||||
import com.lion.lionwebsite.Util.Response;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Calendar;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PublicService {
|
||||
|
||||
final CustomConfigurationMapper configurationMapper;
|
||||
|
||||
final ShareFileMapper shareFileMapper;
|
||||
|
||||
final UserMapper userMapper;
|
||||
|
||||
final TaskHandlerInterceptor taskHandlerInterceptor;
|
||||
@@ -44,41 +32,6 @@ public class PublicService {
|
||||
configurationMapper.updateConfiguration(CustomConfiguration.LAST_UPDATE_IP_ADDRESS_TIME, CustomUtil.now());
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过分享码获取文件
|
||||
* @param httpRequest 请求对象
|
||||
* @param httpResponse 响应对象
|
||||
* @param ShareCode 分享码
|
||||
* @throws IOException 响应时的异常
|
||||
*/
|
||||
public boolean GetFile(HttpServletRequest httpRequest, HttpServletResponse httpResponse, String ShareCode) throws IOException {
|
||||
Response response = Response.generateResponse();
|
||||
|
||||
//参数为空的情况
|
||||
if(ShareCode == null) {
|
||||
response.failure("ShareCode invalid");
|
||||
} else {
|
||||
ShareFile shareFile = shareFileMapper.selectShareFileByShareCode(ShareCode);
|
||||
Calendar ExpireTime = Calendar.getInstance();
|
||||
Calendar now = Calendar.getInstance();
|
||||
|
||||
if (shareFile != null) {
|
||||
ExpireTime.setTime(shareFile.getExpireTime());
|
||||
if (ExpireTime.after(now) && new File(shareFile.getFilePath()).isFile()) {
|
||||
FileDownload.export(httpRequest, httpResponse, shareFile.getFilePath());
|
||||
return true;
|
||||
} else {
|
||||
shareFileMapper.deleteShareFile(shareFile.getShareCode());
|
||||
response.failure("ShareCode is expired or File is not exist");
|
||||
}
|
||||
} else
|
||||
response.failure("ShareCode is not exist or expired");
|
||||
}
|
||||
|
||||
httpResponse.getOutputStream().write(response.toJSONString().getBytes(StandardCharsets.UTF_8));
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改授权码,如果能够执行此方法,则授权码一定存在
|
||||
* @param AuthCode 原来的授权码
|
||||
|
||||
Reference in New Issue
Block a user