package com.iplatform.base;
|
|
import com.iplatform.core.BeanContextAware;
|
import com.walker.file.FileInfo;
|
import com.walker.file.FileStoreType;
|
import com.walker.infrastructure.utils.FileCopyUtils;
|
import com.walker.infrastructure.utils.FileUtils;
|
import com.walker.infrastructure.utils.StringUtils;
|
import org.springframework.web.multipart.MultipartFile;
|
|
import java.io.BufferedInputStream;
|
import java.io.File;
|
import java.io.FileInputStream;
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.util.List;
|
import java.util.Set;
|
|
public abstract class AbstractFileOperateSpiController extends AbstractSecurityController{
|
|
protected FileOperateSpi acquireFileOperateSpi(){
|
return BeanContextAware.getBeanByType(FileOperateSpi.class);
|
}
|
|
/**
|
* 清除给定文件地址的CDN前缀。如:https://qnyun.com/oss/12345678
|
* <pre>
|
* 去掉前缀后,只剩下"12345678"
|
* </pre>
|
* @param path 给定的文件资源地址
|
* @return
|
* @date 2023-05-17
|
*/
|
protected String clearCdnPrefix(String path){
|
return this.acquireFileOperateSpi().clearCdnPrefix(path);
|
}
|
|
/**
|
* 返回存储文件的前缀,根据平台配置参数:本地、FTP或OSS远程存储不同而返回不同前缀。
|
* @return
|
* @date 2023-06-10
|
*/
|
protected String getCdnUrl(){
|
return this.acquireFileOperateSpi().getCdnUrl();
|
}
|
|
/**
|
* 根据文件信息,加载文件二进制内容。
|
* @param fileInfo
|
* @return
|
* @date 2023-03-17
|
*/
|
protected byte[] getLocalFileData(FileInfo fileInfo){
|
String localRoot = this.acquireFileOperateSpi().getFileRootConfig();
|
String absolutePath = localRoot + fileInfo.getUrl();
|
try {
|
return FileCopyUtils.copyToByteArray(new File(absolutePath));
|
} catch (IOException e) {
|
throw new RuntimeException("文件加载异常,可能不存在:" + absolutePath, e);
|
}
|
}
|
|
/**
|
* 根据文件id编号,获取文件基本信息。
|
* @param id
|
* @return
|
* @date 2023-03-17
|
*/
|
protected FileInfo getFileInfo(String id){
|
if(StringUtils.isEmpty(id)){
|
logger.warn("id为空,无法获得文件信息");
|
return null;
|
}
|
return this.acquireFileOperateSpi().getFileInfo(Long.parseLong(id));
|
}
|
|
protected List<FileInfo> getFileInfoList(List<String> ids){
|
if(StringUtils.isEmptyList(ids)){
|
throw new IllegalArgumentException("ids is required!");
|
}
|
return this.acquireFileOperateSpi().getFileInfoList(ids);
|
}
|
|
protected FileInfo uploadFileToLocal(InputStream inputStream
|
, String fileName, String groupId, long fileSize, Integer businessType, String owner) throws Exception{
|
return this.acquireFileOperateSpi().uploadFileToLocal(inputStream, fileName, groupId, fileSize, businessType, owner);
|
}
|
protected FileInfo[] uploadFileToLocal(InputStream[] inputStream
|
, String[] fileName, String groupId, long[] fileSize, Integer businessType, String owner) throws Exception{
|
return this.acquireFileOperateSpi().uploadFileToLocal(inputStream, fileName, groupId, fileSize, businessType, owner);
|
}
|
|
/**
|
* 上传文件到本地,业务控制器直接调用该方法。
|
* @param multipartFile
|
* @param groupId 分组ID,可选
|
* @param businessType 业务类型,可选,请参考电商模块(PID)
|
* @param owner 数据归属:平台为-1,其他为顶级机构ID(商户ID)
|
* @param fileContentType 前端传入的文件上传类型:uploadf 表示文件,其他为图片
|
* @return
|
* @throws Exception 上传失败抛出异常
|
* @date 2023-06-09
|
*/
|
protected FileInfo uploadFileToLocal(MultipartFile multipartFile
|
, String groupId, Integer businessType, String owner, String fileContentType) throws Exception{
|
this.checkMultipartFile(multipartFile);
|
long fileSize = multipartFile.getSize();
|
String fileName = multipartFile.getOriginalFilename().toLowerCase();
|
if(fileName.length() > 99){
|
fileName = fileName.substring(fileName.length()-99);
|
}
|
String fileExt = this.checkFile(fileName, fileSize, fileContentType);
|
logger.debug("上传本地文件扩展名:" + fileExt);
|
return this.uploadFileToLocal(multipartFile.getInputStream(), fileName, groupId, fileSize, businessType, owner);
|
}
|
|
/**
|
* 上传多个文件
|
* @param multipartFile
|
* @param groupId
|
* @param businessType
|
* @param owner
|
* @param fileContentType
|
* @return
|
* @throws Exception
|
* @date 2023-08-01
|
*/
|
protected FileInfo[] uploadFileToLocal(MultipartFile[] multipartFile
|
, String groupId, Integer businessType, String owner, String fileContentType) throws Exception{
|
if(multipartFile == null || multipartFile.length == 0){
|
throw new IllegalArgumentException("multipartFile数组为空");
|
}
|
int size = multipartFile.length;
|
InputStream[] inputStream = new InputStream[size];
|
String[] fileName = new String[size];
|
long[] fileSize = new long[size];
|
for(int i=0; i<size; i++){
|
inputStream[i] = multipartFile[i].getInputStream();
|
fileName[i] = multipartFile[i].getOriginalFilename().toLowerCase();
|
fileSize[i] = multipartFile[i].getSize();
|
}
|
return this.uploadFileToLocal(inputStream, fileName, groupId, fileSize, businessType, owner);
|
}
|
|
protected FileInfo uploadFileToRemote(InputStream inputStream
|
, String fileName, String groupId, long fileSize, Integer businessType, String owner) throws Exception{
|
String remoteFileStoreType = this.getArgumentVariable(ArgumentsConstants.CONFIG_UPLOAD_TYPE).getStringValue();
|
if(StringUtils.isEmpty(remoteFileStoreType)){
|
throw new PlatformRuntimeException("平台未配置任何远程存储类别:" + ArgumentsConstants.CONFIG_UPLOAD_TYPE);
|
}
|
// 2023-07-03,如果配置远程上传为本地
|
if(this.acquireFileOperateSpi().isRemoteAsLocal()){
|
return this.acquireFileOperateSpi().uploadFileToLocal(inputStream, fileName, groupId, fileSize, businessType, owner);
|
}
|
|
FileStoreType fileStoreType = FileStoreType.getType(remoteFileStoreType);
|
if(fileStoreType == FileStoreType.Ftp){
|
return this.acquireFileOperateSpi().uploadFileToFtp(inputStream, fileName, groupId, fileSize, businessType, owner);
|
} else {
|
return this.acquireFileOperateSpi().uploadFileToOss(inputStream, fileName, groupId, fileSize, businessType, owner, fileStoreType);
|
}
|
}
|
protected FileInfo[] uploadFileToRemote(InputStream[] inputStream
|
, String[] fileName, String groupId, long[] fileSize, Integer businessType, String owner) throws Exception{
|
String remoteFileStoreType = this.getArgumentVariable(ArgumentsConstants.CONFIG_UPLOAD_TYPE).getStringValue();
|
if(StringUtils.isEmpty(remoteFileStoreType)){
|
throw new PlatformRuntimeException("平台未配置任何远程存储类别:" + ArgumentsConstants.CONFIG_UPLOAD_TYPE);
|
}
|
// 2023-07-03,如果配置远程上传为本地
|
if(this.acquireFileOperateSpi().isRemoteAsLocal()){
|
return this.acquireFileOperateSpi().uploadFileToLocal(inputStream, fileName, groupId, fileSize, businessType, owner);
|
}
|
|
FileStoreType fileStoreType = FileStoreType.getType(remoteFileStoreType);
|
if(fileStoreType == FileStoreType.Ftp){
|
return this.acquireFileOperateSpi().uploadFileToFtp(inputStream, fileName, groupId, fileSize, businessType, owner);
|
} else {
|
return this.acquireFileOperateSpi().uploadFileToOss(inputStream, fileName, groupId, fileSize, businessType, owner, fileStoreType);
|
}
|
}
|
|
protected FileInfo uploadFileToRemote(MultipartFile multipartFile
|
, String groupId, Integer businessType, String owner, String fileContentType) throws Exception{
|
this.checkMultipartFile(multipartFile);
|
long fileSize = multipartFile.getSize();
|
String fileName = multipartFile.getOriginalFilename().toLowerCase();
|
String fileExt = this.checkFile(fileName, fileSize, fileContentType);
|
logger.debug("上传远程文件扩展名:" + fileExt);
|
return this.uploadFileToRemote(multipartFile.getInputStream(), fileName, groupId, fileSize, businessType, owner);
|
}
|
|
protected FileInfo[] uploadFileToRemote(MultipartFile[] multipartFile
|
, String groupId, Integer businessType, String owner, String fileContentType) throws Exception{
|
int size = multipartFile.length;
|
InputStream[] inputStream = new InputStream[size];
|
String[] fileName = new String[size];
|
long[] fileSize = new long[size];
|
for(int i=0; i<size; i++){
|
inputStream[i] = multipartFile[i].getInputStream();
|
fileName[i] = multipartFile[i].getOriginalFilename().toLowerCase();
|
fileSize[i] = multipartFile[i].getSize();
|
}
|
return this.uploadFileToRemote(inputStream, fileName, groupId, fileSize, businessType, owner);
|
}
|
|
private void checkMultipartFile(MultipartFile multipartFile){
|
if(multipartFile == null){
|
throw new PlatformRuntimeException("上传文件不存在");
|
}
|
long fileSize = multipartFile.getSize();
|
if(fileSize <= 0){
|
throw new PlatformRuntimeException("上传文件大小错误:" + fileSize);
|
}
|
}
|
|
private String checkFile(String fileName, long fileSize, String fileContentType){
|
String fileExt = FileUtils.getFileExt(fileName);
|
if(StringUtils.isEmpty(fileExt)){
|
throw new PlatformRuntimeException("不存在文件扩展名,无法上传");
|
}
|
|
// 平台配置可支持的文件后缀类型
|
String extArrayConfig = null;
|
if(fileContentType.equals(Constants.UPLOAD_AFTER_FILE_KEYWORD)){
|
extArrayConfig = this.getArgumentVariable(ArgumentsConstants.UPLOAD_FILE_EXT_STR_CONFIG_KEY).getStringValue();
|
} else {
|
extArrayConfig = this.getArgumentVariable(ArgumentsConstants.UPLOAD_IMAGE_EXT_STR_CONFIG_KEY).getStringValue();
|
}
|
|
// 如果存在配置后缀限制,就要检查匹配
|
if(StringUtils.isNotEmpty(extArrayConfig)){
|
Set<String> extensionList = StringUtils.commaDelimitedListToSet(extArrayConfig);
|
if(extensionList == null || extensionList.size() == 0){
|
throw new PlatformRuntimeException("上传文件类型,只能是:" + extArrayConfig);
|
}
|
if(!extensionList.contains(fileExt)){
|
throw new PlatformRuntimeException("上传文件类型,只能是:" + extArrayConfig);
|
}
|
}
|
|
// 文件大小限制
|
long fileSizeConfig = 0;
|
if(fileContentType.equals(Constants.UPLOAD_AFTER_FILE_KEYWORD)){
|
fileSizeConfig = this.getArgumentVariable(ArgumentsConstants.UPLOAD_FILE_MAX_SIZE_CONFIG_KEY).getLongValue();
|
} else {
|
fileSizeConfig = this.getArgumentVariable(ArgumentsConstants.UPLOAD_IMAGE_MAX_SIZE_CONFIG_KEY).getLongValue();
|
}
|
// 配置的大小单位:M,这里换成字节
|
fileSizeConfig = fileSizeConfig * 1024 * 1024;
|
if(fileSize > fileSizeConfig){
|
throw new PlatformRuntimeException("上传文件大小:" + fileSize + ",超出限制:" + fileSizeConfig);
|
}
|
return fileExt;
|
}
|
|
/**
|
* 上传文件到服务器本地磁盘。
|
* @param inputStream 文件流,系统使用完会自动关闭
|
* @param fileName 文件名,如: demo.txt
|
* @param groupId 业务ID,可选
|
* @return
|
* @throws Exception
|
* @date 2023-03-16
|
*/
|
@Deprecated
|
protected FileInfo uploadFileToLocal(InputStream inputStream, String fileName, String groupId, long fileSize) throws Exception{
|
return this.acquireFileOperateSpi().uploadFileToSystem(inputStream, fileName, groupId, fileSize);
|
}
|
|
/**
|
* 上传文件到远程服务。
|
* @param inputStream 文件流,系统使用完会自动关闭
|
* @param fileName 文件名,如: demo.txt
|
* @param groupId 业务ID,可选
|
* @return
|
* @throws Exception
|
* @date 2023-02-15
|
*/
|
@Deprecated
|
protected FileInfo uploadFileToRemote(InputStream inputStream, String fileName, String groupId, long fileSize) throws Exception{
|
if(inputStream == null){
|
throw new IllegalArgumentException("上传ftp文件流为空!");
|
}
|
return this.acquireFileOperateSpi().uploadFileToFtp(inputStream, fileName, groupId,fileSize);
|
}
|
|
protected FileInfo uploadFileToRemote(String absoluteFilePath, Integer businessType, String owner) throws Exception{
|
File uploadFile = this.checkAbsoluteFilePath(absoluteFilePath);
|
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(uploadFile));
|
return this.uploadFileToRemote(inputStream, uploadFile.getName(), null, uploadFile.getTotalSpace(), businessType, owner);
|
}
|
|
/**
|
* 上传文件到远程服务目录中。
|
* @param absoluteFilePath
|
* @return 返回上传文件基本信息
|
* @throws Exception
|
* @date 2023-02-15
|
*/
|
@Deprecated
|
protected FileInfo uploadFileToRemote(String absoluteFilePath) throws Exception{
|
// if(StringUtils.isEmpty(absoluteFilePath)){
|
// throw new IllegalArgumentException("上传文件全路径不存在!");
|
// }
|
// File uploadFile = new File(absoluteFilePath);
|
// if(!uploadFile.exists()){
|
// logger.warn("上传文件不存在,file=" + absoluteFilePath);
|
// return null;
|
// }
|
File uploadFile = this.checkAbsoluteFilePath(absoluteFilePath);
|
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(uploadFile));
|
return this.acquireFileOperateSpi().uploadFileToFtp(inputStream, FileUtils.getFileNameWithoutPath(absoluteFilePath), null, uploadFile.getTotalSpace());
|
}
|
|
private File checkAbsoluteFilePath(String absoluteFilePath) throws Exception{
|
if(StringUtils.isEmpty(absoluteFilePath)){
|
throw new IllegalArgumentException("上传文件全路径不存在!");
|
}
|
File uploadFile = new File(absoluteFilePath.toLowerCase());
|
if(!uploadFile.exists()){
|
throw new IllegalArgumentException("上传文件不存在, file=" + absoluteFilePath);
|
}
|
return uploadFile;
|
}
|
}
|