add TempFileService
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,6 +2,7 @@
|
|||||||
/data
|
/data
|
||||||
/logs
|
/logs
|
||||||
/target
|
/target
|
||||||
|
/temp
|
||||||
|
|
||||||
multilingualField/
|
multilingualField/
|
||||||
!.mvn/wrapper/maven-wrapper.jar
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
|||||||
1
.idea/.gitignore
generated
vendored
1
.idea/.gitignore
generated
vendored
@ -2,3 +2,4 @@
|
|||||||
/shelf/
|
/shelf/
|
||||||
/workspace.xml
|
/workspace.xml
|
||||||
CopilotChatHistory.xml
|
CopilotChatHistory.xml
|
||||||
|
developer-tools.xml
|
||||||
@ -32,6 +32,8 @@ public enum SettingKey {
|
|||||||
/** 启用灰色滤镜 */
|
/** 启用灰色滤镜 */
|
||||||
ENABLE_GRAY_FILTER,
|
ENABLE_GRAY_FILTER,
|
||||||
|
|
||||||
|
TEMP_FILE_PATH,
|
||||||
|
|
||||||
// ---------- ICP 备案号 ----------
|
// ---------- ICP 备案号 ----------
|
||||||
|
|
||||||
ICP_IMYEYU_COM,
|
ICP_IMYEYU_COM,
|
||||||
@ -129,6 +131,16 @@ public enum SettingKey {
|
|||||||
|
|
||||||
MUSIC_CONTROLLER_URI,
|
MUSIC_CONTROLLER_URI,
|
||||||
|
|
||||||
|
// ---------- ----------
|
||||||
|
|
||||||
|
JOURNAL_KEY,
|
||||||
|
|
||||||
|
JOURNAL_APP_ID,
|
||||||
|
|
||||||
|
JOURNAL_APP_SECRET,
|
||||||
|
|
||||||
|
JOURNAL_TRAVEL,
|
||||||
|
|
||||||
// ---------- 系统 ----------
|
// ---------- 系统 ----------
|
||||||
|
|
||||||
SYSTEM_FILE_BASE,
|
SYSTEM_FILE_BASE,
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
package com.imyeyu.api.modules.common.bean;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 夜雨
|
||||||
|
* @since 2025-09-27 01:47
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TempFileMetaData {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String originalName;
|
||||||
|
|
||||||
|
private Path path;
|
||||||
|
|
||||||
|
private Long lastAccessAt;
|
||||||
|
}
|
||||||
@ -2,12 +2,6 @@ package com.imyeyu.api.modules.common.controller;
|
|||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import com.imyeyu.io.IO;
|
|
||||||
import com.imyeyu.java.TimiJava;
|
|
||||||
import com.imyeyu.java.bean.timi.TimiCode;
|
|
||||||
import com.imyeyu.java.bean.timi.TimiException;
|
|
||||||
import com.imyeyu.java.ref.Ref;
|
|
||||||
import com.imyeyu.network.Network;
|
|
||||||
import com.imyeyu.api.bean.CaptchaFrom;
|
import com.imyeyu.api.bean.CaptchaFrom;
|
||||||
import com.imyeyu.api.modules.common.bean.ImageType;
|
import com.imyeyu.api.modules.common.bean.ImageType;
|
||||||
import com.imyeyu.api.modules.common.bean.SettingKey;
|
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||||
@ -20,17 +14,26 @@ import com.imyeyu.api.modules.common.service.AttachmentService;
|
|||||||
import com.imyeyu.api.modules.common.service.FeedbackService;
|
import com.imyeyu.api.modules.common.service.FeedbackService;
|
||||||
import com.imyeyu.api.modules.common.service.SettingService;
|
import com.imyeyu.api.modules.common.service.SettingService;
|
||||||
import com.imyeyu.api.modules.common.service.TaskService;
|
import com.imyeyu.api.modules.common.service.TaskService;
|
||||||
|
import com.imyeyu.api.modules.common.service.TempFileService;
|
||||||
import com.imyeyu.api.modules.common.service.TemplateService;
|
import com.imyeyu.api.modules.common.service.TemplateService;
|
||||||
import com.imyeyu.api.modules.common.service.VersionService;
|
import com.imyeyu.api.modules.common.service.VersionService;
|
||||||
import com.imyeyu.api.modules.common.vo.FeedbackRequest;
|
import com.imyeyu.api.modules.common.vo.FeedbackRequest;
|
||||||
|
import com.imyeyu.api.modules.common.vo.TempFileResponse;
|
||||||
import com.imyeyu.api.modules.common.vo.attachment.AttachmentView;
|
import com.imyeyu.api.modules.common.vo.attachment.AttachmentView;
|
||||||
import com.imyeyu.api.modules.system.util.ResourceHandler;
|
import com.imyeyu.api.modules.system.util.ResourceHandler;
|
||||||
import com.imyeyu.api.util.CaptchaManager;
|
import com.imyeyu.api.util.CaptchaManager;
|
||||||
|
import com.imyeyu.io.IO;
|
||||||
|
import com.imyeyu.java.TimiJava;
|
||||||
|
import com.imyeyu.java.bean.timi.TimiCode;
|
||||||
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
|
import com.imyeyu.java.ref.Ref;
|
||||||
|
import com.imyeyu.network.Network;
|
||||||
import com.imyeyu.spring.TimiSpring;
|
import com.imyeyu.spring.TimiSpring;
|
||||||
import com.imyeyu.spring.annotation.AOPLog;
|
import com.imyeyu.spring.annotation.AOPLog;
|
||||||
import com.imyeyu.spring.annotation.IgnoreGlobalReturn;
|
import com.imyeyu.spring.annotation.IgnoreGlobalReturn;
|
||||||
import com.imyeyu.spring.annotation.RequestRateLimit;
|
import com.imyeyu.spring.annotation.RequestRateLimit;
|
||||||
import com.imyeyu.spring.bean.CaptchaData;
|
import com.imyeyu.spring.bean.CaptchaData;
|
||||||
|
import com.imyeyu.spring.bean.RequestRange;
|
||||||
import com.mongodb.client.gridfs.GridFSBucket;
|
import com.mongodb.client.gridfs.GridFSBucket;
|
||||||
import com.mongodb.client.gridfs.GridFSDownloadStream;
|
import com.mongodb.client.gridfs.GridFSDownloadStream;
|
||||||
import com.mongodb.client.gridfs.model.GridFSFile;
|
import com.mongodb.client.gridfs.model.GridFSFile;
|
||||||
@ -39,6 +42,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Cleanup;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.tika.Tika;
|
import org.apache.tika.Tika;
|
||||||
@ -51,6 +55,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.yaml.snakeyaml.Yaml;
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
@ -58,8 +63,12 @@ import java.awt.Graphics2D;
|
|||||||
import java.awt.RenderingHints;
|
import java.awt.RenderingHints;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -83,6 +92,7 @@ public class CommonController {
|
|||||||
private final SettingService settingService;
|
private final SettingService settingService;
|
||||||
private final FeedbackService feedbackService;
|
private final FeedbackService feedbackService;
|
||||||
private final TemplateService templateService;
|
private final TemplateService templateService;
|
||||||
|
private final TempFileService tempFileService;
|
||||||
private final AttachmentService attachmentService;
|
private final AttachmentService attachmentService;
|
||||||
|
|
||||||
private final Gson gson;
|
private final Gson gson;
|
||||||
@ -171,7 +181,7 @@ public class CommonController {
|
|||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@PostMapping("/feedback")
|
@PostMapping("/feedback")
|
||||||
public void createFeedback(@Valid @NotNull @RequestBody CaptchaData<FeedbackRequest> request) {
|
public void createFeedback(@Valid @NotNull @RequestBody CaptchaData<FeedbackRequest> request) {
|
||||||
captchaManager.test(request.getCaptcha(), request.getFrom());
|
captchaManager.test(request.getCaptcha(), request.getCaptchaId());
|
||||||
feedbackService.create(request.getData());
|
feedbackService.create(request.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,12 +260,6 @@ public class CommonController {
|
|||||||
return result.stream().collect(Collectors.toMap(Setting::getKey, Setting::getValue));
|
return result.stream().collect(Collectors.toMap(Setting::getKey, Setting::getValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestRateLimit
|
|
||||||
@GetMapping("/setting/flushCache")
|
|
||||||
public void settingFlushCache() {
|
|
||||||
settingService.flushCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
@AOPLog
|
@AOPLog
|
||||||
@RequestRateLimit
|
@RequestRateLimit
|
||||||
@GetMapping("/attachment/{mongoId}")
|
@GetMapping("/attachment/{mongoId}")
|
||||||
@ -264,7 +268,6 @@ public class CommonController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@AOPLog
|
@AOPLog
|
||||||
@RequestRateLimit
|
|
||||||
@IgnoreGlobalReturn
|
@IgnoreGlobalReturn
|
||||||
@GetMapping("/attachment/read/{mongoId}")
|
@GetMapping("/attachment/read/{mongoId}")
|
||||||
public void readAttachment(
|
public void readAttachment(
|
||||||
@ -372,4 +375,72 @@ public class CommonController {
|
|||||||
resp.setCharacterEncoding(StandardCharsets.UTF_8.toString());
|
resp.setCharacterEncoding(StandardCharsets.UTF_8.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AOPLog
|
||||||
|
@PostMapping("/temp/file/upload")
|
||||||
|
public List<TempFileResponse> uploadFile(@RequestParam("file") List<MultipartFile> files) {
|
||||||
|
return tempFileService.store(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AOPLog
|
||||||
|
@RequestRateLimit
|
||||||
|
@IgnoreGlobalReturn
|
||||||
|
@GetMapping("/temp/file/read/{fileId}")
|
||||||
|
public void tempFileRead(@PathVariable String fileId, HttpServletRequest req, HttpServletResponse resp) {
|
||||||
|
try {
|
||||||
|
File file = tempFileService.get(fileId);
|
||||||
|
if (TimiJava.isEmpty(file) && file.exists()) {
|
||||||
|
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Path filePath = file.toPath();
|
||||||
|
resp.setContentLengthLong(Files.size(filePath));
|
||||||
|
String mimeType = new Tika().detect(filePath);
|
||||||
|
if (TimiJava.isNotEmpty(mimeType)) {
|
||||||
|
resp.setContentType(mimeType);
|
||||||
|
}
|
||||||
|
req.setAttribute(ResourceHandler.ATTR_TYPE, ResourceHandler.Type.FILE);
|
||||||
|
req.setAttribute(ResourceHandler.ATTR_VALUE, filePath);
|
||||||
|
resourceHandler.handleRequest(req, resp);
|
||||||
|
} catch (Exception e) {
|
||||||
|
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@AOPLog
|
||||||
|
@RequestRateLimit
|
||||||
|
@IgnoreGlobalReturn
|
||||||
|
@RequestMapping("/temp/file/download/{fileId}")
|
||||||
|
public void tempFileDownload(@PathVariable String fileId, HttpServletResponse resp) {
|
||||||
|
try {
|
||||||
|
File file = tempFileService.get(fileId);
|
||||||
|
if (TimiJava.isEmpty(file) && file.exists()) {
|
||||||
|
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String mimeType = new Tika().detect(file);
|
||||||
|
resp.setContentType(mimeType);
|
||||||
|
resp.setHeader("Content-Disposition", Network.getFileDownloadHeader(file.getName()));
|
||||||
|
resp.setHeader("Accept-Ranges", "bytes");
|
||||||
|
|
||||||
|
RequestRange range = TimiSpring.requestRange(file.length());
|
||||||
|
if (range == null) {
|
||||||
|
// 完整文件
|
||||||
|
resp.setContentLengthLong(file.length());
|
||||||
|
resp.setStatus(HttpServletResponse.SC_OK);
|
||||||
|
IO.toOutputStream(resp.getOutputStream(), file);
|
||||||
|
} else {
|
||||||
|
// 分片文件
|
||||||
|
resp.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
|
||||||
|
resp.setHeader("Content-Range", "bytes %s-%s/%s".formatted(range.getStart(), range.getEnd(), file.length()));
|
||||||
|
resp.setContentLengthLong(range.getLength());
|
||||||
|
|
||||||
|
@Cleanup RandomAccessFile raf = new RandomAccessFile(file, "r");
|
||||||
|
raf.seek(range.getStart());
|
||||||
|
IO.toOutputStream(resp.getOutputStream(), raf, range.getStart(), range.getLength());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("download error", e);
|
||||||
|
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
package com.imyeyu.api.modules.common.service;
|
||||||
|
|
||||||
|
import com.imyeyu.api.modules.common.bean.TempFileMetaData;
|
||||||
|
import com.imyeyu.api.modules.common.vo.TempFileResponse;
|
||||||
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 夜雨
|
||||||
|
* @since 2025-09-27 01:35
|
||||||
|
*/
|
||||||
|
public interface TempFileService {
|
||||||
|
|
||||||
|
List<TempFileResponse> store(List<MultipartFile> files) throws TimiException;
|
||||||
|
|
||||||
|
File get(String id) throws TimiException;
|
||||||
|
|
||||||
|
TempFileMetaData metadata(String id) throws TimiException;
|
||||||
|
}
|
||||||
@ -0,0 +1,132 @@
|
|||||||
|
package com.imyeyu.api.modules.common.service.implement;
|
||||||
|
|
||||||
|
import com.imyeyu.api.modules.common.bean.SettingKey;
|
||||||
|
import com.imyeyu.api.modules.common.bean.TempFileMetaData;
|
||||||
|
import com.imyeyu.api.modules.common.service.AttachmentService;
|
||||||
|
import com.imyeyu.api.modules.common.service.SettingService;
|
||||||
|
import com.imyeyu.api.modules.common.service.TempFileService;
|
||||||
|
import com.imyeyu.api.modules.common.vo.TempFileResponse;
|
||||||
|
import com.imyeyu.io.IO;
|
||||||
|
import com.imyeyu.io.IOSize;
|
||||||
|
import com.imyeyu.java.TimiJava;
|
||||||
|
import com.imyeyu.java.bean.timi.TimiCode;
|
||||||
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
|
import com.imyeyu.network.Network;
|
||||||
|
import com.imyeyu.spring.TimiSpring;
|
||||||
|
import com.imyeyu.utils.Time;
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 夜雨
|
||||||
|
* @since 2025-09-27 01:47
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class TempFileServiceImplement implements TempFileService {
|
||||||
|
|
||||||
|
private static final Long TTL = Time.H * 6;
|
||||||
|
private static final Long LIMIT = IOSize.GB * 10;
|
||||||
|
|
||||||
|
private final SettingService settingService;
|
||||||
|
private final AttachmentService attachmentService;
|
||||||
|
|
||||||
|
private Path storagePath;
|
||||||
|
|
||||||
|
private final Map<String, TempFileMetaData> metadataMap = new ConcurrentHashMap<>();
|
||||||
|
private final Map<String, Long> usageMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() throws IOException {
|
||||||
|
storagePath = Paths.get(settingService.getAsString(SettingKey.TEMP_FILE_PATH));
|
||||||
|
IO.destroy(storagePath.toFile());
|
||||||
|
Files.createDirectories(storagePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TempFileResponse> store(List<MultipartFile> files) throws TimiException {
|
||||||
|
long newFileSize = files.stream().mapToLong(MultipartFile::getSize).sum();
|
||||||
|
long currentUsage = usageMap.getOrDefault(TimiSpring.getRequestIP(), 0L);
|
||||||
|
TimiException.requiredTrue(currentUsage + newFileSize < LIMIT, "out of storage limit(10 GB)");
|
||||||
|
|
||||||
|
try {
|
||||||
|
List<TempFileResponse> result = new ArrayList<>();
|
||||||
|
for (int i = 0; i < files.size(); i++) {
|
||||||
|
MultipartFile file = files.get(i);
|
||||||
|
|
||||||
|
String fileId = UUID.randomUUID().toString();
|
||||||
|
String fileName = fileId;
|
||||||
|
if (TimiJava.isNotEmpty(file.getOriginalFilename())) {
|
||||||
|
fileName = fileId + "." + Network.uriFileExtension(file.getOriginalFilename());
|
||||||
|
}
|
||||||
|
Path filePath = storagePath.resolve(fileName);
|
||||||
|
Files.copy(file.getInputStream(), filePath);
|
||||||
|
|
||||||
|
// 创建元数据
|
||||||
|
TempFileMetaData metadata = new TempFileMetaData();
|
||||||
|
metadata.setId(fileId);
|
||||||
|
metadata.setPath(filePath);
|
||||||
|
metadata.setName(fileName);
|
||||||
|
metadata.setOriginalName(file.getOriginalFilename());
|
||||||
|
metadata.setLastAccessAt(Time.now());
|
||||||
|
metadataMap.put(metadata.getId(), metadata);
|
||||||
|
|
||||||
|
TempFileResponse resp = new TempFileResponse();
|
||||||
|
resp.setId(metadata.getId());
|
||||||
|
resp.setExpireAt(metadata.getLastAccessAt() + TTL);
|
||||||
|
|
||||||
|
usageMap.put(TimiSpring.getRequestIP(), currentUsage + newFileSize);
|
||||||
|
result.add(resp);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("store temp file error", e);
|
||||||
|
throw new TimiException(TimiCode.ERROR, "store temp file error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File get(String id) throws TimiException {
|
||||||
|
TempFileMetaData metaData = metadataMap.get(id);
|
||||||
|
TimiException.required(metaData, "not found temp file");
|
||||||
|
metaData.setLastAccessAt(Time.now());
|
||||||
|
return metaData.getPath().toFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TempFileMetaData metadata(String id) throws TimiException {
|
||||||
|
return metadataMap.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scheduled(fixedRate = 3600000)
|
||||||
|
public void cleanup() {
|
||||||
|
List<String> expiredIds = metadataMap.values()
|
||||||
|
.stream()
|
||||||
|
.filter(metadata -> metadata.getLastAccessAt() + TTL < Time.now())
|
||||||
|
.map(TempFileMetaData::getId)
|
||||||
|
.toList();
|
||||||
|
for (int i = 0; i < expiredIds.size(); i++) {
|
||||||
|
TempFileMetaData removed = metadataMap.remove(expiredIds.get(i));
|
||||||
|
if (TimiJava.isNotEmpty(removed)) {
|
||||||
|
File file = removed.getPath().toFile();
|
||||||
|
IO.destroy(file);
|
||||||
|
usageMap.computeIfPresent(TimiSpring.getRequestIP(), (ip, usage) -> usage - file.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package com.imyeyu.api.modules.common.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 夜雨
|
||||||
|
* @since 2025-09-27 01:37
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TempFileResponse {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private Long expireAt;
|
||||||
|
}
|
||||||
@ -1,13 +1,13 @@
|
|||||||
package com.imyeyu.api.modules.system.controller;
|
package com.imyeyu.api.modules.system.controller;
|
||||||
|
|
||||||
import com.imyeyu.io.IO;
|
|
||||||
import com.imyeyu.java.bean.timi.TimiCode;
|
|
||||||
import com.imyeyu.java.bean.timi.TimiException;
|
|
||||||
import com.imyeyu.api.modules.common.service.AttachmentService;
|
import com.imyeyu.api.modules.common.service.AttachmentService;
|
||||||
import com.imyeyu.api.modules.common.vo.attachment.AttachmentRequest;
|
import com.imyeyu.api.modules.common.vo.attachment.AttachmentRequest;
|
||||||
import com.imyeyu.api.modules.system.bean.ServerStatus;
|
import com.imyeyu.api.modules.system.bean.ServerStatus;
|
||||||
import com.imyeyu.api.modules.system.service.SystemService;
|
import com.imyeyu.api.modules.system.service.SystemService;
|
||||||
import com.imyeyu.api.modules.system.vo.TempAttachRequest;
|
import com.imyeyu.api.modules.system.vo.TempAttachRequest;
|
||||||
|
import com.imyeyu.io.IO;
|
||||||
|
import com.imyeyu.java.bean.timi.TimiCode;
|
||||||
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
import com.imyeyu.spring.annotation.AOPLog;
|
import com.imyeyu.spring.annotation.AOPLog;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|||||||
Reference in New Issue
Block a user