第一次提交

This commit is contained in:
wyw
2024-08-08 00:31:26 +08:00
commit c202e2b63d
1819 changed files with 221890 additions and 0 deletions

View File

@ -0,0 +1,111 @@
package com.fastbee.oss.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fastbee.common.annotation.Log;
import com.fastbee.common.core.controller.BaseController;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.enums.BusinessType;
import com.fastbee.oss.domain.OssConfig;
import com.fastbee.oss.service.IOssConfigService;
import com.fastbee.common.utils.poi.ExcelUtil;
import com.fastbee.common.core.page.TableDataInfo;
/**
* 对象存储配置Controller
*
* @author zhuangpeng.li
* @date 2024-04-19
*/
@RestController
@RequestMapping("/oss/config")
public class OssConfigController extends BaseController
{
@Autowired
private IOssConfigService ossConfigService;
/**
* 查询对象存储配置列表
*/
@PreAuthorize("@ss.hasPermi('oss:config:list')")
@GetMapping("/list")
public TableDataInfo list(OssConfig ossConfig)
{
startPage();
List<OssConfig> list = ossConfigService.selectOssConfigList(ossConfig);
return getDataTable(list);
}
/**
* 导出对象存储配置列表
*/
@PreAuthorize("@ss.hasPermi('oss:config:export')")
@Log(title = "对象存储配置", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, OssConfig ossConfig)
{
List<OssConfig> list = ossConfigService.selectOssConfigList(ossConfig);
ExcelUtil<OssConfig> util = new ExcelUtil<OssConfig>(OssConfig.class);
util.exportExcel(response, list, "对象存储配置数据");
}
/**
* 获取对象存储配置详细信息
*/
@PreAuthorize("@ss.hasPermi('oss:config:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Integer id)
{
return success(ossConfigService.selectOssConfigById(id));
}
/**
* 新增对象存储配置
*/
@PreAuthorize("@ss.hasPermi('oss:config:add')")
@Log(title = "对象存储配置", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody OssConfig ossConfig)
{
return toAjax(ossConfigService.insertOssConfig(ossConfig));
}
/**
* 修改对象存储配置
*/
@PreAuthorize("@ss.hasPermi('oss:config:edit')")
@Log(title = "对象存储配置", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody OssConfig ossConfig)
{
return toAjax(ossConfigService.updateOssConfig(ossConfig));
}
/**
* 删除对象存储配置
*/
@PreAuthorize("@ss.hasPermi('oss:config:remove')")
@Log(title = "对象存储配置", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Integer[] ids)
{
return toAjax(ossConfigService.deleteOssConfigByIds(ids));
}
@Log(title = "对象存储状态修改", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public AjaxResult changeStatus(@RequestBody OssConfig bo) {
return toAjax(ossConfigService.updateOssConfigStatus(bo));
}
}

View File

@ -0,0 +1,123 @@
package com.fastbee.oss.controller;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.fastbee.common.annotation.Log;
import com.fastbee.common.core.controller.BaseController;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.enums.BusinessType;
import com.fastbee.oss.domain.OssDetail;
import com.fastbee.oss.service.IOssDetailService;
import com.fastbee.common.utils.poi.ExcelUtil;
import com.fastbee.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;
/**
* 文件记录Controller
*
* @author zhuangpeng.li
* @date 2024-04-22
*/
@RestController
@RequestMapping("/oss/detail")
public class OssDetailController extends BaseController {
@Autowired
private IOssDetailService ossDetailService;
/**
* 查询文件记录列表
*/
@PreAuthorize("@ss.hasPermi('oss:detail:list')")
@GetMapping("/list")
public TableDataInfo list(OssDetail ossDetail) {
startPage();
List<OssDetail> list = ossDetailService.selectOssDetailList(ossDetail);
return getDataTable(list);
}
/**
* 导出文件记录列表
*/
@PreAuthorize("@ss.hasPermi('oss:detail:export')")
@Log(title = "文件记录", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, OssDetail ossDetail) {
List<OssDetail> list = ossDetailService.selectOssDetailList(ossDetail);
ExcelUtil<OssDetail> util = new ExcelUtil<OssDetail>(OssDetail.class);
util.exportExcel(response, list, "文件记录数据");
}
/**
* 获取文件记录详细信息
*/
@PreAuthorize("@ss.hasPermi('oss:detail:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Integer id) {
return success(ossDetailService.selectOssDetailById(id));
}
/**
* 新增文件记录
*/
@PreAuthorize("@ss.hasPermi('oss:detail:add')")
@Log(title = "文件记录", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody OssDetail ossDetail) {
return toAjax(ossDetailService.insertOssDetail(ossDetail));
}
/**
* 修改文件记录
*/
@PreAuthorize("@ss.hasPermi('oss:detail:edit')")
@Log(title = "文件记录", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody OssDetail ossDetail) {
return toAjax(ossDetailService.updateOssDetail(ossDetail));
}
/**
* 删除文件记录
*/
@PreAuthorize("@ss.hasPermi('oss:detail:remove')")
@Log(title = "文件记录", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Integer[] ids) {
return toAjax(ossDetailService.deleteOssDetailByIds(ids));
}
/**
* 上传OSS对象存储
*
* @param file 文件
*/
@PreAuthorize("@ss.hasPermi('oss:detail:upload')")
@Log(title = "OSS对象存储", businessType = BusinessType.INSERT)
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public AjaxResult upload(@RequestPart("file") MultipartFile file) {
if (ObjectUtil.isNull(file)) {
return error("上传文件不能为空");
}
return toAjax(ossDetailService.upload(file));
}
/**
* 下载OSS对象
*
* @param ossId OSS对象ID
*/
@PreAuthorize("@ss.hasPermi('oss:detail:download')")
@GetMapping("/download/{ossId}")
public void download(@PathVariable Integer ossId, HttpServletResponse response) throws IOException {
ossDetailService.download(ossId, response);
}
}

View File

@ -0,0 +1,263 @@
package com.fastbee.oss.core;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.HttpMethod;
import com.amazonaws.Protocol;
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.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import com.fastbee.common.exception.GlobalException;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.oss.entity.OssConstant;
import com.fastbee.oss.entity.OssProperties;
import com.fastbee.oss.entity.UploadResult;
import com.fastbee.oss.enums.AccessPolicyType;
import com.fastbee.oss.enums.PolicyType;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
/**
* S3 存储协议 所有兼容S3协议的云厂商均支持
* 阿里云 腾讯云 七牛云 minio
*
*/
public class OssClient {
private final String configKey;
private final OssProperties properties;
private final AmazonS3 client;
public OssClient(String configKey, OssProperties ossProperties) {
this.configKey = configKey;
this.properties = ossProperties;
try {
AwsClientBuilder.EndpointConfiguration endpointConfig =
new AwsClientBuilder.EndpointConfiguration(properties.getEndpoint(), properties.getRegion());
AWSCredentials credentials = new BasicAWSCredentials(properties.getAccessKey(), properties.getSecretKey());
AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials);
ClientConfiguration clientConfig = new ClientConfiguration();
if (OssConstant.IS_HTTPS.equals(properties.getIsHttps())) {
clientConfig.setProtocol(Protocol.HTTPS);
} else {
clientConfig.setProtocol(Protocol.HTTP);
}
AmazonS3ClientBuilder build = AmazonS3Client.builder()
.withEndpointConfiguration(endpointConfig)
.withClientConfiguration(clientConfig)
.withCredentials(credentialsProvider)
.disableChunkedEncoding();
if (!StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE)) {
// minio 使用https限制使用域名访问 需要此配置 站点填域名
build.enablePathStyleAccess();
}
this.client = build.build();
createBucket();
} catch (Exception e) {
if (e instanceof GlobalException) {
throw e;
}
throw new GlobalException("配置错误! 请检查系统配置:[" + e.getMessage() + "]");
}
}
public void createBucket() {
try {
String bucketName = properties.getBucketName();
if (client.doesBucketExistV2(bucketName)) {
return;
}
CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
AccessPolicyType accessPolicy = getAccessPolicy();
createBucketRequest.setCannedAcl(accessPolicy.getAcl());
client.createBucket(createBucketRequest);
client.setBucketPolicy(bucketName, getPolicy(bucketName, accessPolicy.getPolicyType()));
} catch (Exception e) {
throw new GlobalException("创建Bucket失败, 请核对配置信息:[" + e.getMessage() + "]");
}
}
public UploadResult upload(byte[] data, String path, String contentType) {
return upload(new ByteArrayInputStream(data), path, contentType);
}
public UploadResult upload(InputStream inputStream, String path, String contentType) {
if (!(inputStream instanceof ByteArrayInputStream)) {
inputStream = new ByteArrayInputStream(IoUtil.readBytes(inputStream));
}
try {
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(contentType);
metadata.setContentLength(inputStream.available());
PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata);
// 设置上传对象的 Acl 为公共读
putObjectRequest.setCannedAcl(getAccessPolicy().getAcl());
client.putObject(putObjectRequest);
} catch (Exception e) {
throw new GlobalException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]");
}
return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build();
}
public UploadResult upload(File file, String path) {
try {
PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), path, file);
// 设置上传对象的 Acl 为公共读
putObjectRequest.setCannedAcl(getAccessPolicy().getAcl());
client.putObject(putObjectRequest);
} catch (Exception e) {
throw new GlobalException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]");
}
return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build();
}
public void delete(String path) {
path = path.replace(getUrl() + "/", "");
try {
client.deleteObject(properties.getBucketName(), path);
} catch (Exception e) {
throw new GlobalException("删除文件失败,请检查配置信息:[" + e.getMessage() + "]");
}
}
public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
return upload(data, getPath(properties.getPrefix(), suffix), contentType);
}
public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
}
public UploadResult uploadSuffix(File file, String suffix) {
return upload(file, getPath(properties.getPrefix(), suffix));
}
/**
* 获取文件元数据
*
* @param path 完整文件路径
*/
public ObjectMetadata getObjectMetadata(String path) {
path = path.replace(getUrl() + "/", "");
S3Object object = client.getObject(properties.getBucketName(), path);
return object.getObjectMetadata();
}
public InputStream getObjectContent(String path) {
path = path.replace(getUrl() + "/", "");
S3Object object = client.getObject(properties.getBucketName(), path);
return object.getObjectContent();
}
public String getUrl() {
String domain = properties.getDomain();
String endpoint = properties.getEndpoint();
String header = OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? "https://" : "http://";
// 云服务商直接返回
if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)) {
if (StringUtils.isNotBlank(domain)) {
return header + domain;
}
return header + properties.getBucketName() + "." + endpoint;
}
// minio 单独处理
if (StringUtils.isNotBlank(domain)) {
return header + domain + "/" + properties.getBucketName();
}
return header + endpoint + "/" + properties.getBucketName();
}
public String getPath(String prefix, String suffix) {
// 生成uuid
String uuid = IdUtil.fastSimpleUUID();
// 文件路径
String path = DateUtils.datePath() + "/" + uuid;
if (StringUtils.isNotBlank(prefix)) {
path = prefix + "/" + path;
}
return path + suffix;
}
public String getConfigKey() {
return configKey;
}
/**
* 获取私有URL链接
*
* @param objectKey 对象KEY
* @param second 授权时间
*/
public String getPrivateUrl(String objectKey, Integer second) {
GeneratePresignedUrlRequest generatePresignedUrlRequest =
new GeneratePresignedUrlRequest(properties.getBucketName(), objectKey)
.withMethod(HttpMethod.GET)
.withExpiration(new Date(System.currentTimeMillis() + 1000L * second));
URL url = client.generatePresignedUrl(generatePresignedUrlRequest);
return url.toString();
}
/**
* 检查配置是否相同
*/
public boolean checkPropertiesSame(OssProperties properties) {
return this.properties.equals(properties);
}
/**
* 获取当前桶权限类型
*
* @return 当前桶权限类型code
*/
public AccessPolicyType getAccessPolicy() {
return AccessPolicyType.getByType(properties.getAccessPolicy());
}
private static String getPolicy(String bucketName, PolicyType policyType) {
StringBuilder builder = new StringBuilder();
builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n");
switch (policyType) {
case WRITE: builder.append("\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n");
case READ_WRITE: builder.append("\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n");
default: builder.append("\"s3:GetBucketLocation\"\n");
}
builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
builder.append(bucketName);
builder.append("\"\n},\n");
if (policyType == PolicyType.READ) {
builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
builder.append(bucketName);
builder.append("\"\n},\n");
}
builder.append("{\n\"Action\": ");
switch (policyType) {
case WRITE: builder.append("[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n");
case READ_WRITE: builder.append("[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n");
default: builder.append("\"s3:GetObject\",\n");
}
builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
builder.append(bucketName);
builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n");
return builder.toString();
}
}

