diff --git a/Jenkinsfile b/Jenkinsfile
index a30190b..5b8dfb0 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -59,6 +59,7 @@ pipeline {
--name \${CONTAINER_NAME} \
--network sczx-net \
-p 8082:8082 \
+ -e SPRING_PROFILES_ACTIVE=test \
-e JAVA_OPTS="-Xms256m -Xmx512m -Duser.timezone=Asia/Shanghai" \
--restart always \
\${DOCKER_IMAGE}
diff --git a/pom.xml b/pom.xml
index a4da891..e7ae583 100644
--- a/pom.xml
+++ b/pom.xml
@@ -222,6 +222,12 @@
fastjson
1.2.83
+
+
+ commons-codec
+ commons-codec
+ 1.15
+
diff --git a/src/main/java/com/sczx/store/config/OSSConfig.java b/src/main/java/com/sczx/store/config/OSSConfig.java
new file mode 100644
index 0000000..3fc6430
--- /dev/null
+++ b/src/main/java/com/sczx/store/config/OSSConfig.java
@@ -0,0 +1,14 @@
+package com.sczx.store.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "oss")
+public class OSSConfig {
+ private String region;
+ private String accessKeyId;
+ private String accessKeySecret;
+}
diff --git a/src/main/java/com/sczx/store/controller/OssController.java b/src/main/java/com/sczx/store/controller/OssController.java
new file mode 100644
index 0000000..6e2970c
--- /dev/null
+++ b/src/main/java/com/sczx/store/controller/OssController.java
@@ -0,0 +1,26 @@
+package com.sczx.store.controller;
+
+import com.sczx.store.common.Result;
+import com.sczx.store.dto.OssPlicyReq;
+import com.sczx.store.dto.OssPolicyRes;
+import com.sczx.store.service.OssService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Api(value = "oss接口", tags = "oss接口")
+@RestController
+@RequestMapping("/oss")
+public class OssController {
+
+ @Autowired
+ private OssService ossService;
+
+ @PostMapping("/policy")
+ public Result policy(@RequestBody OssPlicyReq ossPlicyReq) {
+ return Result.ok(ossService.getPolicy(ossPlicyReq));
+ }
+}
diff --git a/src/main/java/com/sczx/store/dto/OssPlicyReq.java b/src/main/java/com/sczx/store/dto/OssPlicyReq.java
new file mode 100644
index 0000000..e6e169c
--- /dev/null
+++ b/src/main/java/com/sczx/store/dto/OssPlicyReq.java
@@ -0,0 +1,19 @@
+package com.sczx.store.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@ApiModel(value = "OssPlicy请求对象", description = "OssPlicyReq对象")
+@Data
+public class OssPlicyReq {
+
+ @ApiModelProperty(value = "过期时间")
+ private long expireTime;
+
+ @ApiModelProperty(value = "上传目录")
+ private String dir;
+
+ @ApiModelProperty(value = "bucket名称")
+ private String bucketName;
+}
diff --git a/src/main/java/com/sczx/store/dto/OssPolicyRes.java b/src/main/java/com/sczx/store/dto/OssPolicyRes.java
new file mode 100644
index 0000000..dd10958
--- /dev/null
+++ b/src/main/java/com/sczx/store/dto/OssPolicyRes.java
@@ -0,0 +1,22 @@
+package com.sczx.store.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "OSS上传策略返回对象", description = "OSS上传策略")
+public class OssPolicyRes {
+ @ApiModelProperty(value = "accessKeyId", required = true)
+ private String accessid;
+ @ApiModelProperty(value = "上传策略,需要后端生成", required = true)
+ private String policy;
+ @ApiModelProperty(value = "signature:签名,基于 accessKeySecret 生成", required = true)
+ private String signature;
+ @ApiModelProperty(value = "dir:上传目录(可选)", required = false)
+ private String dir;
+ @ApiModelProperty(value = "host:OSS 访问域名", required = true)
+ private String host;
+ @ApiModelProperty(value = "expire:过期时间", required = true)
+ private Long expire;
+}
diff --git a/src/main/java/com/sczx/store/service/OssService.java b/src/main/java/com/sczx/store/service/OssService.java
new file mode 100644
index 0000000..adc4597
--- /dev/null
+++ b/src/main/java/com/sczx/store/service/OssService.java
@@ -0,0 +1,8 @@
+package com.sczx.store.service;
+
+import com.sczx.store.dto.OssPlicyReq;
+import com.sczx.store.dto.OssPolicyRes;
+
+public interface OssService {
+ OssPolicyRes getPolicy(OssPlicyReq ossPlicyReq);
+}
diff --git a/src/main/java/com/sczx/store/service/impl/OssServiceImpl.java b/src/main/java/com/sczx/store/service/impl/OssServiceImpl.java
new file mode 100644
index 0000000..94daf5c
--- /dev/null
+++ b/src/main/java/com/sczx/store/service/impl/OssServiceImpl.java
@@ -0,0 +1,75 @@
+package com.sczx.store.service.impl;
+
+import com.sczx.store.config.OSSConfig;
+import com.sczx.store.dto.OssPlicyReq;
+import com.sczx.store.dto.OssPolicyRes;
+import com.sczx.store.service.OssService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Base64;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+@Slf4j
+@Service
+public class OssServiceImpl implements OssService {
+
+ @Autowired
+ private OSSConfig ossConfig;
+
+ @Override
+ public OssPolicyRes getPolicy(OssPlicyReq ossPlicyReq) {
+
+ long expireEndTime = System.currentTimeMillis() + ossPlicyReq.getExpireTime() * 1000;
+ Date expiration = new Date(expireEndTime);
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+ String expire = df.format(expiration);
+
+ // 创建policy
+ Map policyMap = new LinkedHashMap<>();
+ policyMap.put("expiration", expire);
+
+ Map conditionMap = new LinkedHashMap<>();
+ conditionMap.put("bucket", ossPlicyReq.getBucketName()); // 需要替换成你的 bucket 名称
+
+ policyMap.put("conditions", new Object[]{conditionMap});
+
+ String policy = Base64.getEncoder().encodeToString(policyMap.toString().getBytes(StandardCharsets.UTF_8));
+ String signature = calculateSignature(ossConfig.getAccessKeySecret(), policy);
+
+ // 构造返回数据
+ OssPolicyRes response = new OssPolicyRes();
+ response.setAccessid(ossConfig.getAccessKeyId());
+ response.setPolicy(policy);
+ response.setSignature(signature);
+ response.setDir(ossPlicyReq.getDir()+"/"); // 可以自定义上传目录
+ response.setHost("https://" + ossPlicyReq.getBucketName() + "." + ossConfig.getRegion() + ".aliyuncs.com"); // 需要替换成你的 bucket 名称
+ response.setExpire(expireEndTime / 1000);
+ return response;
+ }
+
+ /**
+ * 计算签名
+ * @param accessKeySecret
+ * @param policy
+ * @return
+ */
+ private String calculateSignature(String accessKeySecret, String policy) {
+ try {
+ Mac mac = Mac.getInstance("HmacSHA1");
+ mac.init(new SecretKeySpec(accessKeySecret.getBytes(StandardCharsets.UTF_8), "HmacSHA1"));
+ byte[] signData = mac.doFinal(policy.getBytes(StandardCharsets.UTF_8));
+ return Base64.getEncoder().encodeToString(signData);
+ } catch (Exception e) {
+ throw new RuntimeException("计算签名失败", e);
+ }
+ }
+}
diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/src/main/resources/application-local.yml
@@ -0,0 +1 @@
+
diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/src/main/resources/application-test.yml
@@ -0,0 +1 @@
+
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index e2d1b7a..5a8ca86 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -84,3 +84,8 @@ mybatis-plus:
auth:
secret-key: his-is-a-very-long-and-secure-secret-key-for-jwt-signing-please-dont-use-short-keys
token-expiration: 86400000 # 24小时
+
+oss:
+ region: oss-cn-shanghai
+ accessKeyId: LTAI5tFZygsWsFqAqUbBmCrB
+ accessKeySecret: n417ym6PZyq5Gc4NHHps3EwzNiClDJ
\ No newline at end of file