145 lines
4.7 KiB
Java
145 lines
4.7 KiB
Java
|
package edu.whut.smilepicturebackend.manager.upload;
|
|||
|
import cn.hutool.core.date.DateUtil;
|
|||
|
import cn.hutool.core.io.FileUtil;
|
|||
|
import cn.hutool.core.util.NumberUtil;
|
|||
|
import cn.hutool.core.util.RandomUtil;
|
|||
|
import com.qcloud.cos.model.PutObjectResult;
|
|||
|
import com.qcloud.cos.model.ciModel.persistence.CIObject;
|
|||
|
import com.qcloud.cos.model.ciModel.persistence.ImageInfo;
|
|||
|
import edu.whut.smilepicturebackend.config.CosClientConfig;
|
|||
|
import edu.whut.smilepicturebackend.exception.BusinessException;
|
|||
|
import edu.whut.smilepicturebackend.exception.ErrorCode;
|
|||
|
import edu.whut.smilepicturebackend.manager.CosManager;
|
|||
|
import edu.whut.smilepicturebackend.model.file.UploadPictureResult;
|
|||
|
import lombok.extern.slf4j.Slf4j;
|
|||
|
|
|||
|
import javax.annotation.Resource;
|
|||
|
import java.io.File;
|
|||
|
import java.util.Date;
|
|||
|
|
|||
|
/**
|
|||
|
* 图片上传模板
|
|||
|
*/
|
|||
|
@Slf4j
|
|||
|
public abstract class PictureUploadTemplate {
|
|||
|
|
|||
|
@Resource
|
|||
|
private CosClientConfig cosClientConfig;
|
|||
|
|
|||
|
@Resource
|
|||
|
private CosManager cosManager;
|
|||
|
|
|||
|
/**
|
|||
|
* 上传图片
|
|||
|
*
|
|||
|
* @param inputSource 文件
|
|||
|
* @param uploadPathPrefix 上传路径前缀
|
|||
|
* @return
|
|||
|
*/
|
|||
|
public UploadPictureResult uploadPicture(Object inputSource, String uploadPathPrefix) {
|
|||
|
// 1. 校验图片
|
|||
|
validPicture(inputSource);
|
|||
|
// 2. 图片上传地址
|
|||
|
String uuid = RandomUtil.randomString(16);
|
|||
|
String originalFilename = getOriginFilename(inputSource);
|
|||
|
// 自己拼接文件上传路径,而不是使用原始文件名称,可以增强安全性
|
|||
|
String uploadFilename = String.format("%s_%s.%s", DateUtil.formatDate(new Date()), uuid,
|
|||
|
FileUtil.getSuffix(originalFilename));
|
|||
|
//如果多个项目共享存储桶,请在桶的根目录下以各项目名作为目录。
|
|||
|
String projectName="smile-picture";
|
|||
|
String uploadPath = String.format("/%s/%s/%s",projectName, uploadPathPrefix, uploadFilename);
|
|||
|
File file = null;
|
|||
|
try {
|
|||
|
// 3. 创建临时文件,获取文件到服务器
|
|||
|
file = File.createTempFile(uploadPath, null);
|
|||
|
// 处理文件来源
|
|||
|
processFile(inputSource, file);
|
|||
|
// 4. 上传图片到对象存储
|
|||
|
PutObjectResult putObjectResult = cosManager.putPictureObject(uploadPath, file);
|
|||
|
// 5. 获取图片信息对象,封装返回结果
|
|||
|
ImageInfo imageInfo = putObjectResult.getCiUploadResult().getOriginalInfo().getImageInfo();
|
|||
|
return buildResult(originalFilename, file, uploadPath, imageInfo);
|
|||
|
} catch (Exception e) {
|
|||
|
log.error("图片上传到对象存储失败", e);
|
|||
|
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传失败");
|
|||
|
} finally {
|
|||
|
// 6. 临时文件清理
|
|||
|
this.deleteTempFile(file);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 校验输入源(本地文件或 URL)
|
|||
|
*/
|
|||
|
protected abstract void validPicture(Object inputSource);
|
|||
|
|
|||
|
/**
|
|||
|
* 获取输入源的原始文件名
|
|||
|
*/
|
|||
|
protected abstract String getOriginFilename(Object inputSource);
|
|||
|
|
|||
|
/**
|
|||
|
* 处理输入源并生成本地临时文件
|
|||
|
*/
|
|||
|
protected abstract void processFile(Object inputSource, File file) throws Exception;
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* 封装返回结果
|
|||
|
*
|
|||
|
* @param originalFilename
|
|||
|
* @param file
|
|||
|
* @param uploadPath
|
|||
|
* @param imageInfo 对象存储返回的图片信息
|
|||
|
* @return
|
|||
|
*/
|
|||
|
private UploadPictureResult buildResult(String originalFilename, File file, String uploadPath, ImageInfo imageInfo) {
|
|||
|
// 计算宽高
|
|||
|
int picWidth = imageInfo.getWidth();
|
|||
|
int picHeight = imageInfo.getHeight();
|
|||
|
double picScale = NumberUtil.round(picWidth * 1.0 / picHeight, 2).doubleValue();
|
|||
|
// 封装返回结果
|
|||
|
UploadPictureResult uploadPictureResult = new UploadPictureResult();
|
|||
|
uploadPictureResult.setUrl(cosClientConfig.getHost() + "/" + uploadPath);
|
|||
|
uploadPictureResult.setName(FileUtil.mainName(originalFilename));
|
|||
|
uploadPictureResult.setPicSize(FileUtil.size(file));
|
|||
|
uploadPictureResult.setPicWidth(picWidth);
|
|||
|
uploadPictureResult.setPicHeight(picHeight);
|
|||
|
uploadPictureResult.setPicScale(picScale);
|
|||
|
uploadPictureResult.setPicFormat(imageInfo.getFormat());
|
|||
|
uploadPictureResult.setPicColor(imageInfo.getAve());
|
|||
|
// 返回可访问的地址
|
|||
|
return uploadPictureResult;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 清理临时文件
|
|||
|
*
|
|||
|
* @param file
|
|||
|
*/
|
|||
|
public void deleteTempFile(File file) {
|
|||
|
if (file == null) {
|
|||
|
return;
|
|||
|
}
|
|||
|
// 删除临时文件
|
|||
|
boolean deleteResult = file.delete();
|
|||
|
if (!deleteResult) {
|
|||
|
log.error("file delete error, filepath = {}", file.getAbsolutePath());
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|