View File

@ -0,0 +1,251 @@
package com.fastbee.oss.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.fastbee.common.annotation.Excel;
import com.fastbee.common.core.domain.BaseEntity;
/**
* 对象存储配置对象 oss_config
*
* @author zhuangpeng.li
* @date 2024-04-19
*/
public class OssConfig extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** id */
private Integer id;
/** 租户ID */
@Excel(name = "租户ID")
private Long tenantId;
/** 租户名称 */
@Excel(name = "租户名称")
private String tenantName;
/** 配置key */
@Excel(name = "配置key")
private String configKey;
/** accessKey */
@Excel(name = "accessKey")
private String accessKey;
/** 秘钥 */
@Excel(name = "秘钥")
private String secretKey;
/** 桶名称 */
@Excel(name = "桶名称")
private String bucketName;
/** 前缀 */
@Excel(name = "前缀")
private String prefix;
/** 访问站点 */
@Excel(name = "访问站点")
private String endpoint;
/** 自定义域名 */
@Excel(name = "自定义域名")
private String domain;
/** 是否httpsY=是,N=否) */
@Excel(name = "是否https", readConverterExp = "Y==是,N=否")
private String isHttps;
/** 域 */
@Excel(name = "")
private String region;
/** 桶权限类型(0=private 1=public 2=custom) */
@Excel(name = "桶权限类型(0=private 1=public 2=custom)")
private String accessPolicy;
/** 是否默认0=是,1=否) */
@Excel(name = "是否默认", readConverterExp = "0==是,1=否")
private String status;
/** 扩展字段 */
@Excel(name = "扩展字段")
private String ext1;
/** 删除标志0代表存在 2代表删除 */
private String delFlag;
public void setId(Integer id)
{
this.id = id;
}
public Integer getId()
{
return id;
}
public void setTenantId(Long tenantId)
{
this.tenantId = tenantId;
}
public Long getTenantId()
{
return tenantId;
}
public void setTenantName(String tenantName)
{
this.tenantName = tenantName;
}
public String getTenantName()
{
return tenantName;
}
public void setConfigKey(String configKey)
{
this.configKey = configKey;
}
public String getConfigKey()
{
return configKey;
}
public void setAccessKey(String accessKey)
{
this.accessKey = accessKey;
}
public String getAccessKey()
{
return accessKey;
}
public void setSecretKey(String secretKey)
{
this.secretKey = secretKey;
}
public String getSecretKey()
{
return secretKey;
}
public void setBucketName(String bucketName)
{
this.bucketName = bucketName;
}
public String getBucketName()
{
return bucketName;
}
public void setPrefix(String prefix)
{
this.prefix = prefix;
}
public String getPrefix()
{
return prefix;
}
public void setEndpoint(String endpoint)
{
this.endpoint = endpoint;
}
public String getEndpoint()
{
return endpoint;
}
public void setDomain(String domain)
{
this.domain = domain;
}
public String getDomain()
{
return domain;
}
public void setIsHttps(String isHttps)
{
this.isHttps = isHttps;
}
public String getIsHttps()
{
return isHttps;
}
public void setRegion(String region)
{
this.region = region;
}
public String getRegion()
{
return region;
}
public void setAccessPolicy(String accessPolicy)
{
this.accessPolicy = accessPolicy;
}
public String getAccessPolicy()
{
return accessPolicy;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
public void setExt1(String ext1)
{
this.ext1 = ext1;
}
public String getExt1()
{
return ext1;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getDelFlag()
{
return delFlag;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("tenantId", getTenantId())
.append("tenantName", getTenantName())
.append("configKey", getConfigKey())
.append("accessKey", getAccessKey())
.append("secretKey", getSecretKey())
.append("bucketName", getBucketName())
.append("prefix", getPrefix())
.append("endpoint", getEndpoint())
.append("domain", getDomain())
.append("isHttps", getIsHttps())
.append("region", getRegion())
.append("accessPolicy", getAccessPolicy())
.append("status", getStatus())
.append("ext1", getExt1())
.append("delFlag", getDelFlag())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@ -0,0 +1,155 @@
package com.fastbee.oss.domain;
import lombok.Builder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.fastbee.common.annotation.Excel;
import com.fastbee.common.core.domain.BaseEntity;
/**
* 文件记录对象 oss_detail
*
* @author zhuangpeng.li
* @date 2024-04-22
*/
@Builder
public class OssDetail extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 文件id */
private Integer id;
/** 租户ID */
@Excel(name = "租户ID")
private Long tenantId;
/** 租户名称 */
@Excel(name = "租户名称")
private String tenantName;
/** 文件名 */
@Excel(name = "文件名")
private String fileName;
/** 原名 */
@Excel(name = "原名")
private String originalName;
/** 文件后缀名 */
@Excel(name = "文件后缀名")
private String fileSuffix;
/** URL地址 */
@Excel(name = "URL地址")
private String url;
/** 服务商 */
@Excel(name = "服务商")
private String service;
/** 删除标志0代表存在 2代表删除 */
private String delFlag;
public void setId(Integer id)
{
this.id = id;
}
public Integer getId()
{
return id;
}
public void setTenantId(Long tenantId)
{
this.tenantId = tenantId;
}
public Long getTenantId()
{
return tenantId;
}
public void setTenantName(String tenantName)
{
this.tenantName = tenantName;
}
public String getTenantName()
{
return tenantName;
}
public void setFileName(String fileName)
{
this.fileName = fileName;
}
public String getFileName()
{
return fileName;
}
public void setOriginalName(String originalName)
{
this.originalName = originalName;
}
public String getOriginalName()
{
return originalName;
}
public void setFileSuffix(String fileSuffix)
{
this.fileSuffix = fileSuffix;
}
public String getFileSuffix()
{
return fileSuffix;
}
public void setUrl(String url)
{
this.url = url;
}
public String getUrl()
{
return url;
}
public void setService(String service)
{
this.service = service;
}
public String getService()
{
return service;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getDelFlag()
{
return delFlag;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("tenantId", getTenantId())
.append("tenantName", getTenantName())
.append("fileName", getFileName())
.append("originalName", getOriginalName())
.append("fileSuffix", getFileSuffix())
.append("url", getUrl())
.append("service", getService())
.append("delFlag", getDelFlag())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@ -0,0 +1,39 @@
package com.fastbee.oss.entity;
import java.util.Arrays;
import java.util.List;
/**
* 对象存储常量
*
*/
public interface OssConstant {
/**
* 默认配置KEY
*/
String DEFAULT_CONFIG_KEY = "sys_oss:default_config";
String OSS_CONFIG_KEY = "sys_oss:config";
/**
* 预览列表资源开关Key
*/
String PEREVIEW_LIST_RESOURCE_KEY = "sys.oss.previewListResource";
/**
* 系统数据ids
*/
List<Long> SYSTEM_DATA_IDS = Arrays.asList(1L, 2L, 3L, 4L);
/**
* 云服务商
*/
String[] CLOUD_SERVICE = new String[] {"aliyun", "qcloud", "qiniu", "obs"};
/**
* https 状态
*/
String IS_HTTPS = "Y";
}

View File

@ -0,0 +1,58 @@
package com.fastbee.oss.entity;
import lombok.Data;
@Data
public class OssProperties {
/**
* 租户id
*/
private String tenantId;
/**
* 访问站点
*/
private String endpoint;
/**
* 自定义域名
*/
private String domain;
/**
* 前缀
*/
private String prefix;
/**
* ACCESS_KEY
*/
private String accessKey;
/**
* SECRET_KEY
*/
private String secretKey;
/**
* 存储空间名
*/
private String bucketName;
/**
* 存储区域
*/
private String region;
/**
* 是否httpsY=是,N=否)
*/
private String isHttps;
/**
* 桶权限类型(0private 1public 2custom)
*/
private String accessPolicy;
}

View File

@ -0,0 +1,23 @@
package com.fastbee.oss.entity;
import lombok.Builder;
import lombok.Data;
/**
* 上传返回体
*
*/
@Data
@Builder
public class UploadResult {
/**
* 文件路径
*/
private String url;
/**
* 文件名
*/
private String filename;
}

View File

@ -0,0 +1,54 @@
package com.fastbee.oss.enums;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 桶访问策略配置
*
*/
@Getter
@AllArgsConstructor
public enum AccessPolicyType {
/**
* private
*/
PRIVATE("0", CannedAccessControlList.Private, PolicyType.WRITE),
/**
* public
*/
PUBLIC("1", CannedAccessControlList.PublicRead, PolicyType.READ),
/**
* custom
*/
CUSTOM("2",CannedAccessControlList.PublicRead, PolicyType.READ);
/**
* 桶 权限类型
*/
private final String type;
/**
* 文件对象 权限类型
*/
private final CannedAccessControlList acl;
/**
* 桶策略类型
*/
private final PolicyType policyType;
public static AccessPolicyType getByType(String type) {
for (AccessPolicyType value : values()) {
if (value.getType().equals(type)) {
return value;
}
}
throw new RuntimeException("'type' not found By " + type);
}
}

View File

@ -0,0 +1,32 @@
package com.fastbee.oss.enums;
import com.fastbee.common.utils.StringUtils;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Objects;
@AllArgsConstructor
@Getter
public enum PlatformType {
UNKNOWN(0, "未知"),
LOCAL(1, "本地"),
TENCENT(2, "腾讯云"),
ALIYUN(3, "阿里云"),
QINIU(4, "七牛云");
private final Integer value;
private final String text;
public static PlatformType getTypeByValue(Integer value){
if (StringUtils.isNull(value)){
return null;
}
for (PlatformType enums : PlatformType.values()) {
if (Objects.equals(enums.getValue(), value)) {
return enums;
}
}
return null;
}
}

View File

@ -0,0 +1,34 @@
package com.fastbee.oss.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* minio策略配置
*
*/
@Getter
@AllArgsConstructor
public enum PolicyType {
/**
* 只读
*/
READ("read-only"),
/**
* 只写
*/
WRITE("write-only"),
/**
* 读写
*/
READ_WRITE("read-write");
/**
* 类型
*/
private final String type;
}

View File

@ -0,0 +1,63 @@
package com.fastbee.oss.mapper;
import java.util.List;
import com.fastbee.oss.domain.OssConfig;
/**
* 对象存储配置Mapper接口
*
* @author zhuangpeng.li
* @date 2024-04-19
*/
public interface OssConfigMapper
{
/**
* 查询对象存储配置
*
* @param id 对象存储配置主键
* @return 对象存储配置
*/
public OssConfig selectOssConfigById(Integer id);
/**
* 查询对象存储配置列表
*
* @param ossConfig 对象存储配置
* @return 对象存储配置集合
*/
public List<OssConfig> selectOssConfigList(OssConfig ossConfig);
/**
* 新增对象存储配置
*
* @param ossConfig 对象存储配置
* @return 结果
*/
public int insertOssConfig(OssConfig ossConfig);
/**
* 修改对象存储配置
*
* @param ossConfig 对象存储配置
* @return 结果
*/
public int updateOssConfig(OssConfig ossConfig);
/**
* 删除对象存储配置
*
* @param id 对象存储配置主键
* @return 结果
*/
public int deleteOssConfigById(Integer id);
/**
* 批量删除对象存储配置
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteOssConfigByIds(Integer[] ids);
public int resetConfigStatus();
}

View File

@ -0,0 +1,61 @@
package com.fastbee.oss.mapper;
import java.util.List;
import com.fastbee.oss.domain.OssDetail;
/**
* 文件记录Mapper接口
*
* @author zhuangpeng.li
* @date 2024-04-19
*/
public interface OssDetailMapper
{
/**
* 查询文件记录
*
* @param id 文件记录主键
* @return 文件记录
*/
public OssDetail selectOssDetailById(Integer id);
/**
* 查询文件记录列表
*
* @param ossDetail 文件记录
* @return 文件记录集合
*/
public List<OssDetail> selectOssDetailList(OssDetail ossDetail);
/**
* 新增文件记录
*
* @param ossDetail 文件记录
* @return 结果
*/
public int insertOssDetail(OssDetail ossDetail);
/**
* 修改文件记录
*
* @param ossDetail 文件记录
* @return 结果
*/
public int updateOssDetail(OssDetail ossDetail);
/**
* 删除文件记录
*
* @param id 文件记录主键
* @return 结果
*/
public int deleteOssDetailById(Integer id);
/**
* 批量删除文件记录
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteOssDetailByIds(Integer[] ids);
}

View File

@ -0,0 +1,25 @@
package com.fastbee.oss.runner;
import com.fastbee.oss.service.IOssConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@Order(3)
public class OssApplicationRunner implements ApplicationRunner {
@Autowired
private IOssConfigService ossConfigService;
@Override
public void run(ApplicationArguments args) throws Exception {
ossConfigService.init();
log.info("初始化OSS配置成功");
}
}

View File

@ -0,0 +1,70 @@
package com.fastbee.oss.service;
import java.util.List;
import com.fastbee.oss.domain.OssConfig;
/**
* 对象存储配置Service接口
*
* @author zhuangpeng.li
* @date 2024-04-19
*/
public interface IOssConfigService
{
/**
* 初始化OSS配置
*/
void init();
/**
* 查询对象存储配置
*
* @param id 对象存储配置主键
* @return 对象存储配置
*/
public OssConfig selectOssConfigById(Integer id);
/**
* 查询对象存储配置列表
*
* @param ossConfig 对象存储配置
* @return 对象存储配置集合
*/
public List<OssConfig> selectOssConfigList(OssConfig ossConfig);
/**
* 新增对象存储配置
*
* @param ossConfig 对象存储配置
* @return 结果
*/
public int insertOssConfig(OssConfig ossConfig);
/**
* 修改对象存储配置
*
* @param ossConfig 对象存储配置
* @return 结果
*/
public int updateOssConfig(OssConfig ossConfig);
/**
* 批量删除对象存储配置
*
* @param ids 需要删除的对象存储配置主键集合
* @return 结果
*/
public int deleteOssConfigByIds(Integer[] ids);
/**
* 删除对象存储配置信息
*
* @param id 对象存储配置主键
* @return 结果
*/
public int deleteOssConfigById(Integer id);
/**
* 启用停用状态
*/
int updateOssConfigStatus(OssConfig ossConfig);
}

View File

@ -0,0 +1,72 @@
package com.fastbee.oss.service;
import java.io.File;
import java.io.IOException;
import java.util.List;
import com.fastbee.oss.domain.OssDetail;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
/**
* 文件记录Service接口
*
* @author zhuangpeng.li
* @date 2024-04-19
*/
public interface IOssDetailService
{
/**
* 查询文件记录
*
* @param id 文件记录主键
* @return 文件记录
*/
public OssDetail selectOssDetailById(Integer id);
/**
* 查询文件记录列表
*
* @param ossDetail 文件记录
* @return 文件记录集合
*/
public List<OssDetail> selectOssDetailList(OssDetail ossDetail);
/**
* 新增文件记录
*
* @param ossDetail 文件记录
* @return 结果
*/
public int insertOssDetail(OssDetail ossDetail);
/**
* 修改文件记录
*
* @param ossDetail 文件记录
* @return 结果
*/
public int updateOssDetail(OssDetail ossDetail);
/**
* 批量删除文件记录
*
* @param ids 需要删除的文件记录主键集合
* @return 结果
*/
public int deleteOssDetailByIds(Integer[] ids);
/**
* 删除文件记录信息
*
* @param id 文件记录主键
* @return 结果
*/
public int deleteOssDetailById(Integer id);
OssDetail upload(MultipartFile file);
OssDetail upload(File file);
void download(Integer ossId, HttpServletResponse response) throws IOException;
}

View File

@ -0,0 +1,265 @@
package com.fastbee.oss.service;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.HttpMethod;
import com.amazonaws.Protocol;
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.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import com.fastbee.common.exception.GlobalException;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.oss.domain.OssConfig;
import com.fastbee.oss.entity.OssConstant;
import com.fastbee.oss.entity.UploadResult;
import com.fastbee.oss.enums.AccessPolicyType;
import com.fastbee.oss.enums.PolicyType;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
/**
* S3 存储协议 所有兼容S3协议的云厂商均支持
* 阿里云 腾讯云 七牛云 minio
*
*/
public class OssClient {
private final String configKey;
private final OssConfig properties;
private final AmazonS3 client;
public OssClient(String configKey, OssConfig ossProperties) {
this.configKey = configKey;
this.properties = ossProperties;
try {
AwsClientBuilder.EndpointConfiguration endpointConfig =
new AwsClientBuilder.EndpointConfiguration(properties.getEndpoint(), properties.getRegion());
AWSCredentials credentials = new BasicAWSCredentials(properties.getAccessKey(), properties.getSecretKey());
AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials);
ClientConfiguration clientConfig = new ClientConfiguration();
if (OssConstant.IS_HTTPS.equals(properties.getIsHttps())) {
clientConfig.setProtocol(Protocol.HTTPS);
} else {
clientConfig.setProtocol(Protocol.HTTP);
}
AmazonS3ClientBuilder build = AmazonS3Client.builder()
.withEndpointConfiguration(endpointConfig)
.withClientConfiguration(clientConfig)
.withCredentials(credentialsProvider)
.disableChunkedEncoding();
if (!StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE)) {
// minio 使用https限制使用域名访问 需要此配置 站点填域名
build.enablePathStyleAccess();
}
this.client = build.build();
createBucket();
} catch (Exception e) {
if (e instanceof GlobalException) {
throw e;
}
throw new GlobalException("配置错误! 请检查系统配置:[" + e.getMessage() + "]");
}
}
public void createBucket() {
try {
String bucketName = properties.getBucketName();
if (client.doesBucketExistV2(bucketName)) {
return;
}
CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
AccessPolicyType accessPolicy = getAccessPolicy();
createBucketRequest.setCannedAcl(accessPolicy.getAcl());
client.createBucket(createBucketRequest);
client.setBucketPolicy(bucketName, getPolicy(bucketName, accessPolicy.getPolicyType()));
} catch (Exception e) {
throw new GlobalException("创建Bucket失败, 请核对配置信息:[" + e.getMessage() + "]");
}
}
public UploadResult upload(byte[] data, String path, String contentType) {
return upload(new ByteArrayInputStream(data), path, contentType);
}
public UploadResult upload(InputStream inputStream, String path, String contentType) {
if (!(inputStream instanceof ByteArrayInputStream)) {
inputStream = new ByteArrayInputStream(IoUtil.readBytes(inputStream));
}
try {
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(contentType);
metadata.setContentLength(inputStream.available());
PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata);
if(getAccessPolicy().getAcl() != null) {
// 设置上传对象的 Acl 为公共读
putObjectRequest.setCannedAcl(getAccessPolicy().getAcl());
}
client.putObject(putObjectRequest);
} catch (Exception e) {
throw new GlobalException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]");
}
return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build();
}
public UploadResult upload(File file, String path) {
try {
PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), path, file);
// 设置上传对象的 Acl 为公共读
putObjectRequest.setCannedAcl(getAccessPolicy().getAcl());
client.putObject(putObjectRequest);
} catch (Exception e) {
throw new GlobalException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]");
}
return UploadResult.builder().url(getUrl() + "/" + path).filename(path).build();
}
public void delete(String path) {
path = path.replace(getUrl() + "/", "");
try {
client.deleteObject(properties.getBucketName(), path);
} catch (Exception e) {
throw new GlobalException("删除文件失败,请检查配置信息:[" + e.getMessage() + "]");
}
}
public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
return upload(data, getPath(properties.getPrefix(), suffix), contentType);
}
public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
}
public UploadResult uploadSuffix(File file, String suffix) {
return upload(file, getPath(properties.getPrefix(), suffix));
}
/**
* 获取文件元数据
*
* @param path 完整文件路径
*/
public ObjectMetadata getObjectMetadata(String path) {
path = path.replace(getUrl() + "/", "");
S3Object object = client.getObject(properties.getBucketName(), path);
return object.getObjectMetadata();
}
public InputStream getObjectContent(String path) {
path = path.replace(getUrl() + "/", "");
S3Object object = client.getObject(properties.getBucketName(), path);
return object.getObjectContent();
}
public String getUrl() {
String domain = properties.getDomain();
String endpoint = properties.getEndpoint();
String header = OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? "https://" : "http://";
// 云服务商直接返回
if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)) {
if (StringUtils.isNotBlank(domain)) {
return header + domain;
}
return header + properties.getBucketName() + "." + endpoint;
}
// minio 单独处理
if (StringUtils.isNotBlank(domain)) {
return header + domain + "/" + properties.getBucketName();
}
return header + endpoint + "/" + properties.getBucketName();
}
public String getPath(String prefix, String suffix) {
// 生成uuid
String uuid = IdUtil.fastSimpleUUID();
// 文件路径
String path = DateUtils.datePath() + "/" + uuid;
if (StringUtils.isNotBlank(prefix)) {
path = prefix + "/" + path;
}
return path + suffix;
}
public String getConfigKey() {
return configKey;
}
/**
* 获取私有URL链接
*
* @param objectKey 对象KEY
* @param second 授权时间
*/
public String getPrivateUrl(String objectKey, Integer second) {
GeneratePresignedUrlRequest generatePresignedUrlRequest =
new GeneratePresignedUrlRequest(properties.getBucketName(), objectKey)
.withMethod(HttpMethod.GET)
.withExpiration(new Date(System.currentTimeMillis() + 1000L * second));
URL url = client.generatePresignedUrl(generatePresignedUrlRequest);
return url.toString();
}
/**
* 检查配置是否相同
*/
public boolean checkPropertiesSame(OssConfig properties) {
return this.properties.equals(properties);
}
/**
* 获取当前桶权限类型
*
* @return 当前桶权限类型code
*/
public AccessPolicyType getAccessPolicy() {
return AccessPolicyType.getByType(properties.getAccessPolicy());
}
private static String getPolicy(String bucketName, PolicyType policyType) {
StringBuilder builder = new StringBuilder();
builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n");
switch (policyType) {
case WRITE: builder.append("\"s3:GetBucketLocation\",\n\"s3:ListBucketMultipartUploads\"\n");
case READ_WRITE: builder.append("\"s3:GetBucketLocation\",\n\"s3:ListBucket\",\n\"s3:ListBucketMultipartUploads\"\n");
default: builder.append("\"s3:GetBucketLocation\"\n");
}
builder.append("],\n\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
builder.append(bucketName);
builder.append("\"\n},\n");
if (policyType == PolicyType.READ) {
builder.append("{\n\"Action\": [\n\"s3:ListBucket\"\n],\n\"Effect\": \"Deny\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
builder.append(bucketName);
builder.append("\"\n},\n");
}
builder.append("{\n\"Action\": ");
switch (policyType) {
case WRITE: builder.append("[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n");
case READ_WRITE: builder.append("[\n\"s3:AbortMultipartUpload\",\n\"s3:DeleteObject\",\n\"s3:GetObject\",\n\"s3:ListMultipartUploadParts\",\n\"s3:PutObject\"\n],\n");
default: builder.append("\"s3:GetObject\",\n");
}
builder.append("\"Effect\": \"Allow\",\n\"Principal\": \"*\",\n\"Resource\": \"arn:aws:s3:::");
builder.append(bucketName);
builder.append("/*\"\n}\n],\n\"Version\": \"2012-10-17\"\n}\n");
return builder.toString();
}
}

View File

@ -0,0 +1,58 @@
package com.fastbee.oss.service;
import com.fastbee.common.core.redis.RedisCache;
import com.fastbee.common.exception.GlobalException;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.oss.domain.OssConfig;
import com.fastbee.oss.entity.OssConstant;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
public class OssFactory {
private static final Map<String, OssClient> CLIENT_CACHE = new ConcurrentHashMap<>();
/**
* 获取默认实例
*/
public static OssClient instance(RedisCache redis) {
//获取redis 操作类
String configKey = redis.getCacheObject(OssConstant.DEFAULT_CONFIG_KEY);
if (StringUtils.isEmpty(configKey)) {
throw new GlobalException("文件存储服务类型无法找到!");
}
return instance(configKey, redis);
}
/**
* 根据类型获取实例
*/
public static synchronized OssClient instance(String configKey, RedisCache redis) {
OssConfig config = redis.getCacheObject(OssConstant.OSS_CONFIG_KEY + configKey);
if (config == null) {
throw new GlobalException("系统异常, '" + configKey + "'配置信息不存在!");
}
// 使用租户标识避免多个租户相同key实例覆盖
String key = config.getTenantId() + ":" + configKey;
OssClient client = CLIENT_CACHE.get(key);
if (client == null) {
CLIENT_CACHE.put(key, new OssClient(configKey, config));
log.info("创建OSS实例 key => {}", configKey);
return CLIENT_CACHE.get(key);
}
// 配置不相同则重新构建
if (!client.checkPropertiesSame(config)) {
CLIENT_CACHE.put(key, new OssClient(configKey, config));
log.info("重载OSS实例 key => {}", configKey);
return CLIENT_CACHE.get(key);
}
return client;
}
}

View File

@ -0,0 +1,154 @@
package com.fastbee.oss.service.impl;
import java.util.List;
import com.fastbee.common.core.domain.entity.SysUser;
import com.fastbee.common.core.redis.RedisCache;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.oss.entity.OssConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import com.fastbee.oss.mapper.OssConfigMapper;
import com.fastbee.oss.domain.OssConfig;
import com.fastbee.oss.service.IOssConfigService;
import static com.fastbee.common.utils.SecurityUtils.getLoginUser;
import static com.fastbee.common.utils.SecurityUtils.isAdmin;
/**
* 对象存储配置Service业务层处理
*
* @author zhuangpeng.li
* @date 2024-04-19
*/
@Service
public class OssConfigServiceImpl implements IOssConfigService
{
@Autowired
private OssConfigMapper ossConfigMapper;
@Autowired
private RedisCache redisCache;
@Override
public void init() {
List<OssConfig> list = ossConfigMapper.selectOssConfigList(null);
// 加载OSS初始化配置
for (OssConfig config : list) {
String configKey = config.getConfigKey();
if ("0".equals(config.getStatus())) {
redisCache.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, configKey);
}
redisCache.setCacheObject(OssConstant.OSS_CONFIG_KEY+configKey, config);
}
}
/**
* 查询对象存储配置
*
* @param id 对象存储配置主键
* @return 对象存储配置
*/
@Cacheable(value = "ossConfig", key = "#root.methodName + '_' + #id", unless = "#result == null")
@Override
public OssConfig selectOssConfigById(Integer id)
{
return ossConfigMapper.selectOssConfigById(id);
}
/**
* 查询对象存储配置列表
*
* @param ossConfig 对象存储配置
* @return 对象存储配置
*/
@Override
public List<OssConfig> selectOssConfigList(OssConfig ossConfig)
{
SysUser user = getLoginUser().getUser();
ossConfig.setTenantId(user.getDept().getDeptUserId());
return ossConfigMapper.selectOssConfigList(ossConfig);
}
/**
* 新增对象存储配置
*
* @param ossConfig 对象存储配置
* @return 结果
*/
@Caching(put = {
@CachePut(value = "ossConfig", key = "'selectOssConfigById' + '_' + #ossConfig.getId()"),
})
@Override
public int insertOssConfig(OssConfig ossConfig)
{
SysUser user = getLoginUser().getUser();
if (null == user.getDeptId()) {
throw new ServiceException("只允许租户配置");
}
ossConfig.setTenantId(user.getDept().getDeptUserId());
ossConfig.setTenantName(user.getDept().getDeptUserName());
ossConfig.setCreateTime(DateUtils.getNowDate());
redisCache.setCacheObject(OssConstant.OSS_CONFIG_KEY+ossConfig.getConfigKey(), ossConfig);
return ossConfigMapper.insertOssConfig(ossConfig);
}
/**
* 修改对象存储配置
*
* @param ossConfig 对象存储配置
* @return 结果
*/
@Caching(put = {
@CachePut(value = "ossConfig", key = "'selectOssConfigById' + '_' + #ossConfig.getId()"),
})
@Override
public int updateOssConfig(OssConfig ossConfig)
{
ossConfig.setUpdateTime(DateUtils.getNowDate());
redisCache.setCacheObject(OssConstant.OSS_CONFIG_KEY+ossConfig.getConfigKey(), ossConfig);
return ossConfigMapper.updateOssConfig(ossConfig);
}
/**
* 批量删除对象存储配置
*
* @param ids 需要删除的对象存储配置主键
* @return 结果
*/
@CacheEvict(value = "ossConfig", allEntries = true)
@Override
public int deleteOssConfigByIds(Integer[] ids)
{
return ossConfigMapper.deleteOssConfigByIds(ids);
}
/**
* 删除对象存储配置信息
*
* @param id 对象存储配置主键
* @return 结果
*/
@CacheEvict(value = "ossConfig", allEntries = true)
@Override
public int deleteOssConfigById(Integer id)
{
return ossConfigMapper.deleteOssConfigById(id);
}
@Override
public int updateOssConfigStatus(OssConfig ossConfig) {
//重置其他配置状态
ossConfigMapper.resetConfigStatus();
int row = ossConfigMapper.updateOssConfig(ossConfig);
if (row > 0) {
redisCache.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, ossConfig.getConfigKey());
}
return row;
}
}

