Compare commits

...

3 Commits

Author SHA1 Message Date
7a34a481aa add ttl arg for tempFileUpload 2025-12-19 20:15:48 +08:00
a402ea86ef fix circular dependency 2025-12-19 19:47:45 +08:00
3eaa560aec sync travel updatedAt 2025-12-18 21:09:21 +08:00
6 changed files with 28 additions and 11 deletions

View File

@ -20,4 +20,7 @@ public class TempFileMetaData {
private Path path;
private Long lastAccessAt;
/** 缓存时长(毫秒) */
private Long ttl;
}

View File

@ -380,13 +380,14 @@ public class CommonController {
/**
* 上传临时文件
*
* @param files
* @return
* @param files 文件列表
* @param ttl 缓存时长(毫秒),最长 3 天259200000ms
* @return 临时文件响应列表
*/
@AOPLog
@PostMapping("/temp/file/upload")
public List<TempFileResponse> uploadFile(@RequestParam("file") List<MultipartFile> files) {
return tempFileService.store(files);
public List<TempFileResponse> tempFileUpload(@RequestParam("file") List<MultipartFile> files, @RequestParam("ttl") Long ttl) {
return tempFileService.store(files, ttl);
}
/**

View File

@ -15,7 +15,7 @@ import java.util.List;
*/
public interface TempFileService {
List<TempFileResponse> store(List<MultipartFile> files) throws TimiException;
List<TempFileResponse> store(List<MultipartFile> files, Long ttl) throws TimiException;
File get(String id) throws TimiException;

View File

@ -43,7 +43,8 @@ import java.util.concurrent.ConcurrentHashMap;
@RequiredArgsConstructor
public class TempFileServiceImplement implements TempFileService {
private static final Long TTL = Time.H * 6;
private static final Long DEFAULT_TTL = Time.H * 6;
private static final Long MAX_TTL = Time.D * 3;
private static final Long LIMIT = IOSize.GB * 10;
private final SettingService settingService;
@ -61,7 +62,10 @@ public class TempFileServiceImplement implements TempFileService {
Files.createDirectories(storagePath);
}
public List<TempFileResponse> store(List<MultipartFile> files) throws TimiException {
public List<TempFileResponse> store(List<MultipartFile> files, Long ttl) throws TimiException {
ttl = TimiJava.firstNotNull(ttl, DEFAULT_TTL);
TimiException.requiredTrue(0 < ttl && ttl <= MAX_TTL, "ttl must be between 1ms and 3 days(259200000ms)");
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)");
@ -86,11 +90,12 @@ public class TempFileServiceImplement implements TempFileService {
metadata.setName(fileName);
metadata.setOriginalName(file.getOriginalFilename());
metadata.setLastAccessAt(Time.now());
metadata.setTtl(ttl);
metadataMap.put(metadata.getId(), metadata);
TempFileResponse resp = new TempFileResponse();
resp.setId(metadata.getId());
resp.setExpireAt(metadata.getLastAccessAt() + TTL);
resp.setExpireAt(metadata.getLastAccessAt() + ttl);
usageMap.put(TimiSpring.getRequestIP(), currentUsage + newFileSize);
result.add(resp);
@ -128,7 +133,7 @@ public class TempFileServiceImplement implements TempFileService {
public void cleanup() {
List<String> expiredIds = metadataMap.values()
.stream()
.filter(metadata -> metadata.getLastAccessAt() + TTL < Time.now())
.filter(metadata -> metadata.getLastAccessAt() + metadata.getTtl() < Time.now())
.map(TempFileMetaData::getId)
.toList();
for (int i = 0; i < expiredIds.size(); i++) {

View File

@ -9,12 +9,14 @@ import com.imyeyu.api.modules.common.service.TempFileService;
import com.imyeyu.api.modules.journal.entity.TravelLocation;
import com.imyeyu.api.modules.journal.mapper.TravelLocationMapper;
import com.imyeyu.api.modules.journal.service.TravelLocationService;
import com.imyeyu.api.modules.journal.service.TravelService;
import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.spring.mapper.BaseMapper;
import com.imyeyu.spring.service.AbstractEntityService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -30,9 +32,10 @@ import java.util.stream.Collectors;
*/
@Slf4j
@Service
@RequiredArgsConstructor
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class TravelLocationServiceImplement extends AbstractEntityService<TravelLocation, Long> implements TravelLocationService {
private final TravelService travelService;
private final TempFileService tempFileService;
private final AttachmentService attachmentService;
@ -57,6 +60,8 @@ public class TravelLocationServiceImplement extends AbstractEntityService<Travel
attach.setInputStream(tempFileService.getInputStream(tempFileId));
attachmentService.createMedia(attach);
}
// 更新操作时间以保证排序
travelService.update(travelService.get(travelLocation.getTravelId()));
}
@Transactional(TimiServerDBConfig.ROLLBACKER)
@ -87,6 +92,8 @@ public class TravelLocationServiceImplement extends AbstractEntityService<Travel
attach.setInputStream(tempFileService.getInputStream(tempFileId));
attachmentService.createMedia(attach);
}
// 更新操作时间以保证排序
travelService.update(travelService.get(travelLocation.getTravelId()));
}
@Transactional(TimiServerDBConfig.ROLLBACKER)

View File

@ -9,6 +9,7 @@ import com.imyeyu.spring.mapper.BaseMapper;
import com.imyeyu.spring.service.AbstractEntityService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -20,7 +21,7 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Slf4j
@Service
@RequiredArgsConstructor
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
public class TravelServiceImplement extends AbstractEntityService<Travel, Long> implements TravelService {
private final TravelMapper mapper;