Jelajahi Sumber

新增limit-upload接口

codingliang 8 bulan lalu
induk
melakukan
d34a0380da

+ 5 - 0
src/main/java/com/sqx/common/constant/RedisKey.java

@@ -107,4 +107,9 @@ public interface RedisKey {
      * 首页店铺列表缓存key
      */
     String INDEX_SHOP_LIST_CACHE_KEY = "wm:shop:list:";
+
+     /**
+     * 图片上传token缓存key 按ip限制
+     */
+    String IMAGE_UPLOAD_TOKEN_CACHE_KEY_IP_LIMIT = "wm:data:image:upload:token:ip:%s";
 }

+ 0 - 2
src/main/java/com/sqx/common/utils/IPUtils.java

@@ -42,8 +42,6 @@ public class IPUtils {
         	logger.error("IPUtils ERROR ", e);
         }
 
-        
         return ip;
     }
-	
 }

+ 18 - 0
src/main/java/com/sqx/modules/file/app/AppNewFileController.java

@@ -1,5 +1,7 @@
 package com.sqx.modules.file.app;
 
+import cn.hutool.core.util.StrUtil;
+import com.sqx.common.utils.IPUtils;
 import com.sqx.common.utils.Result;
 import com.sqx.modules.app.annotation.Login;
 import com.sqx.modules.file.service.NewFileService;
@@ -7,11 +9,14 @@ import icu.xuyijie.secureapi.annotation.DecryptParam;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletRequest;
+
 /**
  * @author codingliang
  * @date 2025-10-21
@@ -31,4 +36,17 @@ public class AppNewFileController {
         String src = newFileService.upload(file);
         return Result.success().put("data",src);
     }
+
+
+    @PostMapping(value = "limit-upload")
+    public Result uploadWithToken(HttpServletRequest request, @DecryptParam("file") MultipartFile file){
+        String clientIp = IPUtils.getIpAddr(request);
+
+        if (StrUtil.isBlank(clientIp)){
+            return Result.error("未获取到客户端IP地址");
+        }
+
+        String src = newFileService.upload(clientIp, file);
+        return Result.success().put("data", src);
+    }
 }

+ 19 - 0
src/main/java/com/sqx/modules/file/service/NewFileService.java

@@ -3,7 +3,9 @@ package com.sqx.modules.file.service;
 import cn.hutool.core.util.StrUtil;
 import com.aliyun.oss.OSS;
 import com.aliyun.oss.OSSClientBuilder;
+import com.sqx.common.constant.RedisKey;
 import com.sqx.common.exception.SqxException;
+import com.sqx.common.utils.RedisUtils;
 import com.sqx.config.MinioConfig;
 import com.sqx.modules.common.service.CommonInfoService;
 import com.sqx.modules.file.utils.FileUploadUtils;
@@ -33,6 +35,7 @@ public class NewFileService {
     private final CommonInfoService commonInfoService;
     private final MinioClient minioClient;
     private final MinioConfig minioConfig;
+    private final RedisUtils redisUtils;
 
     public String upload(MultipartFile file) {
         // 新增图片类型验证
@@ -87,6 +90,22 @@ public class NewFileService {
         }
     }
 
+    public String upload(String clientIp, MultipartFile file) {
+        String ipLimitKey = String.format(RedisKey.IMAGE_UPLOAD_TOKEN_CACHE_KEY_IP_LIMIT, clientIp);
+        long count = redisUtils.increment(ipLimitKey);
+
+        if (count == 1) {
+            // 第一次访问,设置过期时间为1小时
+            redisUtils.expire(ipLimitKey, RedisUtils.HOUR_ONE_EXPIRE);
+        } else if (count > 15) {
+            // 超过限制,抛出异常
+            throw new SqxException("获取上传token过于频繁,请稍后再试");
+        }
+
+        // 上传文件
+        return upload(file);
+    }
+
     private String getPath(String suffix) {
         // 生成uuid
         String uuid = UUID.randomUUID().toString().replaceAll("-", "");