mirror of https://github.com/halo-dev/halo
新增七牛和又拍的云存储支持
parent
ae4c80c57f
commit
ae7d1d90cf
|
@ -70,4 +70,9 @@ public class Attachment implements Serializable {
|
||||||
* 附件长宽
|
* 附件长宽
|
||||||
*/
|
*/
|
||||||
private String attachWh;
|
private String attachWh;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 附件存储地址
|
||||||
|
*/
|
||||||
|
private String attachLocation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package cc.ryanc.halo.model.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* 七牛上传自定义凭证回调解析
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author : Yawn
|
||||||
|
* @date : 2018/12/3
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class QiNiuPutSet {
|
||||||
|
|
||||||
|
private Long size;
|
||||||
|
private Integer w;
|
||||||
|
private Integer h;
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package cc.ryanc.halo.model.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* 附件存储地址enum
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author : Yawn
|
||||||
|
* @date : 2018/12/4
|
||||||
|
*/
|
||||||
|
public enum AttachLocationEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务器
|
||||||
|
*/
|
||||||
|
SERVER(0,"SERVER"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 七牛
|
||||||
|
*/
|
||||||
|
QINIU(1,"QINIU"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 又拍云
|
||||||
|
*/
|
||||||
|
UPYUN(2,"UPYUN");
|
||||||
|
|
||||||
|
private Integer code;
|
||||||
|
private String desc;
|
||||||
|
|
||||||
|
AttachLocationEnum(Integer code, String desc) {
|
||||||
|
this.code = code;
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDesc() {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,8 +3,11 @@ package cc.ryanc.halo.service;
|
||||||
import cc.ryanc.halo.model.domain.Attachment;
|
import cc.ryanc.halo.model.domain.Attachment;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,4 +58,50 @@ public interface AttachmentService {
|
||||||
* @return Attachment
|
* @return Attachment
|
||||||
*/
|
*/
|
||||||
Attachment removeByAttachId(Long attachId);
|
Attachment removeByAttachId(Long attachId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传转发
|
||||||
|
* @param file
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Map<String,String> upload(MultipartFile file, HttpServletRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原生上传
|
||||||
|
* @param file
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Map<String,String> attachUpload(MultipartFile file, HttpServletRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 七牛云上传
|
||||||
|
* @param file
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Map<String,String> attachQiNiuUpload(MultipartFile file, HttpServletRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 又拍云上传
|
||||||
|
* @param file
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Map<String,String> attachUpYunUpload(MultipartFile file, HttpServletRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 七牛云删除附件
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean deleteQiNiuAttachment(String key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 又拍云删除附件
|
||||||
|
* @param fileName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean deleteUpYunAttachment(String fileName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,45 @@
|
||||||
package cc.ryanc.halo.service.impl;
|
package cc.ryanc.halo.service.impl;
|
||||||
|
|
||||||
import cc.ryanc.halo.model.domain.Attachment;
|
import cc.ryanc.halo.model.domain.Attachment;
|
||||||
|
import cc.ryanc.halo.model.domain.Options;
|
||||||
|
import cc.ryanc.halo.model.dto.QiNiuPutSet;
|
||||||
|
import cc.ryanc.halo.model.enums.AttachLocationEnum;
|
||||||
import cc.ryanc.halo.repository.AttachmentRepository;
|
import cc.ryanc.halo.repository.AttachmentRepository;
|
||||||
|
import cc.ryanc.halo.repository.OptionsRepository;
|
||||||
import cc.ryanc.halo.service.AttachmentService;
|
import cc.ryanc.halo.service.AttachmentService;
|
||||||
|
import cc.ryanc.halo.utils.HaloUtils;
|
||||||
|
import cc.ryanc.halo.utils.Md5Util;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import com.UpYun;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
import com.qiniu.common.QiniuException;
|
||||||
|
import com.qiniu.common.Zone;
|
||||||
|
import com.qiniu.http.Response;
|
||||||
|
import com.qiniu.storage.BucketManager;
|
||||||
|
import com.qiniu.storage.Configuration;
|
||||||
|
import com.qiniu.storage.UploadManager;
|
||||||
|
import com.qiniu.storage.persistent.FileRecorder;
|
||||||
|
import com.qiniu.util.Auth;
|
||||||
|
import com.qiniu.util.StringMap;
|
||||||
|
import com.upyun.UpException;
|
||||||
|
import net.coobird.thumbnailator.Thumbnails;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.List;
|
import javax.imageio.ImageIO;
|
||||||
import java.util.Optional;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
|
@ -29,6 +57,9 @@ public class AttachmentServiceImpl implements AttachmentService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private AttachmentRepository attachmentRepository;
|
private AttachmentRepository attachmentRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private OptionsRepository optionsRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增附件信息
|
* 新增附件信息
|
||||||
*
|
*
|
||||||
|
@ -87,4 +118,241 @@ public class AttachmentServiceImpl implements AttachmentService {
|
||||||
attachmentRepository.delete(attachment.get());
|
attachmentRepository.delete(attachment.get());
|
||||||
return attachment.get();
|
return attachment.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传转发
|
||||||
|
* @param file
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, String> upload(MultipartFile file, HttpServletRequest request) {
|
||||||
|
Map<String,String> resultMap;
|
||||||
|
Options options = optionsRepository.findOptionsByOptionName("attach_loc");
|
||||||
|
if(options == null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
switch (options.getOptionValue()){
|
||||||
|
case "server":
|
||||||
|
resultMap = this.attachUpload(file,request);
|
||||||
|
break;
|
||||||
|
case "qiniu":
|
||||||
|
resultMap = this.attachQiNiuUpload(file,request);
|
||||||
|
break;
|
||||||
|
case "upyun":
|
||||||
|
resultMap = this.attachUpYunUpload(file,request);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
resultMap = this.attachUpload(file,request);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return resultMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原生服务器上传
|
||||||
|
* @param file
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, String> attachUpload(MultipartFile file, HttpServletRequest request) {
|
||||||
|
Map<String,String> resultMap = new HashMap<>(6);
|
||||||
|
try {
|
||||||
|
//用户目录
|
||||||
|
String userPath = System.getProperties().getProperty("user.home") + "/halo";
|
||||||
|
//upload的路径
|
||||||
|
StringBuffer sbMedia = new StringBuffer("upload/");
|
||||||
|
//获取当前年月以创建目录,如果没有该目录则创建
|
||||||
|
sbMedia.append(DateUtil.thisYear()).append("/").append(DateUtil.thisMonth()).append("/");
|
||||||
|
File mediaPath = new File(userPath, sbMedia.toString());
|
||||||
|
if (!mediaPath.exists()) {
|
||||||
|
mediaPath.mkdirs();
|
||||||
|
}
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||||
|
String nameWithOutSuffix = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf('.')).replaceAll(" ", "_").replaceAll(",", "") + dateFormat.format(DateUtil.date()) + new Random().nextInt(1000);
|
||||||
|
String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.') + 1);
|
||||||
|
String fileName = nameWithOutSuffix + "." + fileSuffix;
|
||||||
|
file.transferTo(new File(mediaPath.getAbsoluteFile(), fileName));
|
||||||
|
//压缩图片
|
||||||
|
Thumbnails.of(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(fileName).toString()).size(256, 256).keepAspectRatio(false).toFile(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(nameWithOutSuffix).append("_small.").append(fileSuffix).toString());
|
||||||
|
String filePath = new StringBuffer("/upload/").append(DateUtil.thisYear()).append("/").append(DateUtil.thisMonth()).append("/").append(fileName).toString();
|
||||||
|
String smallPath = new StringBuffer("/upload/").append(DateUtil.thisYear()).append("/").append(DateUtil.thisMonth()).append("/").append(nameWithOutSuffix).append("_small.").append(fileSuffix).toString();
|
||||||
|
String suffix = new StringBuffer(".").append(fileSuffix).toString();
|
||||||
|
String size = HaloUtils.parseSize(new File(mediaPath, fileName).length());
|
||||||
|
String wh = HaloUtils.getImageWh(new File(mediaPath, fileName));
|
||||||
|
resultMap.put("fileName",fileName);
|
||||||
|
resultMap.put("filePath",filePath);
|
||||||
|
resultMap.put("smallPath",smallPath);
|
||||||
|
resultMap.put("suffix",suffix);
|
||||||
|
resultMap.put("size",size);
|
||||||
|
resultMap.put("wh",wh);
|
||||||
|
resultMap.put("location", AttachLocationEnum.SERVER.getDesc());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return resultMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 七牛云上传
|
||||||
|
* @param file
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, String> attachQiNiuUpload(MultipartFile file, HttpServletRequest request) {
|
||||||
|
Map<String, String> resultMap = new HashMap<>(6);
|
||||||
|
try {
|
||||||
|
Configuration cfg = new Configuration(Zone.zone0());
|
||||||
|
String key = Md5Util.getMD5Checksum(file);
|
||||||
|
Options accessKey = optionsRepository.findOptionsByOptionName("qiniu_access_key");
|
||||||
|
Options secretKey = optionsRepository.findOptionsByOptionName("qiniu_secret_key");
|
||||||
|
Options domain = optionsRepository.findOptionsByOptionName("qiniu_domain");
|
||||||
|
Options bucket = optionsRepository.findOptionsByOptionName("qiniu_bucket");
|
||||||
|
Options smallUrl = optionsRepository.findOptionsByOptionName("qiniu_small_url");
|
||||||
|
if(accessKey == null || secretKey == null || domain == null || bucket == null){
|
||||||
|
return resultMap;
|
||||||
|
}
|
||||||
|
Auth auth = Auth.create(accessKey.getOptionValue(),secretKey.getOptionValue());
|
||||||
|
StringMap putPolicy = new StringMap();
|
||||||
|
putPolicy.put("returnBody", "{\"size\":$(fsize),\"w\":$(imageInfo.width),\"h\":$(imageInfo.height)}");
|
||||||
|
String upToken = auth.uploadToken(bucket.getOptionValue(),null,3600,putPolicy);
|
||||||
|
String localTempDir = Paths.get(System.getenv("java.io.tmpdir"),bucket.getOptionValue()).toString();
|
||||||
|
QiNiuPutSet putSet = new QiNiuPutSet();
|
||||||
|
try {
|
||||||
|
FileRecorder fileRecorder = new FileRecorder(localTempDir);
|
||||||
|
UploadManager uploadManager = new UploadManager(cfg,fileRecorder);
|
||||||
|
Response response = uploadManager.put(file.getInputStream(),key,upToken,null,null);
|
||||||
|
//解析上传成功的结果
|
||||||
|
putSet = new Gson().fromJson(response.bodyString(), QiNiuPutSet.class);
|
||||||
|
} catch (QiniuException e) {
|
||||||
|
Response r = e.response;
|
||||||
|
System.err.println(r.toString());
|
||||||
|
try {
|
||||||
|
System.err.println(r.bodyString());
|
||||||
|
} catch (QiniuException ex2) {
|
||||||
|
//ignore
|
||||||
|
}
|
||||||
|
} catch (JsonSyntaxException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}catch (IOException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
String filePath = domain.getOptionValue().contains("http://")?domain.getOptionValue().trim():("http://"+domain.getOptionValue().trim()) + "/" + key;
|
||||||
|
resultMap.put("fileName",file.getOriginalFilename());
|
||||||
|
resultMap.put("filePath",filePath.trim());
|
||||||
|
resultMap.put("smallPath",smallUrl == null ? filePath.trim():(filePath+smallUrl.getOptionValue()).trim());
|
||||||
|
resultMap.put("suffix",file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.')));
|
||||||
|
resultMap.put("size",HaloUtils.parseSize(file.getSize()));
|
||||||
|
resultMap.put("wh",putSet.getW() + "x" + putSet.getH());
|
||||||
|
resultMap.put("location", AttachLocationEnum.QINIU.getDesc());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return resultMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 又拍云上传
|
||||||
|
* @param file
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, String> attachUpYunUpload(MultipartFile file, HttpServletRequest request) {
|
||||||
|
Map<String, String> resultMap = new HashMap<>(6);
|
||||||
|
try {
|
||||||
|
String key = Md5Util.getMD5Checksum(file);
|
||||||
|
Options ossSrc = optionsRepository.findOptionsByOptionName("upyun_oss_src");
|
||||||
|
Options ossPwd = optionsRepository.findOptionsByOptionName("upyun_oss_pwd");
|
||||||
|
Options bucket = optionsRepository.findOptionsByOptionName("upyun_oss_bucket");
|
||||||
|
Options domain = optionsRepository.findOptionsByOptionName("upyun_oss_domain");
|
||||||
|
Options operator = optionsRepository.findOptionsByOptionName("upyun_oss_operator");
|
||||||
|
Options smallUrl = optionsRepository.findOptionsByOptionName("upyun_oss_small");
|
||||||
|
if(ossSrc == null || ossPwd == null || domain == null || bucket == null || operator == null){
|
||||||
|
return resultMap;
|
||||||
|
}
|
||||||
|
String fileName = file.getOriginalFilename();
|
||||||
|
String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.'));
|
||||||
|
UpYun upYun = new UpYun(bucket.getOptionValue(),operator.getOptionValue(),ossPwd.getOptionValue());
|
||||||
|
upYun.setTimeout(60);
|
||||||
|
upYun.setApiDomain(UpYun.ED_AUTO);
|
||||||
|
upYun.setDebug(true);
|
||||||
|
upYun.writeFile(ossSrc.getOptionValue()+key+"."+fileSuffix,file.getBytes(),true,null);
|
||||||
|
String filePath = domain.getOptionValue().contains("http://")?domain.getOptionValue().trim():("http://"+domain.getOptionValue().trim() +ossSrc.getOptionValue() + key + "." + fileSuffix);
|
||||||
|
String smallPath = filePath;
|
||||||
|
if(smallUrl != null){
|
||||||
|
smallPath += smallUrl.getOptionValue();
|
||||||
|
}
|
||||||
|
BufferedImage image = ImageIO.read(file.getInputStream());
|
||||||
|
if (image != null) {
|
||||||
|
resultMap.put("wh",image.getWidth()+"x"+image.getHeight());
|
||||||
|
}
|
||||||
|
resultMap.put("fileName",fileName);
|
||||||
|
resultMap.put("filePath",filePath.trim());
|
||||||
|
resultMap.put("smallPath",smallPath.trim());
|
||||||
|
resultMap.put("suffix",fileSuffix);
|
||||||
|
resultMap.put("size",HaloUtils.parseSize(file.getSize()));
|
||||||
|
resultMap.put("location", AttachLocationEnum.UPYUN.getDesc());
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return resultMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 七牛云删除附件
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean deleteQiNiuAttachment(String key) {
|
||||||
|
boolean flag = true;
|
||||||
|
Configuration cfg = new Configuration(Zone.zone0());
|
||||||
|
Options accessKey = optionsRepository.findOptionsByOptionName("qiniu_access_key");
|
||||||
|
Options secretKey = optionsRepository.findOptionsByOptionName("qiniu_secret_key");
|
||||||
|
Options bucket = optionsRepository.findOptionsByOptionName("qiniu_bucket");
|
||||||
|
if(accessKey == null || secretKey == null || bucket == null){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Auth auth = Auth.create(accessKey.getOptionValue(), secretKey.getOptionValue());
|
||||||
|
BucketManager bucketManager = new BucketManager(auth, cfg);
|
||||||
|
try {
|
||||||
|
bucketManager.delete(bucket.getOptionValue(), key);
|
||||||
|
} catch (QiniuException ex) {
|
||||||
|
System.err.println(ex.code());
|
||||||
|
System.err.println(ex.response.toString());
|
||||||
|
flag = false;
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 又拍云删除附件
|
||||||
|
* @param fileName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean deleteUpYunAttachment(String fileName) {
|
||||||
|
boolean flag = true;
|
||||||
|
Options ossSrc = optionsRepository.findOptionsByOptionName("upyun_oss_src");
|
||||||
|
Options ossPwd = optionsRepository.findOptionsByOptionName("upyun_oss_pwd");
|
||||||
|
Options bucket = optionsRepository.findOptionsByOptionName("upyun_oss_bucket");
|
||||||
|
Options operator = optionsRepository.findOptionsByOptionName("upyun_oss_operator");
|
||||||
|
if(ossSrc == null || ossPwd == null || bucket == null || operator == null){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
UpYun upYun = new UpYun(bucket.getOptionValue(),operator.getOptionValue(),ossPwd.getOptionValue());
|
||||||
|
upYun.setApiDomain(UpYun.ED_AUTO);
|
||||||
|
try {
|
||||||
|
flag = upYun.deleteFile(ossSrc.getOptionValue()+fileName);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (UpException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package cc.ryanc.halo.utils;
|
||||||
|
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* 获取文件hash
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author : Yawn
|
||||||
|
* @date : 2018/12/04
|
||||||
|
*/
|
||||||
|
public class Md5Util {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算文件MD5编码
|
||||||
|
* @param file
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static byte[] createChecksum(MultipartFile file) throws Exception {
|
||||||
|
InputStream fis = file.getInputStream();
|
||||||
|
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
MessageDigest complete = MessageDigest.getInstance("MD5");
|
||||||
|
int numRead;
|
||||||
|
|
||||||
|
do {
|
||||||
|
numRead = fis.read(buffer);
|
||||||
|
if (numRead > 0) {
|
||||||
|
complete.update(buffer, 0, numRead);
|
||||||
|
}
|
||||||
|
} while (numRead != -1);
|
||||||
|
|
||||||
|
fis.close();
|
||||||
|
return complete.digest();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成文件hash值
|
||||||
|
* @param file
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static String getMD5Checksum(MultipartFile file) throws Exception {
|
||||||
|
byte[] b = createChecksum(file);
|
||||||
|
String result = "";
|
||||||
|
|
||||||
|
for (int i=0; i < b.length; i++) {
|
||||||
|
result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 );
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -33,6 +33,10 @@ import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
import static cc.ryanc.halo.model.enums.AttachLocationEnum.QINIU;
|
||||||
|
import static cc.ryanc.halo.model.enums.AttachLocationEnum.SERVER;
|
||||||
|
import static cc.ryanc.halo.model.enums.AttachLocationEnum.UPYUN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
* 后台附件控制器
|
* 后台附件控制器
|
||||||
|
@ -118,47 +122,36 @@ public class AttachmentController {
|
||||||
public Map<String, Object> upload(@RequestParam("file") MultipartFile file,
|
public Map<String, Object> upload(@RequestParam("file") MultipartFile file,
|
||||||
HttpServletRequest request) {
|
HttpServletRequest request) {
|
||||||
Map<String, Object> result = new HashMap<>(3);
|
Map<String, Object> result = new HashMap<>(3);
|
||||||
|
System.out.println("源地址"+file.getOriginalFilename()+"类型"+file.getContentType()+"文件名"+file.getName()+"文件大小"+file.getSize());
|
||||||
if (!file.isEmpty()) {
|
if (!file.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
//用户目录
|
Map<String,String> resultMap = attachmentService.upload(file,request);
|
||||||
String userPath = System.getProperties().getProperty("user.home") + "/halo";
|
if(resultMap == null || resultMap.isEmpty()){
|
||||||
//upload的路径
|
log.error("文件上传失败");
|
||||||
StringBuffer sbMedia = new StringBuffer("upload/");
|
result.put("success", 0);
|
||||||
//获取当前年月以创建目录,如果没有该目录则创建
|
result.put("message", localeMessageUtil.getMessage("code.admin.attachment.upload-failed"));
|
||||||
sbMedia.append(DateUtil.thisYear()).append("/").append(DateUtil.thisMonth()).append("/");
|
return result;
|
||||||
File mediaPath = new File(userPath, sbMedia.toString());
|
|
||||||
if (!mediaPath.exists()) {
|
|
||||||
mediaPath.mkdirs();
|
|
||||||
}
|
}
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
|
|
||||||
String nameWithOutSuffix = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf('.')).replaceAll(" ", "_").replaceAll(",", "") + dateFormat.format(DateUtil.date()) + new Random().nextInt(1000);
|
|
||||||
String fileSuffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.') + 1);
|
|
||||||
String fileName = nameWithOutSuffix + "." + fileSuffix;
|
|
||||||
file.transferTo(new File(mediaPath.getAbsoluteFile(), fileName));
|
|
||||||
|
|
||||||
//压缩图片
|
|
||||||
Thumbnails.of(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(fileName).toString()).size(256, 256).keepAspectRatio(false).toFile(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(nameWithOutSuffix).append("_small.").append(fileSuffix).toString());
|
|
||||||
String filePath = new StringBuffer("/upload/").append(DateUtil.thisYear()).append("/").append(DateUtil.thisMonth()).append("/").append(fileName).toString();
|
|
||||||
//保存在数据库
|
//保存在数据库
|
||||||
Attachment attachment = new Attachment();
|
Attachment attachment = new Attachment();
|
||||||
attachment.setAttachName(fileName);
|
attachment.setAttachName(resultMap.get("fileName"));
|
||||||
attachment.setAttachPath(filePath);
|
attachment.setAttachPath(resultMap.get("filePath"));
|
||||||
attachment.setAttachSmallPath(new StringBuffer("/upload/").append(DateUtil.thisYear()).append("/").append(DateUtil.thisMonth()).append("/").append(nameWithOutSuffix).append("_small.").append(fileSuffix).toString());
|
attachment.setAttachSmallPath(resultMap.get("smallPath"));
|
||||||
attachment.setAttachType(file.getContentType());
|
attachment.setAttachType(file.getContentType());
|
||||||
attachment.setAttachSuffix(new StringBuffer(".").append(fileSuffix).toString());
|
attachment.setAttachSuffix(resultMap.get("suffix"));
|
||||||
attachment.setAttachCreated(DateUtil.date());
|
attachment.setAttachCreated(DateUtil.date());
|
||||||
attachment.setAttachSize(HaloUtils.parseSize(new File(mediaPath, fileName).length()));
|
attachment.setAttachSize(resultMap.get("size"));
|
||||||
attachment.setAttachWh(HaloUtils.getImageWh(new File(mediaPath, fileName)));
|
attachment.setAttachWh(resultMap.get("wh"));
|
||||||
|
attachment.setAttachLocation(resultMap.get("location"));
|
||||||
attachmentService.saveByAttachment(attachment);
|
attachmentService.saveByAttachment(attachment);
|
||||||
log.info("Upload file {} to {} successfully", fileName, mediaPath.getAbsolutePath());
|
log.info("Upload file {} to {} successfully", resultMap.get("fileName"), resultMap.get("filePath"));
|
||||||
logsService.saveByLogs(
|
logsService.saveByLogs(
|
||||||
new Logs(LogsRecord.UPLOAD_FILE, fileName, ServletUtil.getClientIP(request), DateUtil.date())
|
new Logs(LogsRecord.UPLOAD_FILE, resultMap.get("fileName"), ServletUtil.getClientIP(request), DateUtil.date())
|
||||||
);
|
);
|
||||||
|
|
||||||
result.put("success", 1);
|
result.put("success", 1);
|
||||||
result.put("message", localeMessageUtil.getMessage("code.admin.attachment.upload-success"));
|
result.put("message", localeMessageUtil.getMessage("code.admin.attachment.upload-success"));
|
||||||
result.put("url", attachment.getAttachPath());
|
result.put("url", attachment.getAttachPath());
|
||||||
result.put("filename", filePath);
|
result.put("filename", resultMap.get("filePath"));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Upload file failed:{}", e.getMessage());
|
log.error("Upload file failed:{}", e.getMessage());
|
||||||
result.put("success", 0);
|
result.put("success", 0);
|
||||||
|
@ -196,28 +189,52 @@ public class AttachmentController {
|
||||||
public JsonResult removeAttachment(@RequestParam("attachId") Long attachId,
|
public JsonResult removeAttachment(@RequestParam("attachId") Long attachId,
|
||||||
HttpServletRequest request) {
|
HttpServletRequest request) {
|
||||||
Optional<Attachment> attachment = attachmentService.findByAttachId(attachId);
|
Optional<Attachment> attachment = attachmentService.findByAttachId(attachId);
|
||||||
|
String attachLocation = attachment.get().getAttachLocation();
|
||||||
String delFileName = attachment.get().getAttachName();
|
String delFileName = attachment.get().getAttachName();
|
||||||
String delSmallFileName = delFileName.substring(0, delFileName.lastIndexOf('.')) + "_small" + attachment.get().getAttachSuffix();
|
boolean flag = true;
|
||||||
try {
|
try {
|
||||||
//删除数据库中的内容
|
//删除数据库中的内容
|
||||||
attachmentService.removeByAttachId(attachId);
|
attachmentService.removeByAttachId(attachId);
|
||||||
//删除文件
|
if(attachLocation!=null){
|
||||||
String userPath = System.getProperties().getProperty("user.home") + "/halo";
|
if(attachLocation.equals(SERVER.getDesc())){
|
||||||
File mediaPath = new File(userPath, attachment.get().getAttachPath().substring(0, attachment.get().getAttachPath().lastIndexOf('/')));
|
String delSmallFileName = delFileName.substring(0, delFileName.lastIndexOf('.')) + "_small" + attachment.get().getAttachSuffix();
|
||||||
File delFile = new File(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(delFileName).toString());
|
//删除文件
|
||||||
File delSmallFile = new File(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(delSmallFileName).toString());
|
String userPath = System.getProperties().getProperty("user.home") + "/halo";
|
||||||
if (delFile.exists() && delFile.isFile()) {
|
File mediaPath = new File(userPath, attachment.get().getAttachPath().substring(0, attachment.get().getAttachPath().lastIndexOf('/')));
|
||||||
if (delFile.delete() && delSmallFile.delete()) {
|
File delFile = new File(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(delFileName).toString());
|
||||||
log.info("Delete file {} successfully!", delFileName);
|
File delSmallFile = new File(new StringBuffer(mediaPath.getAbsolutePath()).append("/").append(delSmallFileName).toString());
|
||||||
logsService.saveByLogs(
|
if (delFile.exists() && delFile.isFile()) {
|
||||||
new Logs(LogsRecord.REMOVE_FILE, delFileName, ServletUtil.getClientIP(request), DateUtil.date())
|
if (delFile.delete() && delSmallFile.delete()) {
|
||||||
);
|
flag = true;
|
||||||
} else {
|
} else {
|
||||||
log.error("Deleting attachment {} failed!", delFileName);
|
flag = false;
|
||||||
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.delete-failed"));
|
}
|
||||||
|
}
|
||||||
|
}else if(attachLocation.equals(QINIU.getDesc())){
|
||||||
|
//七牛删除
|
||||||
|
String attachPath = attachment.get().getAttachPath();
|
||||||
|
String key =attachPath.substring(attachPath.lastIndexOf("/")+1);
|
||||||
|
flag = attachmentService.deleteQiNiuAttachment(key);
|
||||||
|
}else if(attachLocation.equals(UPYUN.getDesc())){
|
||||||
|
//又拍删除
|
||||||
|
String attachPath = attachment.get().getAttachPath();
|
||||||
|
String fileName =attachPath.substring(attachPath.lastIndexOf("/")+1);
|
||||||
|
flag = attachmentService.deleteUpYunAttachment(fileName);
|
||||||
|
}else{
|
||||||
|
//..
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(flag){
|
||||||
|
log.info("Delete file {} successfully!", delFileName);
|
||||||
|
logsService.saveByLogs(
|
||||||
|
new Logs(LogsRecord.REMOVE_FILE, delFileName, ServletUtil.getClientIP(request), DateUtil.date())
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
log.error("Deleting attachment {} failed!", delFileName);
|
||||||
|
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.delete-failed"));
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
log.error("Deleting attachment {} failed: {}", delFileName, e.getMessage());
|
log.error("Deleting attachment {} failed: {}", delFileName, e.getMessage());
|
||||||
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.delete-failed"));
|
return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.delete-failed"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,7 +217,9 @@ admin.setting.form.upyun-oss-bucket = 空间名称:
|
||||||
admin.setting.form.upyun-oss-operator = 操作员名称:
|
admin.setting.form.upyun-oss-operator = 操作员名称:
|
||||||
admin.setting.form.upyun-oss-pwd = 操作员密码:
|
admin.setting.form.upyun-oss-pwd = 操作员密码:
|
||||||
admin.setting.form.upyun-oss-src = 文件目录:
|
admin.setting.form.upyun-oss-src = 文件目录:
|
||||||
|
admin.setting.form.upyun-oss-small = 处理策略:
|
||||||
admin.setting.form.qiniu-domain = 域名:
|
admin.setting.form.qiniu-domain = 域名:
|
||||||
|
admin.setting.form.qiniu-small-url = 处理策略:
|
||||||
admin.setting.form.admin-pjax = 启用 pjax:
|
admin.setting.form.admin-pjax = 启用 pjax:
|
||||||
admin.setting.form.admin-loading = 后台加载动画:
|
admin.setting.form.admin-loading = 后台加载动画:
|
||||||
admin.setting.form.admin-layout = 后台布局:
|
admin.setting.form.admin-layout = 后台布局:
|
||||||
|
|
|
@ -217,7 +217,9 @@ admin.setting.form.upyun-oss-bucket = Bucket name:
|
||||||
admin.setting.form.upyun-oss-operator = Operator
|
admin.setting.form.upyun-oss-operator = Operator
|
||||||
admin.setting.form.upyun-oss-pwd = Password
|
admin.setting.form.upyun-oss-pwd = Password
|
||||||
admin.setting.form.upyun-oss-src = File Directory:
|
admin.setting.form.upyun-oss-src = File Directory:
|
||||||
|
admin.setting.form.upyun-oss-small = Strategy:
|
||||||
admin.setting.form.qiniu-domain = Domain:
|
admin.setting.form.qiniu-domain = Domain:
|
||||||
|
admin.setting.form.qiniu-small-url = Strategy:
|
||||||
admin.setting.form.admin-pjax = Pjax:
|
admin.setting.form.admin-pjax = Pjax:
|
||||||
admin.setting.form.admin-loading = Load animation:
|
admin.setting.form.admin-loading = Load animation:
|
||||||
admin.setting.form.admin-layout = Layout:
|
admin.setting.form.admin-layout = Layout:
|
||||||
|
|
|
@ -217,7 +217,9 @@ admin.setting.form.upyun-oss-bucket = 空间名称:
|
||||||
admin.setting.form.upyun-oss-operator = 操作员名称:
|
admin.setting.form.upyun-oss-operator = 操作员名称:
|
||||||
admin.setting.form.upyun-oss-pwd = 操作员密码:
|
admin.setting.form.upyun-oss-pwd = 操作员密码:
|
||||||
admin.setting.form.upyun-oss-src = 文件目录:
|
admin.setting.form.upyun-oss-src = 文件目录:
|
||||||
|
admin.setting.form.upyun-oss-small = 处理策略:
|
||||||
admin.setting.form.qiniu-domain = 域名:
|
admin.setting.form.qiniu-domain = 域名:
|
||||||
|
admin.setting.form.qiniu-small-url = 处理策略:
|
||||||
admin.setting.form.admin-pjax = 启用 pjax:
|
admin.setting.form.admin-pjax = 启用 pjax:
|
||||||
admin.setting.form.admin-loading = 后台加载动画:
|
admin.setting.form.admin-loading = 后台加载动画:
|
||||||
admin.setting.form.admin-layout = 后台布局:
|
admin.setting.form.admin-layout = 后台布局:
|
||||||
|
|
|
@ -361,20 +361,20 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-lg-2 col-sm-4 control-label"><@spring.message code='admin.setting.form.attach-choose' /></label>
|
<label class="col-lg-2 col-sm-4 control-label"><@spring.message code='admin.setting.form.attach-choose' /></label>
|
||||||
<div class="col-lg-4 col-sm-8 control-radio">
|
<div class="col-lg-4 col-sm-8 control-radio">
|
||||||
<#--<div class="pretty p-default p-round">-->
|
|
||||||
<#--<input type="radio" name="attach_loc" value="server" ${((options.attach_loc!'server')=='server')?string('checked','')}>-->
|
|
||||||
<#--<div class="state p-primary">-->
|
|
||||||
<#--<label><@spring.message code='admin.setting.form.attach-loc-server' /></label>-->
|
|
||||||
<#--</div>-->
|
|
||||||
<#--</div>-->
|
|
||||||
<div class="pretty p-default p-round">
|
<div class="pretty p-default p-round">
|
||||||
<input type="radio" name="attach_loc" value="upyun" ${((options.attach_loc!)=='upyun')?string('checked','')} disabled="disabled">
|
<input type="radio" name="attach_loc" value="server" ${((options.attach_loc!'server')=='server')?string('checked','')}>
|
||||||
|
<div class="state p-primary">
|
||||||
|
<label><@spring.message code='admin.setting.form.attach-loc-server' /></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="pretty p-default p-round">
|
||||||
|
<input type="radio" name="attach_loc" value="upyun" ${((options.attach_loc!)=='upyun')?string('checked','')} >
|
||||||
<div class="state p-primary">
|
<div class="state p-primary">
|
||||||
<label><@spring.message code='admin.setting.form.attach-loc-upyun' /></label>
|
<label><@spring.message code='admin.setting.form.attach-loc-upyun' /></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="pretty p-default p-round">
|
<div class="pretty p-default p-round">
|
||||||
<input type="radio" name="attach_loc" value="qiniu" ${((options.attach_loc!)=='qiniu')?string('checked','')} disabled="disabled">
|
<input type="radio" name="attach_loc" value="qiniu" ${((options.attach_loc!)=='qiniu')?string('checked','')} >
|
||||||
<div class="state p-primary">
|
<div class="state p-primary">
|
||||||
<label><@spring.message code='admin.setting.form.attach-loc-qiniu' /></label>
|
<label><@spring.message code='admin.setting.form.attach-loc-qiniu' /></label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -383,9 +383,9 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 原生设置 -->
|
<!-- 原生设置 -->
|
||||||
<#--<div class="server-options" style="display: none">-->
|
<div class="server-options" style="display: none">
|
||||||
|
|
||||||
<#--</div>-->
|
</div>
|
||||||
|
|
||||||
<!-- 又拍云选项 -->
|
<!-- 又拍云选项 -->
|
||||||
<div class="upyun-options" style="display: none">
|
<div class="upyun-options" style="display: none">
|
||||||
|
@ -419,6 +419,12 @@
|
||||||
<input type="text" class="form-control" id="upyunOssSrc" name="upyun_oss_src" value="${options.upyun_oss_src!}">
|
<input type="text" class="form-control" id="upyunOssSrc" name="upyun_oss_src" value="${options.upyun_oss_src!}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="upyunOssSmall" class="col-lg-2 col-sm-4 control-label"><@spring.message code='admin.setting.form.upyun-oss-small' /></label>
|
||||||
|
<div class="col-lg-4 col-sm-8">
|
||||||
|
<input type="text" class="form-control" id="upyunOssSmall" name="upyun_oss_small" value="${options.upyun_oss_small!}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 七牛云 -->
|
<!-- 七牛云 -->
|
||||||
|
@ -447,6 +453,12 @@
|
||||||
<input type="text" class="form-control" id="qiniuBucket" name="qiniu_bucket" value="${options.qiniu_bucket!}">
|
<input type="text" class="form-control" id="qiniuBucket" name="qiniu_bucket" value="${options.qiniu_bucket!}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="qiniuSmallUrl" class="col-lg-2 col-sm-4 control-label"><@spring.message code='admin.setting.form.qiniu-small-url' /></label>
|
||||||
|
<div class="col-lg-4 col-sm-8">
|
||||||
|
<input type="text" class="form-control" id="qiniuSamllUrl" name="qiniu_small_url" value="${options.qiniu_small_url!}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-footer">
|
<div class="box-footer">
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="box-footer">
|
<div class="box-footer">
|
||||||
<button type="button" class="btn btn-danger btn-sm pull-left" onclick="btn_delete()"><@spring.message code="common.btn.delete" /></button>
|
<button type="button" class="btn btn-danger btn-sm pull-left" onclick="btn_delete()"><@spring.message code="common.btn.delete" /></button>
|
||||||
<button type="button" class="btn btn-info btn-sm pull-right btn-copy" data-clipboard-text="${options.blog_url!}${attachment.attachPath}"><@spring.message code='admin.attachments.modal.form.btn.copy-path' /></button>
|
<button type="button" class="btn btn-info btn-sm pull-right btn-copy" data-clipboard-text="<#if attachment.attachLocation == 'SERVER'>${options.blog_url!}</#if>${attachment.attachPath}"><@spring.message code='admin.attachments.modal.form.btn.copy-path' /></button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue