diff --git a/pigx-common/pigx-common-aws/pom.xml b/pigx-common/pigx-common-aws/pom.xml
new file mode 100755
index 000000000..8dbea393c
--- /dev/null
+++ b/pigx-common/pigx-common-aws/pom.xml
@@ -0,0 +1,24 @@
+
+
+ 4.0.0
+
+ com.pig4cloud
+ pigx-common
+ 3.9.0-SNAPSHOT
+
+
+ pigx-common-aws
+ jar
+
+ pigx 文件系统依赖
+
+
+
+ com.amazonaws
+ aws-java-sdk-s3
+ 1.11.543
+
+
+
\ No newline at end of file
diff --git a/pigx-common/pigx-common-aws/src/main/java/com/pig4cloud/pigx/common/aws/AwsAutoConfiguration.java b/pigx-common/pigx-common-aws/src/main/java/com/pig4cloud/pigx/common/aws/AwsAutoConfiguration.java
new file mode 100755
index 000000000..6e79c5d37
--- /dev/null
+++ b/pigx-common/pigx-common-aws/src/main/java/com/pig4cloud/pigx/common/aws/AwsAutoConfiguration.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.aws;
+
+import com.pig4cloud.pigx.common.aws.http.AwsEndpoint;
+import com.pig4cloud.pigx.common.aws.service.AwsTemplate;
+import lombok.AllArgsConstructor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * aws 自动配置类
+ *
+ * @author lengleng
+ * @author 858695266
+ */
+@AllArgsConstructor
+@EnableConfigurationProperties({AwsProperties.class})
+public class AwsAutoConfiguration {
+ private final AwsProperties properties;
+
+ @Bean
+ @ConditionalOnMissingBean(AwsTemplate.class)
+ @ConditionalOnProperty(name = "oss.endpoint")
+ AwsTemplate awsTemplate() {
+ return new AwsTemplate(properties);
+ }
+
+ @Bean
+ @ConditionalOnProperty(name = "oss.enable", havingValue = "true")
+ public AwsEndpoint awsEndpoint(AwsTemplate template) {
+ return new AwsEndpoint(template);
+ }
+
+}
diff --git a/pigx-common/pigx-common-aws/src/main/java/com/pig4cloud/pigx/common/aws/AwsProperties.java b/pigx-common/pigx-common-aws/src/main/java/com/pig4cloud/pigx/common/aws/AwsProperties.java
new file mode 100755
index 000000000..9425bfbbe
--- /dev/null
+++ b/pigx-common/pigx-common-aws/src/main/java/com/pig4cloud/pigx/common/aws/AwsProperties.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.aws;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * aws 配置信息
+ *
+ * @author lengleng
+ * @author 858695266
+ * 配置文件添加:
+ * oss:
+ * enable: true
+ * endpoint: http://127.0.0.1:9000
+ * access-key: lengleng
+ * secret-key: lengleng
+ * bucket-name: lengleng
+ * region:
+ * custom-domain: https://oss.xxx.com/lengleng
+ *
+ * bucket 设置公共读权限
+ */
+@Data
+@ConfigurationProperties(prefix = "oss")
+public class AwsProperties {
+ /**
+ * 对象存储服务的URL
+ */
+ private String endpoint;
+
+ /**
+ * 自定义域名
+ */
+ private String customDomain;
+
+ /**
+ * 应用ID
+ */
+ private String appId;
+
+ /**
+ * 区域
+ */
+ private String region;
+
+ /**
+ * Access key就像用户ID,可以唯一标识你的账户
+ */
+ private String accessKey;
+
+ /**
+ * Secret key是你账户的密码
+ */
+ private String secretKey;
+
+ /**
+ * 默认的存储桶名称
+ */
+ private String bucketName = "payerp";
+
+}
diff --git a/pigx-common/pigx-common-aws/src/main/java/com/pig4cloud/pigx/common/aws/http/AwsEndpoint.java b/pigx-common/pigx-common-aws/src/main/java/com/pig4cloud/pigx/common/aws/http/AwsEndpoint.java
new file mode 100755
index 000000000..9123bf8c9
--- /dev/null
+++ b/pigx-common/pigx-common-aws/src/main/java/com/pig4cloud/pigx/common/aws/http/AwsEndpoint.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.aws.http;
+
+import com.amazonaws.services.s3.model.Bucket;
+import com.amazonaws.services.s3.model.S3Object;
+import com.amazonaws.services.s3.model.S3ObjectSummary;
+import com.pig4cloud.pigx.common.aws.service.AwsTemplate;
+import lombok.AllArgsConstructor;
+import lombok.SneakyThrows;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * aws 对外提供服务端点
+ *
+ * @author lengleng
+ * @author 858695266
+ *
+ * oss.enable
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/aws")
+public class AwsEndpoint {
+ private final AwsTemplate template;
+
+ /**
+ * Bucket Endpoints
+ */
+ @SneakyThrows
+ @PostMapping("/bucket/{bucketName}")
+ public Bucket createBucker(@PathVariable String bucketName) {
+
+ template.createBucket(bucketName);
+ return template.getBucket(bucketName).get();
+
+ }
+
+ @SneakyThrows
+ @GetMapping("/bucket")
+ public List getBuckets() {
+ return template.getAllBuckets();
+ }
+
+ @SneakyThrows
+ @GetMapping("/bucket/{bucketName}")
+ public Bucket getBucket(@PathVariable String bucketName) {
+ return template.getBucket(bucketName).orElseThrow(() -> new IllegalArgumentException("Bucket Name not found!"));
+ }
+
+ @SneakyThrows
+ @DeleteMapping("/bucket/{bucketName}")
+ @ResponseStatus(HttpStatus.ACCEPTED)
+ public void deleteBucket(@PathVariable String bucketName) {
+ template.removeBucket(bucketName);
+ }
+
+ /**
+ * Object Endpoints
+ */
+ @SneakyThrows
+ @PostMapping("/object/{bucketName}")
+ public S3Object createObject(@RequestBody MultipartFile object, @PathVariable String bucketName) {
+ String name = object.getOriginalFilename();
+ template.putObject(bucketName, name, object.getInputStream(), object.getSize(), object.getContentType());
+ return template.getObjectInfo(bucketName, name);
+
+ }
+
+ @SneakyThrows
+ @PostMapping("/object/{bucketName}/{objectName}")
+ public S3Object createObject(@RequestBody MultipartFile object, @PathVariable String bucketName, @PathVariable String objectName) {
+ template.putObject(bucketName, objectName, object.getInputStream(), object.getSize(), object.getContentType());
+ return template.getObjectInfo(bucketName, objectName);
+
+ }
+
+ @SneakyThrows
+ @GetMapping("/object/{bucketName}/{objectName}")
+ public List filterObject(@PathVariable String bucketName, @PathVariable String objectName) {
+
+ return template.getAllObjectsByPrefix(bucketName, objectName, true);
+
+ }
+
+ @SneakyThrows
+ @GetMapping("/object/{bucketName}/{objectName}/{expires}")
+ public Map getObject(@PathVariable String bucketName, @PathVariable String objectName, @PathVariable Integer expires) {
+ Map responseBody = new HashMap<>(8);
+ // Put Object info
+ responseBody.put("bucket", bucketName);
+ responseBody.put("object", objectName);
+ responseBody.put("url", template.getObjectURL(bucketName, objectName, expires));
+ responseBody.put("expires", expires);
+ return responseBody;
+ }
+
+ @SneakyThrows
+ @ResponseStatus(HttpStatus.ACCEPTED)
+ @DeleteMapping("/object/{bucketName}/{objectName}/")
+ public void deleteObject(@PathVariable String bucketName, @PathVariable String objectName) {
+
+ template.removeObject(bucketName, objectName);
+ }
+
+
+}
diff --git a/pigx-common/pigx-common-aws/src/main/java/com/pig4cloud/pigx/common/aws/service/AwsTemplate.java b/pigx-common/pigx-common-aws/src/main/java/com/pig4cloud/pigx/common/aws/service/AwsTemplate.java
new file mode 100755
index 000000000..245e2466e
--- /dev/null
+++ b/pigx-common/pigx-common-aws/src/main/java/com/pig4cloud/pigx/common/aws/service/AwsTemplate.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2018-2025, lengleng All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * Neither the name of the pig4cloud.com developer nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Author: lengleng (wangiegie@gmail.com)
+ */
+
+package com.pig4cloud.pigx.common.aws.service;
+
+import com.amazonaws.ClientConfiguration;
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.auth.AWSStaticCredentialsProvider;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.client.builder.AwsClientBuilder;
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.AmazonS3Client;
+import com.amazonaws.services.s3.model.*;
+import com.amazonaws.util.IOUtils;
+import com.pig4cloud.pigx.common.aws.AwsProperties;
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import org.springframework.beans.factory.InitializingBean;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.*;
+
+
+/**
+ * aws-s3 通用存储操作
+ * 支持所有兼容s3协议的云存储: {阿里云OSS,腾讯云COS,七牛云,京东云,minio 等}
+ *
+ * @author lengleng
+ * @author 858695266
+ * @date 2020/5/23 6:36 上午
+ * @since 1.0
+ */
+@RequiredArgsConstructor
+public class AwsTemplate implements InitializingBean {
+ private final AwsProperties ossProperties;
+
+ private AmazonS3 amazonS3;
+
+ /**
+ * 创建bucket
+ *
+ * @param bucketName bucket名称
+ */
+ @SneakyThrows
+ public void createBucket(String bucketName) {
+ if (!amazonS3.doesBucketExistV2(bucketName)) {
+ amazonS3.createBucket((bucketName));
+ }
+ }
+
+ /**
+ * 获取全部bucket
+ *
+ *
+ * @see AWS API Documentation
+ */
+ @SneakyThrows
+ public List getAllBuckets() {
+ return amazonS3.listBuckets();
+ }
+
+ /**
+ * @param bucketName bucket名称
+ * @see AWS API Documentation
+ */
+ @SneakyThrows
+ public Optional getBucket(String bucketName) {
+ return amazonS3.listBuckets().stream().filter(b -> b.getName().equals(bucketName)).findFirst();
+ }
+
+ /**
+ * @param bucketName bucket名称
+ * @see AWS API Documentation
+ */
+ @SneakyThrows
+ public void removeBucket(String bucketName) {
+ amazonS3.deleteBucket(bucketName);
+ }
+
+ /**
+ * 根据文件前置查询文件
+ *
+ * @param bucketName bucket名称
+ * @param prefix 前缀
+ * @param recursive 是否递归查询
+ * @return S3ObjectSummary 列表
+ * @see AWS API Documentation
+ */
+ @SneakyThrows
+ public List getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) {
+ ObjectListing objectListing = amazonS3.listObjects(bucketName, prefix);
+ return new ArrayList<>(objectListing.getObjectSummaries());
+ }
+
+ /**
+ * 获取文件外链
+ *
+ * @param bucketName bucket名称
+ * @param objectName 文件名称
+ * @param expires 过期时间 <=7
+ * @see AmazonS3#generatePresignedUrl(String bucketName, String key, Date expiration)
+ * @return url
+ */
+ @SneakyThrows
+ public String getObjectURL(String bucketName, String objectName, Integer expires) {
+ Date date = new Date();
+ Calendar calendar = new GregorianCalendar();
+ calendar.setTime(date);
+ calendar.add(Calendar.DAY_OF_MONTH, expires);
+ URL url = amazonS3.generatePresignedUrl(bucketName, objectName, calendar.getTime());
+ return url.toString();
+ }
+
+ /**
+ * 获取文件
+ *
+ * @param bucketName bucket名称
+ * @param objectName 文件名称
+ * @see AWS API Documentation
+ * @return 二进制流
+ */
+ @SneakyThrows
+ public InputStream getObject(String bucketName, String objectName) {
+ return amazonS3.getObject(bucketName, objectName).getObjectContent();
+ }
+
+ /**
+ * 上传文件
+ *
+ * @param bucketName bucket名称
+ * @param objectName 文件名称
+ * @param stream 文件流
+ * @throws Exception
+ */
+ public void putObject(String bucketName, String objectName, InputStream stream) throws Exception {
+ putObject(bucketName, objectName, stream, (long) stream.available(), "application/octet-stream");
+ }
+
+ /**
+ * 上传文件
+ *
+ * @param bucketName bucket名称
+ * @param objectName 文件名称
+ * @param stream 文件流
+ * @param size 大小
+ * @param contextType 类型
+ * @see AWS API Documentation
+ * @throws Exception
+ */
+ public PutObjectResult putObject(String bucketName, String objectName, InputStream stream, long size, String contextType) throws Exception {
+// String fileName = getFileName(objectName);
+ byte[] bytes = IOUtils.toByteArray(stream);
+ ObjectMetadata objectMetadata = new ObjectMetadata();
+ objectMetadata.setContentLength(size);
+ objectMetadata.setContentType(contextType);
+ ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
+ // 上传
+ return amazonS3.putObject(bucketName, objectName, byteArrayInputStream, objectMetadata);
+
+ }
+
+ /**
+ * 获取文件信息
+ *
+ * @param bucketName bucket名称
+ * @param objectName 文件名称
+ * @see AWS API Documentation
+ * @throws Exception
+ */
+ public S3Object getObjectInfo(String bucketName, String objectName) throws Exception {
+ return amazonS3.getObject(bucketName, objectName);
+ }
+
+ /**
+ * 删除文件
+ *
+ * @param bucketName bucket名称
+ * @param objectName 文件名称
+ * @see AWS API Documentation
+ * @throws Exception
+ */
+ public void removeObject(String bucketName, String objectName) throws Exception {
+ amazonS3.deleteObject(bucketName, objectName);
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ ClientConfiguration clientConfiguration = new ClientConfiguration();
+ AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(
+ ossProperties.getEndpoint(), ossProperties.getRegion());
+ AWSCredentials awsCredentials = new BasicAWSCredentials(ossProperties.getAccessKey(), ossProperties.getSecretKey());
+ AWSCredentialsProvider awsCredentialsProvider = new AWSStaticCredentialsProvider(awsCredentials);
+ this.amazonS3 = AmazonS3Client.builder()
+ .withEndpointConfiguration(endpointConfiguration)
+ .withClientConfiguration(clientConfiguration)
+ .withCredentials(awsCredentialsProvider)
+ .disableChunkedEncoding()
+ .withPathStyleAccessEnabled(false)
+ .build();
+ }
+}
diff --git a/pigx-common/pigx-common-aws/src/main/resources/META-INF/spring.factories b/pigx-common/pigx-common-aws/src/main/resources/META-INF/spring.factories
new file mode 100755
index 000000000..062b7741c
--- /dev/null
+++ b/pigx-common/pigx-common-aws/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+ com.pig4cloud.pigx.common.aws.AwsAutoConfiguration
\ No newline at end of file
diff --git a/pigx-common/pigx-common-bom/pom.xml b/pigx-common/pigx-common-bom/pom.xml
index 2179e5f62..1172d610f 100644
--- a/pigx-common/pigx-common-bom/pom.xml
+++ b/pigx-common/pigx-common-bom/pom.xml
@@ -73,6 +73,11 @@
pigx-common-minio
${pigx.version}
+
+ com.pig4cloud
+ pigx-common-aws
+ ${pigx.version}
+
com.pig4cloud
pigx-common-security
diff --git a/pigx-common/pom.xml b/pigx-common/pom.xml
index 6e0dbca2b..f884bf244 100644
--- a/pigx-common/pom.xml
+++ b/pigx-common/pom.xml
@@ -43,6 +43,7 @@
pigx-common-job
pigx-common-log
pigx-common-minio
+ pigx-common-aws
pigx-common-security
pigx-common-sentinel
pigx-common-sequence
diff --git a/pigx-upms/pigx-upms-biz/pom.xml b/pigx-upms/pigx-upms-biz/pom.xml
index 2ffed11e0..20c48f7e2 100644
--- a/pigx-upms/pigx-upms-biz/pom.xml
+++ b/pigx-upms/pigx-upms-biz/pom.xml
@@ -55,7 +55,7 @@
com.pig4cloud
- pigx-common-minio
+ pigx-common-aws
diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysFileServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysFileServiceImpl.java
index f3431c217..4ea061ebf 100644
--- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysFileServiceImpl.java
+++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysFileServiceImpl.java
@@ -24,9 +24,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.entity.SysFile;
import com.pig4cloud.pigx.admin.mapper.SysFileMapper;
import com.pig4cloud.pigx.admin.service.SysFileService;
+import com.pig4cloud.pigx.common.aws.AwsProperties;
+import com.pig4cloud.pigx.common.aws.service.AwsTemplate;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.util.R;
-import com.pig4cloud.pigx.common.minio.service.MinioTemplate;
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
@@ -50,7 +51,8 @@ import java.util.Map;
@Service
@AllArgsConstructor
public class SysFileServiceImpl extends ServiceImpl implements SysFileService {
- private final MinioTemplate minioTemplate;
+ private final AwsTemplate minioTemplate;
+ private final AwsProperties awsProperties;
/**
@@ -63,12 +65,12 @@ public class SysFileServiceImpl extends ServiceImpl impl
public R uploadFile(MultipartFile file) {
String fileName = IdUtil.simpleUUID() + StrUtil.DOT + FileUtil.extName(file.getOriginalFilename());
Map resultMap = new HashMap<>(4);
- resultMap.put("bucketName", CommonConstants.BUCKET_NAME);
+ resultMap.put("bucketName", awsProperties.getBucketName());
resultMap.put("fileName", fileName);
- resultMap.put("url", String.format("/admin/sys-file/%s/%s", CommonConstants.BUCKET_NAME, fileName));
+ resultMap.put("url", String.format("/admin/sys-file/%s/%s", awsProperties.getBucketName(), fileName));
try {
- minioTemplate.putObject(CommonConstants.BUCKET_NAME, fileName, file.getInputStream());
+ minioTemplate.putObject(awsProperties.getBucketName(), fileName, file.getInputStream());
//文件管理数据记录,收集管理追踪文件
fileLog(file, fileName);
} catch (Exception e) {
@@ -107,7 +109,7 @@ public class SysFileServiceImpl extends ServiceImpl impl
@Transactional(rollbackFor = Exception.class)
public Boolean deleteFile(Long id) {
SysFile file = this.getById(id);
- minioTemplate.removeObject(CommonConstants.BUCKET_NAME, file.getFileName());
+ minioTemplate.removeObject(awsProperties.getBucketName(), file.getFileName());
return this.removeById(id);
}
@@ -125,7 +127,7 @@ public class SysFileServiceImpl extends ServiceImpl impl
sysFile.setOriginal(original);
sysFile.setFileSize(file.getSize());
sysFile.setType(FileUtil.extName(original));
- sysFile.setBucketName(CommonConstants.BUCKET_NAME);
+ sysFile.setBucketName(awsProperties.getBucketName());
sysFile.setCreateUser(SecurityUtils.getUser().getUsername());
this.save(sysFile);
}
diff --git a/pom.xml b/pom.xml
index 34d90d89c..4d1a60c5d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -49,6 +49,7 @@
2.1.1
2.11.4
6.0.13
+ 1.11.543
2.2.0
5.22.0
172.17.0.111