View File

@ -0,0 +1,198 @@
package com.fastbee.oss.service.impl;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import com.fastbee.common.core.domain.entity.SysUser;
import com.fastbee.common.core.redis.RedisCache;
import com.fastbee.common.exception.GlobalException;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.common.utils.file.FileUtils;
import com.fastbee.oss.service.OssClient;
import com.fastbee.oss.entity.UploadResult;
import com.fastbee.oss.enums.AccessPolicyType;
import com.fastbee.oss.service.OssFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import com.fastbee.oss.mapper.OssDetailMapper;
import com.fastbee.oss.domain.OssDetail;
import com.fastbee.oss.service.IOssDetailService;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import static com.fastbee.common.utils.SecurityUtils.getLoginUser;
/**
* 文件记录Service业务层处理
*
* @author zhuangpeng.li
* @date 2024-04-19
*/
@Service
public class OssDetailServiceImpl implements IOssDetailService {
@Autowired
private OssDetailMapper ossDetailMapper;
@Autowired
private RedisCache redisCache;
/**
* 查询文件记录
*
* @param id 文件记录主键
* @return 文件记录
*/
@Override
public OssDetail selectOssDetailById(Integer id) {
return ossDetailMapper.selectOssDetailById(id);
}
/**
* 查询文件记录列表
*
* @param ossDetail 文件记录
* @return 文件记录
*/
@Override
public List<OssDetail> selectOssDetailList(OssDetail ossDetail) {
SysUser user = getLoginUser().getUser();
ossDetail.setTenantId(user.getDept().getDeptUserId());
return ossDetailMapper.selectOssDetailList(ossDetail);
}
/**
* 新增文件记录
*
* @param ossDetail 文件记录
* @return 结果
*/
@Override
public int insertOssDetail(OssDetail ossDetail) {
SysUser user = getLoginUser().getUser();
ossDetail.setTenantId(user.getDept().getDeptUserId());
ossDetail.setCreateTime(DateUtils.getNowDate());
return ossDetailMapper.insertOssDetail(ossDetail);
}
/**
* 修改文件记录
*
* @param ossDetail 文件记录
* @return 结果
*/
@Override
public int updateOssDetail(OssDetail ossDetail) {
ossDetail.setUpdateTime(DateUtils.getNowDate());
return ossDetailMapper.updateOssDetail(ossDetail);
}
/**
* 批量删除文件记录
*
* @param ids 需要删除的文件记录主键
* @return 结果
*/
@Override
public int deleteOssDetailByIds(Integer[] ids) {
OssClient storage = OssFactory.instance(redisCache);
for (Integer id : ids) {
OssDetail detail = selectOssDetailById(id);
if (detail != null) {
storage.delete(detail.getUrl());
return ossDetailMapper.deleteOssDetailById(id);
} else {
return -1;
}
}
return -1;
}
/**
* 删除文件记录信息
*
* @param id 文件记录主键
* @return 结果
*/
@Override
public int deleteOssDetailById(Integer id) {
OssDetail detail = selectOssDetailById(id);
if (detail != null) {
OssClient storage = OssFactory.instance(redisCache);
storage.delete(detail.getUrl());
return ossDetailMapper.deleteOssDetailById(id);
} else {
return -1;
}
}
@Override
public OssDetail upload(MultipartFile file) {
String originalfileName = file.getOriginalFilename();
String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
OssClient storage = OssFactory.instance(redisCache);
UploadResult uploadResult;
try {
uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType());
} catch (IOException e) {
throw new GlobalException(e.getMessage());
}
// 保存文件信息
return buildResultEntity(originalfileName, suffix, storage.getConfigKey(), uploadResult);
}
@Override
public OssDetail upload(File file) {
String originalfileName = file.getName();
String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
OssClient storage = OssFactory.instance(redisCache);
UploadResult uploadResult = storage.uploadSuffix(file, suffix);
// 保存文件信息
return buildResultEntity(originalfileName, suffix, storage.getConfigKey(), uploadResult);
}
private OssDetail buildResultEntity(String originalfileName, String suffix, String configKey, UploadResult uploadResult) {
OssDetail oss = OssDetail.builder()
.url(uploadResult.getUrl())
.fileSuffix(suffix)
.fileName(uploadResult.getFilename())
.originalName(originalfileName)
.service(configKey)
.build();
this.insertOssDetail(oss);
return this.matchingUrl(oss);
}
private OssDetail matchingUrl(OssDetail oss) {
OssClient storage = OssFactory.instance(oss.getService(), redisCache);
// 仅修改桶类型为 private 的URL临时URL时长为120s
if (AccessPolicyType.PRIVATE == storage.getAccessPolicy()) {
oss.setUrl(storage.getPrivateUrl(oss.getFileName(), 120));
}
return oss;
}
@Override
public void download(Integer ossId, HttpServletResponse response) throws IOException {
OssDetail sysOss = ossDetailMapper.selectOssDetailById(ossId);
if (ObjectUtil.isNull(sysOss)) {
throw new GlobalException("文件数据不存在!");
}
FileUtils.setAttachmentResponseHeader(response, sysOss.getOriginalName());
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");
OssClient storage = OssFactory.instance(sysOss.getService(), redisCache);
try (InputStream inputStream = storage.getObjectContent(sysOss.getUrl())) {
int available = inputStream.available();
IoUtil.copy(inputStream, response.getOutputStream(), available);
response.setContentLength(available);
} catch (Exception e) {
throw new GlobalException(e.getMessage());
}
}
}

