Commit 33e38bec by zhangxingmin

push

parent cbec905d
...@@ -3,6 +3,8 @@ package com.yd.oss.api.controller; ...@@ -3,6 +3,8 @@ package com.yd.oss.api.controller;
import com.yd.common.result.Result; import com.yd.common.result.Result;
import com.yd.oss.api.service.ApiOssStsService; import com.yd.oss.api.service.ApiOssStsService;
import com.yd.oss.feign.client.ApiOssStsFeignClient; import com.yd.oss.feign.client.ApiOssStsFeignClient;
import com.yd.oss.feign.request.ApiBatchSaveFilesRequest;
import com.yd.oss.feign.response.ApiBatchSaveFilesResponse;
import com.yd.oss.feign.response.ApiGetStsTokenResponse; import com.yd.oss.feign.response.ApiGetStsTokenResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
...@@ -11,7 +13,7 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -11,7 +13,7 @@ import org.springframework.web.bind.annotation.RestController;
/** /**
* OSS-STS接口信息 * OSS-分片接口信息
* *
* @author zxm * @author zxm
* @since 2025-07-31 * @since 2025-07-31
...@@ -28,7 +30,16 @@ public class ApiOssStsController implements ApiOssStsFeignClient { ...@@ -28,7 +30,16 @@ public class ApiOssStsController implements ApiOssStsFeignClient {
* 获取STS凭证 * 获取STS凭证
* @return * @return
*/ */
public Result<ApiGetStsTokenResponse> getStsToken(){ public Result<ApiGetStsTokenResponse> getStsToken(String projectBizId){
return apiOssStsService.getStsToken(); return apiOssStsService.getStsToken(projectBizId);
}
/**
* 批量保存文件列表
* @return
*/
@Override
public Result<ApiBatchSaveFilesResponse> batchSaveFiles(ApiBatchSaveFilesRequest request) {
return apiOssStsService.batchSaveFiles(request);
} }
} }
\ No newline at end of file
package com.yd.oss.api.service; package com.yd.oss.api.service;
import com.yd.common.result.Result; import com.yd.common.result.Result;
import com.yd.oss.feign.request.ApiBatchSaveFilesRequest;
import com.yd.oss.feign.response.ApiBatchSaveFilesResponse;
import com.yd.oss.feign.response.ApiGetStsTokenResponse; import com.yd.oss.feign.response.ApiGetStsTokenResponse;
public interface ApiOssStsService { public interface ApiOssStsService {
Result<ApiGetStsTokenResponse> getStsToken(); Result<ApiGetStsTokenResponse> getStsToken(String projectBizId);
Result<ApiBatchSaveFilesResponse> batchSaveFiles(ApiBatchSaveFilesRequest request);
} }
...@@ -2,20 +2,35 @@ package com.yd.oss.feign.client; ...@@ -2,20 +2,35 @@ package com.yd.oss.feign.client;
import com.yd.common.result.Result; import com.yd.common.result.Result;
import com.yd.oss.feign.fallback.ApiOssStsFeignFallbackFactory; import com.yd.oss.feign.fallback.ApiOssStsFeignFallbackFactory;
import com.yd.oss.feign.request.ApiBatchSaveFilesRequest;
import com.yd.oss.feign.response.ApiBatchSaveFilesResponse;
import com.yd.oss.feign.response.ApiGetStsTokenResponse; import com.yd.oss.feign.response.ApiGetStsTokenResponse;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import javax.validation.constraints.NotBlank;
/** /**
* OSS服务信息Feign客户端 * OSS-分片服务信息Feign客户端
*/ */
@FeignClient(name = "yd-oss-api", fallbackFactory = ApiOssStsFeignFallbackFactory.class) @FeignClient(name = "yd-oss-api", fallbackFactory = ApiOssStsFeignFallbackFactory.class)
public interface ApiOssStsFeignClient { public interface ApiOssStsFeignClient {
/** /**
* 获取STS凭证 * 获取STS凭证
* @param projectBizId
* @return * @return
*/ */
@GetMapping("/sts-token") @GetMapping("/sts-token")
Result<ApiGetStsTokenResponse> getStsToken(); Result<ApiGetStsTokenResponse> getStsToken(@NotBlank(message = "项目ID不能为空") @RequestParam(value = "projectBizId") String projectBizId);
/**
* 批量保存文件列表
* @return
*/
@PostMapping("/batch/save/files")
Result<ApiBatchSaveFilesResponse> batchSaveFiles(@Validated @RequestBody ApiBatchSaveFilesRequest request);
} }
package com.yd.oss.feign.dto;
import lombok.Data;
@Data
public class ApiOssFileDto {
/**
* 文件名(原始文件名)
*/
private String fileName;
/**
* 文件大小
*/
private Long fileSize;
/**
* 上传文件路径(完整路径)
*/
private String fileUrl;
}
...@@ -2,10 +2,13 @@ package com.yd.oss.feign.fallback; ...@@ -2,10 +2,13 @@ package com.yd.oss.feign.fallback;
import com.yd.common.result.Result; import com.yd.common.result.Result;
import com.yd.oss.feign.client.ApiOssStsFeignClient; import com.yd.oss.feign.client.ApiOssStsFeignClient;
import com.yd.oss.feign.request.ApiBatchSaveFilesRequest;
import com.yd.oss.feign.response.ApiBatchSaveFilesResponse;
import com.yd.oss.feign.response.ApiGetStsTokenResponse; import com.yd.oss.feign.response.ApiGetStsTokenResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory; import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestParam;
/** /**
* OSS服务信息Feign降级处理 * OSS服务信息Feign降级处理
...@@ -17,7 +20,12 @@ public class ApiOssStsFeignFallbackFactory implements FallbackFactory<ApiOssStsF ...@@ -17,7 +20,12 @@ public class ApiOssStsFeignFallbackFactory implements FallbackFactory<ApiOssStsF
public ApiOssStsFeignClient create(Throwable cause) { public ApiOssStsFeignClient create(Throwable cause) {
return new ApiOssStsFeignClient() { return new ApiOssStsFeignClient() {
@Override @Override
public Result<ApiGetStsTokenResponse> getStsToken() { public Result<ApiGetStsTokenResponse> getStsToken(String projectBizId) {
return null;
}
@Override
public Result<ApiBatchSaveFilesResponse> batchSaveFiles(ApiBatchSaveFilesRequest request) {
return null; return null;
} }
}; };
......
package com.yd.oss.feign.request;
import com.yd.oss.feign.dto.ApiOssFileDto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
@Data
public class ApiBatchSaveFilesRequest {
/**
* 所属租户ID(业务id)
*/
@NotBlank(message = "所属租户ID不能为空")
private String tenantBizId;
/**
* 所属项目ID(业务id)
*/
@NotBlank(message = "所属项目ID不能为空")
private String projectBizId;
/**
* 对象类型
*/
private String objectType;
/**
* 对象所属表名(预约表、新单跟进表等)
*/
private String objectTableName;
/**
* 对象名
*/
private String objectName;
/**
* 对象业务ID
*/
@NotBlank(message = "对象业务ID不能为空")
private String objectBizId;
/**
* 上传的文件对象列表
*/
@NotEmpty(message = "上传的文件对象列表不能为空")
private List<ApiOssFileDto> apiOssFileDtoList;
}
package com.yd.oss.feign.response;
import lombok.Data;
import java.util.List;
@Data
public class ApiBatchSaveFilesResponse {
private List<ApiOssFileResponse> fileResponses;
}
package com.yd.oss.feign.response;
import lombok.Data;
@Data
public class ApiOssFileResponse {
/**
* 文件元数据表唯一业务ID(不传值)
*/
private String fileBizId;
/**
* 文件名(原始文件名)
*/
private String fileName;
/**
* 文件大小
*/
private Long fileSize;
/**
* 上传文件路径(完整路径)
*/
private String fileUrl;
}
package com.yd.oss.service.config;
import com.aliyun.oss.OSS;
import com.yd.oss.service.service.OssService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicOssClientProxy implements InvocationHandler {
private final OssService ossService;
public DynamicOssClientProxy(OssService ossService) {
this.ossService = ossService;
}
public static OSS createProxy(OssService ossService) {
return (OSS) Proxy.newProxyInstance(
DynamicOssClientProxy.class.getClassLoader(),
new Class[]{OSS.class},
new DynamicOssClientProxy(ossService)
);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 每次方法调用都从 OssService 获取当前客户端
OSS currentClient = ossService.getOssClient();
return method.invoke(currentClient, args);
}
}
\ No newline at end of file
...@@ -4,6 +4,7 @@ import com.aliyun.oss.OSS; ...@@ -4,6 +4,7 @@ import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.OSSClientBuilder;
import com.yd.oss.service.model.OssProvider; import com.yd.oss.service.model.OssProvider;
import com.yd.oss.service.service.IOssProviderService; import com.yd.oss.service.service.IOssProviderService;
import com.yd.oss.service.service.OssService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
...@@ -38,14 +39,20 @@ public class OssConfig { ...@@ -38,14 +39,20 @@ public class OssConfig {
} }
} }
// @Bean
// @Primary
// public OSS ossClient() {
// return new OSSClientBuilder().build(
// currentProvider.getEndpoint(),
// currentProvider.getAccessKey(),
// currentProvider.getSecretKey()
// );
// }
@Bean @Bean
@Primary public OSS ossClient(OssService ossService) {
public OSS ossClient() { // 返回动态代理,每次调用都委托给 ossService.getOssClient()
return new OSSClientBuilder().build( return DynamicOssClientProxy.createProxy(ossService);
currentProvider.getEndpoint(),
currentProvider.getAccessKey(),
currentProvider.getSecretKey()
);
} }
@Bean @Bean
......
...@@ -28,6 +28,18 @@ public class OssFile implements Serializable { ...@@ -28,6 +28,18 @@ public class OssFile implements Serializable {
private Long id; private Long id;
/** /**
* 所属租户ID(业务id)
*/
@TableField("tenant_biz_id")
private String tenantBizId;
/**
* 所属项目ID(业务id)
*/
@TableField("project_biz_id")
private String projectBizId;
/**
* 对象类型 * 对象类型
*/ */
@TableField("object_type") @TableField("object_type")
......
...@@ -34,6 +34,18 @@ public class OssProvider implements Serializable { ...@@ -34,6 +34,18 @@ public class OssProvider implements Serializable {
private String providerBizId; private String providerBizId;
/** /**
* 所属租户ID(业务id)
*/
@TableField("tenant_biz_id")
private String tenantBizId;
/**
* 所属项目ID(业务id)
*/
@TableField("project_biz_id")
private String projectBizId;
/**
* 服务商编码(业务编码) * 服务商编码(业务编码)
*/ */
@TableField("code") @TableField("code")
......
...@@ -26,4 +26,6 @@ public interface IOssProviderService extends IService<OssProvider> { ...@@ -26,4 +26,6 @@ public interface IOssProviderService extends IService<OssProvider> {
boolean saveProvider(OssProvider provider); boolean saveProvider(OssProvider provider);
boolean deleteProvider(Long id); boolean deleteProvider(Long id);
OssProvider getProviderByProjectId(String projectBizId);
} }
package com.yd.oss.service.service; package com.yd.oss.service.service;
import com.yd.oss.feign.request.ApiUploadFileRequest; import com.aliyun.oss.OSS;
import com.yd.oss.service.dto.FileMetadata; import com.yd.oss.service.dto.FileMetadata;
import com.yd.oss.service.dto.OssUploadFileReqDto; import com.yd.oss.service.dto.OssUploadFileReqDto;
import com.yd.oss.service.dto.OssUploadFileResDto; import com.yd.oss.service.dto.OssUploadFileResDto;
...@@ -53,12 +53,17 @@ public interface OssService { ...@@ -53,12 +53,17 @@ public interface OssService {
// 获取文件元数据(使用默认存储桶) // 获取文件元数据(使用默认存储桶)
FileMetadata getFileMetadata(String fileKey); FileMetadata getFileMetadata(String fileKey);
void switchProviderByProjectId(String projectBizId);
// 切换OSS提供商 // 切换OSS提供商
void switchProvider(String providerName); void switchProvider(String providerName);
// 切换OSS提供商(通过ID) // 切换OSS提供商(通过ID)
void switchProvider(Long providerId); void switchProvider(Long providerId);
//获取当前使用的 OSS 客户端
OSS getOssClient();
// 获取当前使用的提供商 // 获取当前使用的提供商
OssProvider getCurrentProvider(); OssProvider getCurrentProvider();
......
...@@ -588,6 +588,26 @@ public class AliYunOssServiceImpl implements OssService { ...@@ -588,6 +588,26 @@ public class AliYunOssServiceImpl implements OssService {
} }
/** /**
* 切换OSS提供商-根据项目ID切换
* @param projectBizId
*/
@Override
public void switchProviderByProjectId(String projectBizId) {
try {
// 根据项目ID获取OSS提供商
OssProvider provider = ossProviderService.getProviderByProjectId(projectBizId);
// 切换到新的提供商
switchToProvider(provider);
log.info("已切换到OSS提供商: {}", provider.getName());
} catch (Exception e) {
log.error("切换OSS提供商失败: {}", e.getMessage());
throw new RuntimeException("切换OSS提供商失败");
}
}
/**
* 切换OSS提供商 * 切换OSS提供商
* @param providerName * @param providerName
*/ */
...@@ -628,6 +648,16 @@ public class AliYunOssServiceImpl implements OssService { ...@@ -628,6 +648,16 @@ public class AliYunOssServiceImpl implements OssService {
} }
/** /**
* 获取当前使用的 OSS 客户端
* @return
*/
@Override
public OSS getOssClient() {
// 返回当前实例持有的客户端
return this.ossClient;
}
/**
* 切换到指定的OSS提供商 * 切换到指定的OSS提供商
* @param provider * @param provider
*/ */
...@@ -637,14 +667,18 @@ public class AliYunOssServiceImpl implements OssService { ...@@ -637,14 +667,18 @@ public class AliYunOssServiceImpl implements OssService {
this.ossClient.shutdown(); this.ossClient.shutdown();
} }
// 创建新的客户端 // 注入服务商
this.currentProvider = provider; this.currentProvider = provider;
// 注入服务商对应的OSS客户端
this.ossClient = new OSSClientBuilder().build( this.ossClient = new OSSClientBuilder().build(
provider.getEndpoint(), provider.getEndpoint(),
provider.getAccessKey(), provider.getAccessKey(),
provider.getSecretKey() provider.getSecretKey()
); );
// 注入桶
this.defaultBucket = provider.getBucketName(); this.defaultBucket = provider.getBucketName();
// 注入服务端点
this.defaultEndpoint = provider.getEndpoint();
} }
/** /**
......
package com.yd.oss.service.service.impl; package com.yd.oss.service.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yd.common.exception.BusinessException; import com.yd.common.exception.BusinessException;
import com.yd.oss.service.model.OssProvider; import com.yd.oss.service.model.OssProvider;
import com.yd.oss.service.dao.OssProviderMapper; import com.yd.oss.service.dao.OssProviderMapper;
...@@ -113,4 +114,17 @@ public class OssProviderServiceImpl extends ServiceImpl<OssProviderMapper, OssPr ...@@ -113,4 +114,17 @@ public class OssProviderServiceImpl extends ServiceImpl<OssProviderMapper, OssPr
public boolean deleteProvider(Long id) { public boolean deleteProvider(Long id) {
return ossProviderMapper.deleteById(id) > 0; return ossProviderMapper.deleteById(id) > 0;
} }
/**
* 根据项目ID查询对应OSS服务商
* @param projectBizId
* @return
*/
@Override
public OssProvider getProviderByProjectId(String projectBizId) {
return baseMapper.selectOne(new LambdaQueryWrapper<OssProvider>()
.eq(OssProvider::getProjectBizId,projectBizId)
.last(" limit 1 ")
);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment