Compare commits
3 Commits
e61da7d8f9
...
7a34a481aa
| Author | SHA1 | Date | |
|---|---|---|---|
| 7a34a481aa | |||
| a402ea86ef | |||
| 3eaa560aec |
@ -20,4 +20,7 @@ public class TempFileMetaData {
|
|||||||
private Path path;
|
private Path path;
|
||||||
|
|
||||||
private Long lastAccessAt;
|
private Long lastAccessAt;
|
||||||
|
|
||||||
|
/** 缓存时长(毫秒) */
|
||||||
|
private Long ttl;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -380,13 +380,14 @@ public class CommonController {
|
|||||||
/**
|
/**
|
||||||
* 上传临时文件
|
* 上传临时文件
|
||||||
*
|
*
|
||||||
* @param files
|
* @param files 文件列表
|
||||||
* @return
|
* @param ttl 缓存时长(毫秒),最长 3 天(259200000ms)
|
||||||
|
* @return 临时文件响应列表
|
||||||
*/
|
*/
|
||||||
@AOPLog
|
@AOPLog
|
||||||
@PostMapping("/temp/file/upload")
|
@PostMapping("/temp/file/upload")
|
||||||
public List<TempFileResponse> uploadFile(@RequestParam("file") List<MultipartFile> files) {
|
public List<TempFileResponse> tempFileUpload(@RequestParam("file") List<MultipartFile> files, @RequestParam("ttl") Long ttl) {
|
||||||
return tempFileService.store(files);
|
return tempFileService.store(files, ttl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public interface TempFileService {
|
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;
|
File get(String id) throws TimiException;
|
||||||
|
|
||||||
|
|||||||
@ -43,7 +43,8 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class TempFileServiceImplement implements TempFileService {
|
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 static final Long LIMIT = IOSize.GB * 10;
|
||||||
|
|
||||||
private final SettingService settingService;
|
private final SettingService settingService;
|
||||||
@ -61,7 +62,10 @@ public class TempFileServiceImplement implements TempFileService {
|
|||||||
Files.createDirectories(storagePath);
|
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 newFileSize = files.stream().mapToLong(MultipartFile::getSize).sum();
|
||||||
long currentUsage = usageMap.getOrDefault(TimiSpring.getRequestIP(), 0L);
|
long currentUsage = usageMap.getOrDefault(TimiSpring.getRequestIP(), 0L);
|
||||||
TimiException.requiredTrue(currentUsage + newFileSize < LIMIT, "out of storage limit(10 GB)");
|
TimiException.requiredTrue(currentUsage + newFileSize < LIMIT, "out of storage limit(10 GB)");
|
||||||
@ -86,11 +90,12 @@ public class TempFileServiceImplement implements TempFileService {
|
|||||||
metadata.setName(fileName);
|
metadata.setName(fileName);
|
||||||
metadata.setOriginalName(file.getOriginalFilename());
|
metadata.setOriginalName(file.getOriginalFilename());
|
||||||
metadata.setLastAccessAt(Time.now());
|
metadata.setLastAccessAt(Time.now());
|
||||||
|
metadata.setTtl(ttl);
|
||||||
metadataMap.put(metadata.getId(), metadata);
|
metadataMap.put(metadata.getId(), metadata);
|
||||||
|
|
||||||
TempFileResponse resp = new TempFileResponse();
|
TempFileResponse resp = new TempFileResponse();
|
||||||
resp.setId(metadata.getId());
|
resp.setId(metadata.getId());
|
||||||
resp.setExpireAt(metadata.getLastAccessAt() + TTL);
|
resp.setExpireAt(metadata.getLastAccessAt() + ttl);
|
||||||
|
|
||||||
usageMap.put(TimiSpring.getRequestIP(), currentUsage + newFileSize);
|
usageMap.put(TimiSpring.getRequestIP(), currentUsage + newFileSize);
|
||||||
result.add(resp);
|
result.add(resp);
|
||||||
@ -128,7 +133,7 @@ public class TempFileServiceImplement implements TempFileService {
|
|||||||
public void cleanup() {
|
public void cleanup() {
|
||||||
List<String> expiredIds = metadataMap.values()
|
List<String> expiredIds = metadataMap.values()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(metadata -> metadata.getLastAccessAt() + TTL < Time.now())
|
.filter(metadata -> metadata.getLastAccessAt() + metadata.getTtl() < Time.now())
|
||||||
.map(TempFileMetaData::getId)
|
.map(TempFileMetaData::getId)
|
||||||
.toList();
|
.toList();
|
||||||
for (int i = 0; i < expiredIds.size(); i++) {
|
for (int i = 0; i < expiredIds.size(); i++) {
|
||||||
|
|||||||
@ -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.entity.TravelLocation;
|
||||||
import com.imyeyu.api.modules.journal.mapper.TravelLocationMapper;
|
import com.imyeyu.api.modules.journal.mapper.TravelLocationMapper;
|
||||||
import com.imyeyu.api.modules.journal.service.TravelLocationService;
|
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.TimiJava;
|
||||||
import com.imyeyu.java.bean.timi.TimiException;
|
import com.imyeyu.java.bean.timi.TimiException;
|
||||||
import com.imyeyu.spring.mapper.BaseMapper;
|
import com.imyeyu.spring.mapper.BaseMapper;
|
||||||
import com.imyeyu.spring.service.AbstractEntityService;
|
import com.imyeyu.spring.service.AbstractEntityService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@ -30,9 +32,10 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
|
||||||
public class TravelLocationServiceImplement extends AbstractEntityService<TravelLocation, Long> implements TravelLocationService {
|
public class TravelLocationServiceImplement extends AbstractEntityService<TravelLocation, Long> implements TravelLocationService {
|
||||||
|
|
||||||
|
private final TravelService travelService;
|
||||||
private final TempFileService tempFileService;
|
private final TempFileService tempFileService;
|
||||||
private final AttachmentService attachmentService;
|
private final AttachmentService attachmentService;
|
||||||
|
|
||||||
@ -57,6 +60,8 @@ public class TravelLocationServiceImplement extends AbstractEntityService<Travel
|
|||||||
attach.setInputStream(tempFileService.getInputStream(tempFileId));
|
attach.setInputStream(tempFileService.getInputStream(tempFileId));
|
||||||
attachmentService.createMedia(attach);
|
attachmentService.createMedia(attach);
|
||||||
}
|
}
|
||||||
|
// 更新操作时间以保证排序
|
||||||
|
travelService.update(travelService.get(travelLocation.getTravelId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
@ -87,6 +92,8 @@ public class TravelLocationServiceImplement extends AbstractEntityService<Travel
|
|||||||
attach.setInputStream(tempFileService.getInputStream(tempFileId));
|
attach.setInputStream(tempFileService.getInputStream(tempFileId));
|
||||||
attachmentService.createMedia(attach);
|
attachmentService.createMedia(attach);
|
||||||
}
|
}
|
||||||
|
// 更新操作时间以保证排序
|
||||||
|
travelService.update(travelService.get(travelLocation.getTravelId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import com.imyeyu.spring.mapper.BaseMapper;
|
|||||||
import com.imyeyu.spring.service.AbstractEntityService;
|
import com.imyeyu.spring.service.AbstractEntityService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor(onConstructor_ = {@Lazy})
|
||||||
public class TravelServiceImplement extends AbstractEntityService<Travel, Long> implements TravelService {
|
public class TravelServiceImplement extends AbstractEntityService<Travel, Long> implements TravelService {
|
||||||
|
|
||||||
private final TravelMapper mapper;
|
private final TravelMapper mapper;
|
||||||
|
|||||||
Reference in New Issue
Block a user