284 lines
11 KiB
Java
284 lines
11 KiB
Java
package com.gxwebsoft.common.system.controller;
|
||
|
||
import cn.hutool.core.util.StrUtil;
|
||
import com.alibaba.fastjson.JSONObject;
|
||
import com.aliyun.oss.ClientException;
|
||
import com.aliyun.oss.OSS;
|
||
import com.aliyun.oss.OSSClientBuilder;
|
||
import com.aliyun.oss.OSSException;
|
||
import com.aliyun.oss.common.auth.CredentialsProvider;
|
||
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
|
||
import com.aliyun.oss.common.utils.BinaryUtil;
|
||
import com.aliyun.oss.model.PolicyConditions;
|
||
import com.aliyun.oss.model.PutObjectRequest;
|
||
import com.aliyun.oss.model.PutObjectResult;
|
||
import com.aliyuncs.DefaultAcsClient;
|
||
import com.aliyuncs.auth.sts.AssumeRoleRequest;
|
||
import com.aliyuncs.auth.sts.AssumeRoleResponse;
|
||
import com.aliyuncs.http.MethodType;
|
||
import com.aliyuncs.profile.DefaultProfile;
|
||
import com.aliyuncs.profile.IClientProfile;
|
||
import com.gxwebsoft.common.core.annotation.OperationLog;
|
||
import com.gxwebsoft.common.core.config.ConfigProperties;
|
||
import com.gxwebsoft.common.core.utils.FileServerUtil;
|
||
import com.gxwebsoft.common.core.utils.RedisUtil;
|
||
import com.gxwebsoft.common.core.web.ApiResult;
|
||
import com.gxwebsoft.common.core.web.BaseController;
|
||
import com.gxwebsoft.common.system.entity.Company;
|
||
import com.gxwebsoft.common.system.entity.FileRecord;
|
||
import com.gxwebsoft.common.system.service.CompanyService;
|
||
import com.gxwebsoft.common.system.service.FileRecordService;
|
||
import com.gxwebsoft.common.system.service.SettingService;
|
||
import io.swagger.annotations.Api;
|
||
import io.swagger.annotations.ApiOperation;
|
||
import org.springframework.web.bind.annotation.*;
|
||
import org.springframework.web.multipart.MultipartFile;
|
||
|
||
import javax.annotation.Resource;
|
||
import javax.servlet.http.HttpServletRequest;
|
||
import java.io.File;
|
||
import java.nio.charset.StandardCharsets;
|
||
import java.text.SimpleDateFormat;
|
||
import java.util.Date;
|
||
import java.util.HashMap;
|
||
import java.util.Map;
|
||
|
||
/**
|
||
* 阿里云OSS云存储
|
||
*
|
||
* @author WebSoft
|
||
* @since 2022-11-19 13:54:27
|
||
*/
|
||
@Api(tags = "阿里云OSS云存储")
|
||
@RestController
|
||
@RequestMapping("/api/oss")
|
||
public class AliOssController extends BaseController {
|
||
@Resource
|
||
private ConfigProperties config;
|
||
@Resource
|
||
private RedisUtil redisUtil;
|
||
@Resource
|
||
private FileRecordService fileRecordService;
|
||
@Resource
|
||
private CompanyService companyService;
|
||
@Resource
|
||
private SettingService settingService;
|
||
|
||
@ApiOperation("上传文件")
|
||
@PostMapping("/upload")
|
||
public ApiResult<FileRecord> upload(@RequestParam MultipartFile file, HttpServletRequest request) throws Exception{
|
||
// 获取租户ID
|
||
String tenantId = request.getHeader("TenantId");
|
||
String companyId = request.getHeader("CompanyId");
|
||
String groupId = request.getHeader("GroupId");
|
||
String appId = request.getHeader("AppId");
|
||
if(StrUtil.isBlank(tenantId)){
|
||
return fail("传参错误",null);
|
||
}
|
||
|
||
// 读取配置信息
|
||
JSONObject settingInfo;
|
||
String key3 = "Upload:" + tenantId;
|
||
settingInfo = redisUtil.get(key3, JSONObject.class);
|
||
if (settingInfo == null) {
|
||
settingInfo = settingService.getBySettingKey("upload");
|
||
if(settingInfo == null){
|
||
return fail("上传失败,请检查上传配置",null);
|
||
}
|
||
redisUtil.set(key3,settingInfo);
|
||
}
|
||
String endpoint = settingInfo.getString("bucketEndpoint");
|
||
String bucketDomain = settingInfo.getString("bucketDomain");
|
||
String bucketName = settingInfo.getString("bucketName");
|
||
String accessKeyId = settingInfo.getString("accessKeyId");
|
||
String accessKeySecret = settingInfo.getString("accessKeySecret");
|
||
|
||
// 判断是否登录
|
||
String authorization = getAuthorization();
|
||
|
||
// 判断存储空间是否已满
|
||
String key = "StorageIsFull:" + tenantId;
|
||
String storageIsFull = redisUtil.get(key);
|
||
if(StrUtil.isNotBlank(storageIsFull)){
|
||
// 使用自定义云存储不限制
|
||
if(bucketName.equals("oss-gxwebsoft")){
|
||
return fail("存储空间已满", null);
|
||
}
|
||
}
|
||
|
||
// 上传文件结果
|
||
FileRecord result;
|
||
CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);
|
||
// 创建OSSClient实例。
|
||
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
|
||
|
||
try {
|
||
|
||
String dir = getUploadDir();
|
||
File upload = FileServerUtil.upload(file, dir, config.getUploadUuidName());
|
||
String path = upload.getAbsolutePath().replace("\\", "/").substring(dir.length());
|
||
String originalName = file.getOriginalFilename();
|
||
|
||
// 创建PutObjectRequest对象。
|
||
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, path, upload);
|
||
// 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。
|
||
// ObjectMetadata metadata = new ObjectMetadata();
|
||
// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
|
||
// metadata.setObjectAcl(CannedAccessControlList.Private);
|
||
// putObjectRequest.setMetadata(metadata);
|
||
|
||
// 上传文件。
|
||
PutObjectResult ossResult = ossClient.putObject(putObjectRequest);
|
||
|
||
// 保存记录并返回
|
||
result = new FileRecord();
|
||
if(StrUtil.isNotBlank(authorization)){
|
||
result.setCreateUserId(getLoginUserId());
|
||
}
|
||
if(StrUtil.isNotBlank(companyId)){
|
||
result.setCompanyId(Integer.valueOf(companyId));
|
||
}
|
||
if(StrUtil.isNotBlank(groupId)){
|
||
result.setGroupId(Integer.valueOf(groupId));
|
||
}
|
||
if(StrUtil.isNotBlank(appId)){
|
||
result.setAppId(Integer.valueOf(appId));
|
||
}
|
||
path = "/".concat(path);
|
||
result.setName(StrUtil.isBlank(originalName) ? upload.getName() : originalName);
|
||
result.setLength(upload.length());
|
||
result.setPath(bucketDomain + path);
|
||
result.setThumbnail(bucketDomain + path + "?x-oss-process=image/resize,m_fixed,w_100,h_100/quality,Q_90");
|
||
result.setUrl(bucketDomain + path + "?x-oss-process=image/resize,w_750/quality,Q_90");
|
||
result.setDownloadUrl(bucketDomain + path);
|
||
String contentType = FileServerUtil.getContentType(upload);
|
||
result.setContentType(contentType);
|
||
result.setTenantId(Integer.valueOf(tenantId));
|
||
upload.delete();
|
||
fileRecordService.save(result);
|
||
// 更新存储空间
|
||
if(companyId != null){
|
||
Company company = companyService.getById(Integer.valueOf(companyId));
|
||
company.setStorage(company.getStorage() + result.getLength());
|
||
if(company.getStorage().compareTo(company.getStorageMax()) > 0){
|
||
redisUtil.set(key,1);
|
||
}
|
||
companyService.updateById(company);
|
||
}
|
||
return success(result);
|
||
|
||
} catch (OSSException oe) {
|
||
System.out.println("Caught an OSSException, which means your request made it to OSS, "
|
||
+ "but was rejected with an error response for some reason.");
|
||
System.out.println("Error Message:" + oe.getErrorMessage());
|
||
System.out.println("Error Code:" + oe.getErrorCode());
|
||
System.out.println("Request ID:" + oe.getRequestId());
|
||
System.out.println("Host ID:" + oe.getHostId());
|
||
} catch (ClientException ce) {
|
||
System.out.println("Caught an ClientException, which means the client encountered "
|
||
+ "a serious internal problem while trying to communicate with OSS, "
|
||
+ "such as not being able to access the network.");
|
||
System.out.println("Error Message:" + ce.getMessage());
|
||
} finally {
|
||
if (ossClient != null) {
|
||
ossClient.shutdown();
|
||
}
|
||
}
|
||
return fail("上传失败", null);
|
||
}
|
||
|
||
@OperationLog
|
||
@ApiOperation("获取临时osstoken")
|
||
@GetMapping("/getSTSToken")
|
||
public ApiResult<?> getSTSToken() {
|
||
// STS接入地址,例如sts.cn-hangzhou.aliyuncs.com。
|
||
String endpoint = "sts.cn-shenzhen.aliyuncs.com";
|
||
// 填写步骤1生成的RAM用户访问密钥AccessKey ID和AccessKey Secret。
|
||
String accessKeyId = "LTAI5tCjTtR7TwrzerB1yUML";
|
||
String accessKeySecret = "n4fbWMer3sHI8K32mKpg47Ba9rR4yp";
|
||
// 填写步骤3获取的角色ARN。
|
||
String roleArn = "acs:ram::1470199532233684:role/wsoss";
|
||
// 自定义角色会话名称,用来区分不同的令牌,例如可填写为SessionTest。
|
||
String roleSessionName = "wsoss";
|
||
// 设置临时访问凭证的有效时间为3600秒。
|
||
Long durationSeconds = 3600L;
|
||
try {
|
||
// regionId表示RAM的地域ID。以华东1(杭州)地域为例,regionID填写为cn-hangzhou。也可以保留默认值,默认值为空字符串("")。
|
||
String regionId = "";
|
||
// 添加endpoint。适用于Java SDK 3.12.0及以上版本。
|
||
DefaultProfile.addEndpoint(regionId, "Sts", endpoint);
|
||
// 构造default profile。
|
||
IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
|
||
// 构造client。
|
||
DefaultAcsClient client = new DefaultAcsClient(profile);
|
||
final AssumeRoleRequest request = new AssumeRoleRequest();
|
||
// 适用于Java SDK 3.12.0及以上版本。
|
||
request.setSysMethod(MethodType.POST);
|
||
// 适用于Java SDK 3.12.0以下版本。
|
||
//request.setMethod(MethodType.POST);
|
||
request.setRoleArn(roleArn);
|
||
request.setRoleSessionName(roleSessionName);
|
||
// request.setPolicy(policy);
|
||
request.setDurationSeconds(durationSeconds);
|
||
final AssumeRoleResponse response = client.getAcsResponse(request);
|
||
return success(response);
|
||
} catch (ClientException | com.aliyuncs.exceptions.ClientException e) {
|
||
System.out.println("Failed:");
|
||
System.out.println("Error message: " + e.getMessage());
|
||
return fail(e.getMessage());
|
||
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取前端表单提交的参数
|
||
* @return
|
||
*/
|
||
@ApiOperation("")
|
||
@GetMapping("/getPostForm")
|
||
public ApiResult<?> getPostForm(){
|
||
String endpoint = config.getEndpoint();
|
||
// RAM用户的访问密钥(AccessKey ID和AccessKey Secret)。
|
||
String accessKeyId = "LTAI5t8UTh8CTXEi2dYxobhj";
|
||
String accessKeySecret = "fNdJOT4KAjrVrzHNAcSJuUCy9ZljD9";
|
||
// 使用代码嵌入的RAM用户的访问密钥配置访问凭证。
|
||
CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);
|
||
// 填写Bucket名称,例如examplebucket。
|
||
String bucket = config.getBucketName();
|
||
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
|
||
|
||
try {
|
||
String host = "https://" + bucket + "." + endpoint;
|
||
String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
|
||
|
||
|
||
long expireTime = 60;
|
||
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
|
||
Date expiration = new Date(expireEndTime);
|
||
PolicyConditions policyConds = new PolicyConditions();
|
||
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE,0,100*1024*1024);
|
||
|
||
|
||
String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
|
||
byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
|
||
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
|
||
String postSignature = ossClient.calculatePostSignature(postPolicy);
|
||
Map result = new HashMap<>();
|
||
result.put("polocyBase64",encodedPolicy);
|
||
result.put("signature",postSignature);
|
||
result.put("expireEndTime",expireEndTime);
|
||
return success(result);
|
||
} finally {
|
||
ossClient.shutdown();
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* 文件上传位置(服务器)
|
||
*/
|
||
private String getUploadDir() {
|
||
return config.getUploadPath() + "file/";
|
||
}
|
||
}
|