View File

@ -0,0 +1,152 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fastbee.oss.mapper.OssConfigMapper">
<resultMap type="com.fastbee.oss.domain.OssConfig" id="OssConfigResult">
<result property="id" column="id" />
<result property="tenantId" column="tenant_id" />
<result property="tenantName" column="tenant_name" />
<result property="configKey" column="config_key" />
<result property="accessKey" column="access_key" />
<result property="secretKey" column="secret_key" />
<result property="bucketName" column="bucket_name" />
<result property="prefix" column="prefix" />
<result property="endpoint" column="endpoint" />
<result property="domain" column="domain" />
<result property="isHttps" column="is_https" />
<result property="region" column="region" />
<result property="accessPolicy" column="access_policy" />
<result property="status" column="status" />
<result property="ext1" column="ext1" />
<result property="delFlag" column="del_flag" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectOssConfigVo">
select id, tenant_id, tenant_name, config_key, access_key, secret_key, bucket_name, prefix, endpoint, domain, is_https, region, access_policy, status, ext1, del_flag, create_by, create_time, update_by, update_time, remark from oss_config
</sql>
<select id="selectOssConfigList" parameterType="com.fastbee.oss.domain.OssConfig" resultMap="OssConfigResult">
<include refid="selectOssConfigVo"/>
<where>
<if test="tenantId != null "> and tenant_id = #{tenantId}</if>
<if test="tenantName != null and tenantName != ''"> and tenant_name like concat('%', #{tenantName}, '%')</if>
<if test="configKey != null and configKey != ''"> and config_key = #{configKey}</if>
<if test="accessKey != null and accessKey != ''"> and access_key = #{accessKey}</if>
<if test="secretKey != null and secretKey != ''"> and secret_key = #{secretKey}</if>
<if test="bucketName != null and bucketName != ''"> and bucket_name like concat('%', #{bucketName}, '%')</if>
<if test="prefix != null and prefix != ''"> and prefix = #{prefix}</if>
<if test="endpoint != null and endpoint != ''"> and endpoint = #{endpoint}</if>
<if test="domain != null and domain != ''"> and domain = #{domain}</if>
<if test="isHttps != null and isHttps != ''"> and is_https = #{isHttps}</if>
<if test="region != null and region != ''"> and region = #{region}</if>
<if test="accessPolicy != null and accessPolicy != ''"> and access_policy = #{accessPolicy}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
<if test="ext1 != null and ext1 != ''"> and ext1 = #{ext1}</if>
</where>
</select>
<select id="selectOssConfigById" parameterType="Integer" resultMap="OssConfigResult">
<include refid="selectOssConfigVo"/>
where id = #{id}
</select>
<insert id="insertOssConfig" parameterType="com.fastbee.oss.domain.OssConfig" useGeneratedKeys="true" keyProperty="id">
insert into oss_config
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="tenantId != null">tenant_id,</if>
<if test="tenantName != null and tenantName != ''">tenant_name,</if>
<if test="configKey != null and configKey != ''">config_key,</if>
<if test="accessKey != null and accessKey != ''">access_key,</if>
<if test="secretKey != null and secretKey != ''">secret_key,</if>
<if test="bucketName != null and bucketName != ''">bucket_name,</if>
<if test="prefix != null and prefix != ''">prefix,</if>
<if test="endpoint != null and endpoint != ''">endpoint,</if>
<if test="domain != null and domain != ''">domain,</if>
<if test="isHttps != null and isHttps != ''">is_https,</if>
<if test="region != null and region != ''">region,</if>
<if test="accessPolicy != null and accessPolicy != ''">access_policy,</if>
<if test="status != null and status != ''">status,</if>
<if test="ext1 != null and ext1 != ''">ext1,</if>
<if test="delFlag != null and delFlag != ''">del_flag,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="tenantId != null">#{tenantId},</if>
<if test="tenantName != null and tenantName != ''">#{tenantName},</if>
<if test="configKey != null and configKey != ''">#{configKey},</if>
<if test="accessKey != null and accessKey != ''">#{accessKey},</if>
<if test="secretKey != null and secretKey != ''">#{secretKey},</if>
<if test="bucketName != null and bucketName != ''">#{bucketName},</if>
<if test="prefix != null and prefix != ''">#{prefix},</if>
<if test="endpoint != null and endpoint != ''">#{endpoint},</if>
<if test="domain != null and domain != ''">#{domain},</if>
<if test="isHttps != null and isHttps != ''">#{isHttps},</if>
<if test="region != null and region != ''">#{region},</if>
<if test="accessPolicy != null and accessPolicy != ''">#{accessPolicy},</if>
<if test="status != null and status != ''">#{status},</if>
<if test="ext1 != null and ext1 != ''">#{ext1},</if>
<if test="delFlag != null and delFlag != ''">#{delFlag},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateOssConfig" parameterType="com.fastbee.oss.domain.OssConfig">
update oss_config
<trim prefix="SET" suffixOverrides=",">
<if test="tenantId != null">tenant_id = #{tenantId},</if>
<if test="tenantName != null and tenantName != ''">tenant_name = #{tenantName},</if>
<if test="configKey != null and configKey != ''">config_key = #{configKey},</if>
<if test="accessKey != null and accessKey != ''">access_key = #{accessKey},</if>
<if test="secretKey != null and secretKey != ''">secret_key = #{secretKey},</if>
<if test="bucketName != null and bucketName != ''">bucket_name = #{bucketName},</if>
<if test="prefix != null and prefix != ''">prefix = #{prefix},</if>
<if test="endpoint != null and endpoint != ''">endpoint = #{endpoint},</if>
<if test="domain != null and domain != ''">domain = #{domain},</if>
<if test="isHttps != null and isHttps != ''">is_https = #{isHttps},</if>
<if test="region != null and region != ''">region = #{region},</if>
<if test="accessPolicy != null and accessPolicy != ''">access_policy = #{accessPolicy},</if>
<if test="status != null and status != ''">status = #{status},</if>
<if test="ext1 != null and ext1 != ''">ext1 = #{ext1},</if>
<if test="delFlag != null and delFlag != ''">del_flag = #{delFlag},</if>
<if test="createBy != null and createBy != ''">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteOssConfigById" parameterType="Integer">
delete from oss_config where id = #{id}
</delete>
<delete id="deleteOssConfigByIds" parameterType="String">
delete from oss_config where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<update id="resetConfigStatus">
update oss_config set status = 1
where status = 0
</update>
</mapper>

View File

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fastbee.oss.mapper.OssDetailMapper">
<resultMap type="com.fastbee.oss.domain.OssDetail" id="OssDetailResult">
<result property="id" column="id" />
<result property="tenantId" column="tenant_id" />
<result property="tenantName" column="tenant_name" />
<result property="fileName" column="file_name" />
<result property="originalName" column="original_name" />
<result property="fileSuffix" column="file_suffix" />
<result property="url" column="url" />
<result property="service" column="service" />
<result property="delFlag" column="del_flag" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectOssDetailVo">
select id, tenant_id, tenant_name, file_name, original_name, file_suffix, url, service, del_flag, create_by, create_time, update_by, update_time, remark from oss_detail
</sql>
<select id="selectOssDetailList" parameterType="com.fastbee.oss.domain.OssDetail" resultMap="OssDetailResult">
<include refid="selectOssDetailVo"/>
<where>
<if test="tenantId != null "> and tenant_id = #{tenantId}</if>
<if test="tenantName != null and tenantName != ''"> and tenant_name like concat('%', #{tenantName}, '%')</if>
<if test="fileName != null and fileName != ''"> and file_name like concat('%', #{fileName}, '%')</if>
<if test="originalName != null and originalName != ''"> and original_name like concat('%', #{originalName}, '%')</if>
<if test="fileSuffix != null and fileSuffix != ''"> and file_suffix = #{fileSuffix}</if>
<if test="url != null and url != ''"> and url = #{url}</if>
<if test="service != null and service != ''"> and service = #{service}</if>
</where>
</select>
<select id="selectOssDetailById" parameterType="Integer" resultMap="OssDetailResult">
<include refid="selectOssDetailVo"/>
where id = #{id}
</select>
<insert id="insertOssDetail" parameterType="com.fastbee.oss.domain.OssDetail" useGeneratedKeys="true" keyProperty="id">
insert into oss_detail
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="tenantId != null">tenant_id,</if>
<if test="tenantName != null and tenantName != ''">tenant_name,</if>
<if test="fileName != null and fileName != ''">file_name,</if>
<if test="originalName != null and originalName != ''">original_name,</if>
<if test="fileSuffix != null and fileSuffix != ''">file_suffix,</if>
<if test="url != null and url != ''">url,</if>
<if test="service != null and service != ''">service,</if>
<if test="delFlag != null and delFlag != ''">del_flag,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="tenantId != null">#{tenantId},</if>
<if test="tenantName != null and tenantName != ''">#{tenantName},</if>
<if test="fileName != null and fileName != ''">#{fileName},</if>
<if test="originalName != null and originalName != ''">#{originalName},</if>
<if test="fileSuffix != null and fileSuffix != ''">#{fileSuffix},</if>
<if test="url != null and url != ''">#{url},</if>
<if test="service != null and service != ''">#{service},</if>
<if test="delFlag != null and delFlag != ''">#{delFlag},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
<update id="updateOssDetail" parameterType="com.fastbee.oss.domain.OssDetail">
update oss_detail
<trim prefix="SET" suffixOverrides=",">
<if test="tenantId != null">tenant_id = #{tenantId},</if>
<if test="tenantName != null and tenantName != ''">tenant_name = #{tenantName},</if>
<if test="fileName != null and fileName != ''">file_name = #{fileName},</if>
<if test="originalName != null and originalName != ''">original_name = #{originalName},</if>
<if test="fileSuffix != null and fileSuffix != ''">file_suffix = #{fileSuffix},</if>
<if test="url != null and url != ''">url = #{url},</if>
<if test="service != null and service != ''">service = #{service},</if>
<if test="delFlag != null and delFlag != ''">del_flag = #{delFlag},</if>
<if test="createBy != null and createBy != ''">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteOssDetailById" parameterType="Integer">
delete from oss_detail where id = #{id}
</delete>
<delete id="deleteOssDetailByIds" parameterType="String">
delete from oss_detail where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@ -0,0 +1,64 @@
-- ----------------------------
-- Table structure for oss_detail
-- ----------------------------
DROP TABLE IF EXISTS `oss_detail`;
CREATE TABLE `oss_detail`
(
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '文件id',
`tenant_id` bigint(20) NOT NULL DEFAULT 1 COMMENT '租户ID',
`tenant_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '租户名称',
`file_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '文件名',
`original_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '原名',
`file_suffix` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '文件后缀名',
`url` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'URL地址',
`service` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'aliyun' COMMENT '服务商',
`del_flag` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '删除标志0代表存在 2代表删除',
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime(0) NOT NULL COMMENT '创建时间',
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB
AUTO_INCREMENT = 1
CHARACTER SET = utf8
COLLATE = utf8_general_ci COMMENT = '文件记录表'
ROW_FORMAT = Dynamic;
DROP TABLE IF EXISTS `oss_config`;
CREATE TABLE `oss_config`
(
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id',
`tenant_id` bigint(20) NOT NULL DEFAULT 1 COMMENT '租户ID',
`tenant_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '租户名称',
`config_key` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '配置key',
`access_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT 'accessKey',
`secret_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '秘钥',
`bucket_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '桶名称',
`prefix` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT'前缀',
`endpoint` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '访问站点',
`domain` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '自定义域名',
`is_https` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N' COMMENT '是否httpsY=是,N=否)',
`region` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '',
`access_policy` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '1' COMMENT '桶权限类型(0=private 1=public 2=custom)',
`status` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '1' COMMENT '是否默认0=是,1=否)',
`ext1` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '扩展字段',
`del_flag` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '删除标志0代表存在 2代表删除',
`create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime(0) NOT NULL COMMENT '创建时间',
`update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB
AUTO_INCREMENT = 1
CHARACTER SET = utf8
COLLATE = utf8_general_ci COMMENT = '对象存储配置表'
ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of oss_config
-- ----------------------------
insert into oss_config values (1, 1, 'admin', 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'fastbee', '', 'oss-cn-beijing.aliyuncs.com', '','N', '', '0' ,'0', '', '0', '', '2023-02-25 23:15:57', '', NULL, NULL);
insert into oss_config values (2, 1, 'admin', 'qiniu', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'fastbee', '', 's3-cn-north-1.qiniucs.com', '','N', '', '1' ,'1', '', '0', '', '2023-02-25 23:15:57', '', NULL, NULL);