1
This commit is contained in:
44
src/main/java/com/aida/seller/util/DesensitizationUtil.java
Normal file
44
src/main/java/com/aida/seller/util/DesensitizationUtil.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package com.aida.seller.util;
|
||||
|
||||
import cn.hutool.core.util.DesensitizedUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
public class DesensitizationUtil {
|
||||
|
||||
private DesensitizationUtil() {}
|
||||
|
||||
public static String mobile(String mobile) {
|
||||
if (StrUtil.isBlank(mobile)) {
|
||||
return "";
|
||||
}
|
||||
return DesensitizedUtil.mobilePhone(mobile);
|
||||
}
|
||||
|
||||
public static String email(String email) {
|
||||
if (StrUtil.isBlank(email)) {
|
||||
return "";
|
||||
}
|
||||
return DesensitizedUtil.email(email);
|
||||
}
|
||||
|
||||
public static String idCard(String idCard) {
|
||||
if (StrUtil.isBlank(idCard)) {
|
||||
return "";
|
||||
}
|
||||
return DesensitizedUtil.idCardNum(idCard, 4, 4);
|
||||
}
|
||||
|
||||
public static String bankCard(String bankCard) {
|
||||
if (StrUtil.isBlank(bankCard)) {
|
||||
return "";
|
||||
}
|
||||
return DesensitizedUtil.bankCard(bankCard);
|
||||
}
|
||||
|
||||
public static String chineseName(String name) {
|
||||
if (StrUtil.isBlank(name)) {
|
||||
return "";
|
||||
}
|
||||
return DesensitizedUtil.chineseName(name);
|
||||
}
|
||||
}
|
||||
99
src/main/java/com/aida/seller/util/JwtUtil.java
Normal file
99
src/main/java/com/aida/seller/util/JwtUtil.java
Normal file
@@ -0,0 +1,99 @@
|
||||
package com.aida.seller.util;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.aida.seller.config.JwtConfig;
|
||||
import io.jsonwebtoken.*;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class JwtUtil {
|
||||
|
||||
private final JwtConfig jwtConfig;
|
||||
|
||||
private SecretKey getSecretKey() {
|
||||
return Keys.hmacShaKeyFor(jwtConfig.getSecret().getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
public String generateToken(Long userId, String username) {
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
claims.put("userId", userId);
|
||||
claims.put("username", username);
|
||||
return createToken(claims, username);
|
||||
}
|
||||
|
||||
public String generateToken(Long userId, String username, Map<String, Object> additionalClaims) {
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
claims.put("userId", userId);
|
||||
claims.put("username", username);
|
||||
if (additionalClaims != null) {
|
||||
claims.putAll(additionalClaims);
|
||||
}
|
||||
return createToken(claims, username);
|
||||
}
|
||||
|
||||
private String createToken(Map<String, Object> claims, String subject) {
|
||||
return Jwts.builder()
|
||||
.claims(claims)
|
||||
.subject(subject)
|
||||
.issuedAt(new Date())
|
||||
.expiration(new Date(System.currentTimeMillis() + jwtConfig.getExpiration()))
|
||||
.signWith(getSecretKey())
|
||||
.compact();
|
||||
}
|
||||
|
||||
public Claims parseToken(String token) {
|
||||
return Jwts.parser()
|
||||
.verifyWith(getSecretKey())
|
||||
.build()
|
||||
.parseSignedClaims(token)
|
||||
.getPayload();
|
||||
}
|
||||
|
||||
public String getUsernameFromToken(String token) {
|
||||
Claims claims = parseToken(token);
|
||||
return claims.getSubject();
|
||||
}
|
||||
|
||||
public Long getUserIdFromToken(String token) {
|
||||
Claims claims = parseToken(token);
|
||||
return claims.get("userId", Long.class);
|
||||
}
|
||||
|
||||
public boolean isTokenExpired(String token) {
|
||||
try {
|
||||
Claims claims = parseToken(token);
|
||||
return claims.getExpiration().before(new Date());
|
||||
} catch (ExpiredJwtException e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean validateToken(String token) {
|
||||
if (StrUtil.isBlank(token)) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
parseToken(token);
|
||||
return true;
|
||||
} catch (JwtException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String refreshToken(String token) {
|
||||
Claims claims = parseToken(token);
|
||||
String username = claims.getSubject();
|
||||
Long userId = claims.get("userId", Long.class);
|
||||
return generateToken(userId, username);
|
||||
}
|
||||
}
|
||||
460
src/main/java/com/aida/seller/util/MinioUtil.java
Normal file
460
src/main/java/com/aida/seller/util/MinioUtil.java
Normal file
@@ -0,0 +1,460 @@
|
||||
package com.aida.seller.util;
|
||||
|
||||
import com.aida.seller.common.constants.MinioFileConstants;
|
||||
import com.aida.seller.common.exception.MinioException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.minio.*;
|
||||
import io.minio.http.Method;
|
||||
import io.minio.messages.DeleteError;
|
||||
import io.minio.messages.DeleteObject;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class MinioUtil {
|
||||
|
||||
@Autowired
|
||||
private MinioClient minioClient;
|
||||
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
private static final String REDIS_MINIO_URL_PREFIX = "minio:url:";
|
||||
private static final long URL_CACHE_EXPIRE_SECONDS = 24 * 60 * 60;
|
||||
|
||||
@Value("${minio.default-bucket}")
|
||||
private String defaultBucketName;
|
||||
|
||||
@Value("${minio.endpoint}")
|
||||
private String endpoint;
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
public String uploadImage(MultipartFile file, String bucketName, String userId) {
|
||||
try {
|
||||
if (bucketName == null || bucketName.isEmpty()) {
|
||||
bucketName = defaultBucketName;
|
||||
}
|
||||
|
||||
if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
|
||||
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
|
||||
}
|
||||
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
|
||||
String fileName = UUID.randomUUID().toString() + fileExtension;
|
||||
String filePath = (userId != null && !userId.isEmpty()) ? userId + "/" + fileName : fileName;
|
||||
|
||||
minioClient.putObject(PutObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(filePath)
|
||||
.stream(file.getInputStream(), file.getSize(), -1)
|
||||
.contentType(file.getContentType())
|
||||
.build());
|
||||
|
||||
log.info("文件上传成功,桶名: {}, 文件路径: {}", bucketName, filePath);
|
||||
return bucketName + "/" + filePath;
|
||||
} catch (Exception e) {
|
||||
log.error("文件上传失败: {}", e.getMessage(), e);
|
||||
throw new MinioException("文件上传失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public String uploadImage(MultipartFile file, String userId) {
|
||||
return uploadImage(file, null, userId);
|
||||
}
|
||||
|
||||
public String uploadImage(MultipartFile file) {
|
||||
return uploadImage(file, null, null);
|
||||
}
|
||||
|
||||
public String getImageUrl(String path, int expires) {
|
||||
if (!path.contains("/")) {
|
||||
}
|
||||
int index = path.indexOf("/");
|
||||
String bucketName = path.substring(0, index);
|
||||
String fileName = path.substring(index + 1);
|
||||
return getImageUrl(bucketName, fileName, expires);
|
||||
}
|
||||
|
||||
public String getImageUrl(String bucketName, String filePath, int expires) {
|
||||
String cacheKey = REDIS_MINIO_URL_PREFIX + bucketName + "/" + filePath;
|
||||
Object cachedUrl = redisUtil.get(cacheKey);
|
||||
if (cachedUrl != null) {
|
||||
return cachedUrl.toString();
|
||||
}
|
||||
|
||||
try {
|
||||
String url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
|
||||
.method(Method.GET)
|
||||
.bucket(bucketName)
|
||||
.object(filePath)
|
||||
.expiry(expires)
|
||||
.build());
|
||||
|
||||
redisUtil.setWithExpire(cacheKey, url, URL_CACHE_EXPIRE_SECONDS);
|
||||
return url;
|
||||
} catch (Exception e) {
|
||||
log.error("获取临时访问地址失败: {}", e.getMessage(), e);
|
||||
throw new MinioException("获取临时访问地址失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getImageUrl(String bucketName, String filePath) {
|
||||
return getImageUrl(bucketName, filePath, 7 * 24 * 60 * 60);
|
||||
}
|
||||
|
||||
public void deleteImage(String objectPath) {
|
||||
try {
|
||||
int index = objectPath.indexOf("/");
|
||||
if (index == -1) {
|
||||
throw new MinioException("无效的对象路径,格式应为 bucketName/filePath");
|
||||
}
|
||||
String bucketName = objectPath.substring(0, index);
|
||||
String filePath = objectPath.substring(index + 1);
|
||||
|
||||
minioClient.removeObject(RemoveObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(filePath)
|
||||
.build());
|
||||
|
||||
log.info("文件删除成功,桶名: {}, 文件路径: {}", bucketName, filePath);
|
||||
} catch (Exception e) {
|
||||
log.error("文件删除失败: {}", e.getMessage(), e);
|
||||
throw new MinioException("文件删除失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteImages(List<String> objectPaths) {
|
||||
if (objectPaths == null || objectPaths.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
String firstPath = objectPaths.get(0);
|
||||
int index = firstPath.indexOf("/");
|
||||
if (index == -1) {
|
||||
throw new MinioException("无效的对象路径,格式应为 bucketName/filePath");
|
||||
}
|
||||
String bucketName = firstPath.substring(0, index);
|
||||
|
||||
List<DeleteObject> deleteObjects = new ArrayList<>();
|
||||
for (String objectPath : objectPaths) {
|
||||
int sepIndex = objectPath.indexOf("/");
|
||||
if (sepIndex != -1) {
|
||||
String filePath = objectPath.substring(sepIndex + 1);
|
||||
deleteObjects.add(new DeleteObject(filePath));
|
||||
}
|
||||
}
|
||||
|
||||
Iterable<Result<DeleteError>> results = minioClient.removeObjects(RemoveObjectsArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.objects(deleteObjects)
|
||||
.build());
|
||||
|
||||
for (Result<DeleteError> result : results) {
|
||||
DeleteError error = result.get();
|
||||
log.error("文件删除失败,桶名: {}, 文件路径: {}, 错误信息: {}", bucketName, error.objectName(), error.message());
|
||||
}
|
||||
|
||||
log.info("批量删除文件成功,桶名: {}, 文件数量: {}", bucketName, objectPaths.size());
|
||||
} catch (Exception e) {
|
||||
log.error("批量删除文件失败: {}", e.getMessage(), e);
|
||||
throw new MinioException("批量删除文件失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public String uploadBase64Image(String base64Image, String bucketName, String filePath) {
|
||||
try {
|
||||
String[] base64Parts = base64Image.split(",");
|
||||
String imageData = base64Parts[1];
|
||||
String contentType = base64Parts[0].split(":")[1].split(";")[0];
|
||||
|
||||
byte[] imageBytes = java.util.Base64.getDecoder().decode(imageData);
|
||||
|
||||
if (bucketName == null || bucketName.isEmpty()) {
|
||||
bucketName = defaultBucketName;
|
||||
}
|
||||
|
||||
if (filePath == null || filePath.isEmpty()) {
|
||||
String fileExtension = contentType.split("/")[1];
|
||||
filePath = UUID.randomUUID().toString() + "." + fileExtension;
|
||||
}
|
||||
|
||||
return uploadImage(imageBytes, bucketName, filePath, contentType);
|
||||
} catch (Exception e) {
|
||||
log.error("base64图片上传失败: {}", e.getMessage(), e);
|
||||
throw new MinioException("base64图片上传失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public String uploadBase64Image(String base64Image, String bucketName) {
|
||||
return uploadBase64Image(base64Image, bucketName, null);
|
||||
}
|
||||
|
||||
public String uploadBase64Image(String base64Image) {
|
||||
return uploadBase64Image(base64Image, null, null);
|
||||
}
|
||||
|
||||
private String uploadImage(byte[] bytes, String bucketName, String filePath, String contentType) {
|
||||
try {
|
||||
if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
|
||||
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
|
||||
}
|
||||
|
||||
minioClient.putObject(PutObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(filePath)
|
||||
.stream(new ByteArrayInputStream(bytes), bytes.length, -1)
|
||||
.contentType(contentType)
|
||||
.build());
|
||||
|
||||
return bucketName + "/" + filePath;
|
||||
} catch (Exception e) {
|
||||
log.error("文件上传失败: {}", e.getMessage(), e);
|
||||
throw new MinioException("文件上传失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public String uploadBytes(byte[] bytes, MinioFileConstants.FileType fileType, String contentType, String bucketName) {
|
||||
String objectName = MinioFileConstants.generateObjectNameByType(fileType);
|
||||
return uploadBytes(bytes, objectName, contentType, bucketName);
|
||||
}
|
||||
|
||||
public String uploadBytes(byte[] bytes, String objectName, String contentType, String bucketName) {
|
||||
if (bytes == null || bytes.length == 0) {
|
||||
throw new MinioException("文件内容不能为空");
|
||||
}
|
||||
|
||||
try {
|
||||
minioClient.putObject(
|
||||
PutObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(objectName)
|
||||
.stream(new ByteArrayInputStream(bytes), bytes.length, -1)
|
||||
.contentType(contentType)
|
||||
.build()
|
||||
);
|
||||
|
||||
log.info("字节数组上传成功: {}/{}", bucketName, objectName);
|
||||
return bucketName + "/" + objectName;
|
||||
} catch (Exception e) {
|
||||
log.error("字节数组上传失败: {}", e.getMessage(), e);
|
||||
throw new MinioException("字节数组上传失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public InputStream downloadFile(String logicalPath) {
|
||||
int index = logicalPath.indexOf("/");
|
||||
if (index <= 0) {
|
||||
throw new MinioException("逻辑路径格式错误,应包含桶名: " + logicalPath);
|
||||
}
|
||||
|
||||
String bucketName = logicalPath.substring(0, index);
|
||||
String objectName = logicalPath.substring(index + 1);
|
||||
|
||||
try {
|
||||
boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
|
||||
if (!bucketExists) {
|
||||
throw new MinioException("桶不存在: " + bucketName);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("验证桶存在性失败: {}", e.getMessage(), e);
|
||||
throw new MinioException("验证桶存在性失败bucketName:{}", bucketName);
|
||||
}
|
||||
|
||||
try {
|
||||
return minioClient.getObject(
|
||||
GetObjectArgs.builder()
|
||||
.bucket(bucketName)
|
||||
.object(objectName)
|
||||
.build()
|
||||
);
|
||||
} catch (Exception e) {
|
||||
log.error("文件下载失败: {}", e.getMessage(), e);
|
||||
throw new MinioException("文件下载失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getLogicalPathFromPresignedUrl(String presignedUrl) {
|
||||
try {
|
||||
URL url = new URL(presignedUrl);
|
||||
|
||||
String path = url.getPath();
|
||||
if (path.startsWith("/")) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
|
||||
int firstSlashIndex = path.indexOf("/");
|
||||
if (firstSlashIndex <= 0) {
|
||||
throw new MinioException("预签名URL路径格式无效,应包含桶名和对象名: " + presignedUrl);
|
||||
}
|
||||
|
||||
String bucketName = path.substring(0, firstSlashIndex);
|
||||
String objectName = path.substring(firstSlashIndex + 1);
|
||||
|
||||
return bucketName + "/" + objectName;
|
||||
} catch (Exception e) {
|
||||
log.error("预签名URL解析失败: {}", e.getMessage(), e);
|
||||
throw new MinioException("预签名URL解析失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPresignedUrl(String str) {
|
||||
if (str == null || str.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
URL url = new URL(str);
|
||||
String host = url.getHost();
|
||||
String endpointHost = endpoint;
|
||||
if (endpointHost.startsWith("http://")) {
|
||||
endpointHost = endpointHost.substring(7);
|
||||
} else if (endpointHost.startsWith("https://")) {
|
||||
endpointHost = endpointHost.substring(8);
|
||||
}
|
||||
if (endpointHost.contains(":")) {
|
||||
endpointHost = endpointHost.substring(0, endpointHost.indexOf(":"));
|
||||
}
|
||||
return host.equals(endpointHost);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isMinioLogicalPath(String str) {
|
||||
if (str == null || str.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (!(str instanceof String)) {
|
||||
return false;
|
||||
}
|
||||
String trimStr = str.trim();
|
||||
if (trimStr.startsWith("http://") || trimStr.startsWith("https://")) {
|
||||
return false;
|
||||
}
|
||||
if (!trimStr.contains("/")) {
|
||||
return false;
|
||||
}
|
||||
if (trimStr.contains(" ") || trimStr.contains("\n") || trimStr.contains("\t")) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isMinioResource(String str) {
|
||||
return isPresignedUrl(str) || isMinioLogicalPath(str);
|
||||
}
|
||||
|
||||
public String processJsonPresignedUrls(String jsonString, int expires) {
|
||||
if (jsonString == null || jsonString.isEmpty()) {
|
||||
return jsonString;
|
||||
}
|
||||
|
||||
try {
|
||||
JsonNode rootNode = objectMapper.readTree(jsonString);
|
||||
JsonNode processedNode = processNode(rootNode, expires);
|
||||
return objectMapper.writeValueAsString(processedNode);
|
||||
} catch (Exception e) {
|
||||
log.error("处理JSON中的预签名URL失败: {}", e.getMessage(), e);
|
||||
return jsonString;
|
||||
}
|
||||
}
|
||||
|
||||
private JsonNode processNode(JsonNode node, int expires) {
|
||||
if (node.isObject()) {
|
||||
ObjectNode objectNode = (ObjectNode) node;
|
||||
Iterator<Map.Entry<String, JsonNode>> fields = objectNode.fields();
|
||||
while (fields.hasNext()) {
|
||||
Map.Entry<String, JsonNode> field = fields.next();
|
||||
JsonNode value = field.getValue();
|
||||
if (value.isTextual()) {
|
||||
String text = value.asText();
|
||||
if (isMinioResource(text)) {
|
||||
String newUrl = processMinioResource(text, expires);
|
||||
objectNode.put(field.getKey(), newUrl);
|
||||
}
|
||||
} else if (!value.isNull()) {
|
||||
JsonNode processedValue = processNode(value, expires);
|
||||
objectNode.set(field.getKey(), processedValue);
|
||||
}
|
||||
}
|
||||
return objectNode;
|
||||
} else if (node.isArray()) {
|
||||
ArrayNode arrayNode = (ArrayNode) node;
|
||||
for (int i = 0; i < arrayNode.size(); i++) {
|
||||
JsonNode element = arrayNode.get(i);
|
||||
if (element.isTextual()) {
|
||||
String text = element.asText();
|
||||
if (isMinioResource(text)) {
|
||||
String newUrl = processMinioResource(text, expires);
|
||||
arrayNode.set(i, newUrl);
|
||||
}
|
||||
} else if (!element.isNull()) {
|
||||
JsonNode processedElement = processNode(element, expires);
|
||||
arrayNode.set(i, processedElement);
|
||||
}
|
||||
}
|
||||
return arrayNode;
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
public String processMinioResource(String resource, int expires) {
|
||||
try {
|
||||
String logicalPath;
|
||||
if (isPresignedUrl(resource)) {
|
||||
logicalPath = getLogicalPathFromPresignedUrl(resource);
|
||||
} else if (isMinioLogicalPath(resource)) {
|
||||
logicalPath = resource.trim();
|
||||
} else {
|
||||
log.warn("未识别的MinIO资源格式: {}", resource);
|
||||
return resource;
|
||||
}
|
||||
|
||||
return getImageUrl(logicalPath, expires);
|
||||
} catch (Exception e) {
|
||||
log.error("处理MinIO资源失败: {}, error: {}", resource, e.getMessage(), e);
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
|
||||
public String convertToLogicalPath(String url) {
|
||||
if (url == null || url.isEmpty()) {
|
||||
throw new MinioException("URL不能为空");
|
||||
}
|
||||
if (isMinioLogicalPath(url)) {
|
||||
return url.trim();
|
||||
} else if (isPresignedUrl(url)) {
|
||||
return getLogicalPathFromPresignedUrl(url);
|
||||
} else {
|
||||
throw new MinioException("无法识别的MinIO资源格式: " + url + ",请提供有效的预签名URL或逻辑路径");
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteImagesByUrls(Collection<String> urls) {
|
||||
if (urls == null || urls.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (String url : urls) {
|
||||
String logicalPath = convertToLogicalPath(url);
|
||||
deleteImage(logicalPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
203
src/main/java/com/aida/seller/util/RedisUtil.java
Normal file
203
src/main/java/com/aida/seller/util/RedisUtil.java
Normal file
@@ -0,0 +1,203 @@
|
||||
package com.aida.seller.util;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class RedisUtil {
|
||||
|
||||
private final RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
public void set(String key, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis set error, key: {}, error: {}", key, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void set(String key, Object value, long timeout, TimeUnit unit) {
|
||||
try {
|
||||
redisTemplate.opsForValue().set(key, value, timeout, unit);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis set with expiry error, key: {}, error: {}", key, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void setWithExpire(String key, Object value, long seconds) {
|
||||
set(key, value, seconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public Object get(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForValue().get(key);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis get error, key: {}, error: {}", key, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T get(String key, Class<T> type) {
|
||||
try {
|
||||
Object value = redisTemplate.opsForValue().get(key);
|
||||
if (value != null && type.isInstance(value)) {
|
||||
return (T) value;
|
||||
}
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
log.error("Redis get with type error, key: {}, error: {}", key, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Long increment(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForValue().increment(key);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis increment error, key: {}, error: {}", key, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Long increment(String key, long delta) {
|
||||
try {
|
||||
return redisTemplate.opsForValue().increment(key, delta);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis increment error, key: {}, delta: {}, error: {}", key, delta, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Long decrement(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForValue().decrement(key);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis decrement error, key: {}, error: {}", key, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Long decrement(String key, long delta) {
|
||||
try {
|
||||
return redisTemplate.opsForValue().decrement(key, delta);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis decrement error, key: {}, delta: {}, error: {}", key, delta, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean delete(String key) {
|
||||
try {
|
||||
return redisTemplate.delete(key);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis delete error, key: {}, error: {}", key, e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Long delete(Collection<String> keys) {
|
||||
try {
|
||||
return redisTemplate.delete(keys);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis batch delete error, error: {}", e.getMessage());
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
public void hSet(String key, String hashKey, Object value) {
|
||||
try {
|
||||
redisTemplate.opsForHash().put(key, hashKey, value);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis hSet error, key: {}, hashKey: {}, error: {}", key, hashKey, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public Object hGet(String key, String hashKey) {
|
||||
try {
|
||||
return redisTemplate.opsForHash().get(key, hashKey);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis hGet error, key: {}, hashKey: {}, error: {}", key, hashKey, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Object hGetAll(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForHash().entries(key);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis hGetAll error, key: {}, error: {}", key, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Long hDelete(String key, Object... hashKeys) {
|
||||
try {
|
||||
return redisTemplate.opsForHash().delete(key, hashKeys);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis hDelete error, key: {}, error: {}", key, e.getMessage());
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
public Long hIncrement(String key, String hashKey, long delta) {
|
||||
try {
|
||||
return redisTemplate.opsForHash().increment(key, hashKey, delta);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis hIncrement error, key: {}, hashKey: {}, error: {}", key, hashKey, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean hasKey(String key) {
|
||||
try {
|
||||
return redisTemplate.hasKey(key);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis hasKey error, key: {}, error: {}", key, e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean expire(String key, long timeout, TimeUnit unit) {
|
||||
try {
|
||||
return redisTemplate.expire(key, timeout, unit);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis expire error, key: {}, error: {}", key, e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean expire(String key, long seconds) {
|
||||
return expire(key, seconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public Long getExpire(String key, TimeUnit unit) {
|
||||
try {
|
||||
return redisTemplate.getExpire(key, unit);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis getExpire error, key: {}, error: {}", key, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Long getExpire(String key) {
|
||||
return getExpire(key, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public Set<String> keys(String pattern) {
|
||||
try {
|
||||
return redisTemplate.keys(pattern);
|
||||
} catch (Exception e) {
|
||||
log.error("Redis keys error, pattern: {}, error: {}", pattern, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
43
src/main/java/com/aida/seller/util/ValidationUtil.java
Normal file
43
src/main/java/com/aida/seller/util/ValidationUtil.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package com.aida.seller.util;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ValidationUtil {
|
||||
|
||||
private static final Pattern MOBILE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
|
||||
private static final Pattern EMAIL_PATTERN = Pattern.compile("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");
|
||||
private static final Pattern ID_CARD_PATTERN = Pattern.compile("^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$");
|
||||
private static final Pattern URL_PATTERN = Pattern.compile("^(https?|ftp)://[^\\s/$.?#].[^\\s]*$");
|
||||
|
||||
private ValidationUtil() {}
|
||||
|
||||
public static boolean isMobile(String mobile) {
|
||||
if (StrUtil.isBlank(mobile)) {
|
||||
return false;
|
||||
}
|
||||
return MOBILE_PATTERN.matcher(mobile).matches();
|
||||
}
|
||||
|
||||
public static boolean isEmail(String email) {
|
||||
if (StrUtil.isBlank(email)) {
|
||||
return false;
|
||||
}
|
||||
return EMAIL_PATTERN.matcher(email).matches();
|
||||
}
|
||||
|
||||
public static boolean isIdCard(String idCard) {
|
||||
if (StrUtil.isBlank(idCard)) {
|
||||
return false;
|
||||
}
|
||||
return ID_CARD_PATTERN.matcher(idCard).matches();
|
||||
}
|
||||
|
||||
public static boolean isUrl(String url) {
|
||||
if (StrUtil.isBlank(url)) {
|
||||
return false;
|
||||
}
|
||||
return URL_PATTERN.matcher(url).matches();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user