package com.tourguide.modules.review.service;
|
|
import com.tourguide.common.exception.BusinessException;
|
import com.tourguide.config.properties.StorageProperties;
|
import org.springframework.stereotype.Service;
|
import org.springframework.web.multipart.MultipartFile;
|
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.nio.file.Files;
|
import java.nio.file.Path;
|
import java.nio.file.Paths;
|
import java.nio.file.StandardCopyOption;
|
import java.util.HashMap;
|
import java.util.Map;
|
import java.util.UUID;
|
|
@Service
|
public class ReviewImageStorageService {
|
private static final long MAX_FILE_SIZE = 5L * 1024 * 1024;
|
private static final Map<String, String> CONTENT_TYPE_EXTENSIONS = createContentTypeExtensions();
|
private final StorageProperties storageProperties;
|
|
public ReviewImageStorageService(StorageProperties storageProperties) {
|
this.storageProperties = storageProperties;
|
}
|
|
public String store(MultipartFile file) {
|
if (file == null || file.isEmpty()) {
|
throw new BusinessException(400, "请选择评价图片");
|
}
|
if (file.getSize() > MAX_FILE_SIZE) {
|
throw new BusinessException(400, "评价图片不能超过5MB");
|
}
|
String extension = CONTENT_TYPE_EXTENSIONS.get(file.getContentType());
|
if (extension == null) {
|
throw new BusinessException(400, "评价图片仅支持 JPG、PNG 或 WebP 格式");
|
}
|
|
Path directory = Paths.get(storageProperties.getReviewImageDirectory()).toAbsolutePath().normalize();
|
String filename = UUID.randomUUID().toString().replace("-", "") + extension;
|
Path target = directory.resolve(filename).normalize();
|
if (!target.startsWith(directory)) {
|
throw new BusinessException(400, "评价图片文件路径不合法");
|
}
|
try {
|
Files.createDirectories(directory);
|
try (InputStream inputStream = file.getInputStream()) {
|
Files.copy(inputStream, target, StandardCopyOption.REPLACE_EXISTING);
|
}
|
} catch (IOException exception) {
|
throw new BusinessException(500, "评价图片保存失败,请稍后重试");
|
}
|
return normalizePublicPath(storageProperties.getReviewImagePublicPath()) + "/" + filename;
|
}
|
|
private String normalizePublicPath(String publicPath) {
|
String normalized = publicPath == null ? "/uploads/review-images" : publicPath.trim();
|
if (!normalized.startsWith("/")) normalized = "/" + normalized;
|
while (normalized.endsWith("/")) normalized = normalized.substring(0, normalized.length() - 1);
|
return normalized;
|
}
|
|
private static Map<String, String> createContentTypeExtensions() {
|
Map<String, String> extensions = new HashMap<String, String>();
|
extensions.put("image/jpeg", ".jpg");
|
extensions.put("image/png", ".png");
|
extensions.put("image/webp", ".webp");
|
return extensions;
|
}
|
}
|