写在最前面
哦吼吼吼吼,最近写了个功能,富文本编辑器中自带的上传图片只能单张图片上传,几百张图片上传这可把天真给累惨了,所以咋办把源码改造它。
HTML部分
<input type="file" id="fs-file" name="file" multiple="multiple" accept="image/jpg,image/jpeg,image/png,image/gif">
$("#fs-file").on('change', function () {
var file = input_f[0].files;
if (!file) {
return false;
}
var form = new FormData();
for (var i = 0; i < file.length; i++) {
form.append("file", file[i]);
console.info(form);
}
$.ajax({
url: _MTONS.BASE_PATH + "/post/uploads",
data: form,
type: "POST",
cache: false, //上传文件无需缓存
processData: false, //用于对data参数进行序列化处理 这里必须false
contentType: false, //必须
beforeSend: function () {
index = top.layer.load(0, {
shade: [0.5, '#fff'] //0.1透明度的白色背景
});
},
complete: function () {
top.layer.close(index);
},
success: function (result) {
if (result.status === 200) {
var names=result.name.split('-');
var paths=result.path.split('-');
// console.info(result.name);
for (var i = 0; i <names.length ; i++) {
var image = `![` + names[i] + `](` + _MTONS.BASE_PATH + paths[i] + `)`;
editor.replaceSelection(image);
var cursor = editor.getCursor();
editor.setCursor({
line: cursor.line,
ch: cursor.ch
});
editor.focus();
}
} else {
layer.alert(result.message);
}
}
});
});
java 部分
@PostMapping("/uploads")
@ResponseBody
public UploadResult uploads(@RequestParam(value = "file", required = false) MultipartFile[] file,
HttpServletRequest request) throws IOException {
UploadResult result = new UploadResult();
String crop = request.getParameter("crop");
// 检查空
if (null == file) {
return result.error(errorInfo.get("NOFILE"));
}
// 保存图片
try {
String fileNames = "", paths = "";
for (MultipartFile f : file) {
String fileName = f.getOriginalFilename();
fileNames += fileName + "-";
String path;
int size = ServletRequestUtils.getIntParameter(request, "size", getWidth(f));
path = storageFactory.get().storeScale(f, Consts.thumbnailPath, size);
paths += path + "-";
}
fileNames = fileNames.substring(0,fileNames.length() - 1);
paths = paths.substring(0,paths.length() - 1);
result.ok(errorInfo.get("SUCCESS"));
result.setName(fileNames);
result.setPath(paths);
} catch (Exception e) {
result.error(errorInfo.get("UNKNOWN"));
e.printStackTrace();
}
return result;
}
public static class UploadResult {
public static int OK = 200;
public static int ERROR = 400;
/**
* 上传状态
*/
private int status;
/**
* 提示文字
*/
private String message;
/**
* 文件名
*/
private String name;
/**
* 文件大小
*/
private long size;
/**
* 文件存放路径
*/
private String path;
public UploadResult ok(String message) {
this.status = OK;
this.message = message;
return this;
}
public UploadResult error(String message) {
this.status = ERROR;
this.message = message;
return this;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
@Component
public class StorageFactory {
@Autowired
private ApplicationContext applicationContext;
@Autowired
private SiteOptions siteOptions;
private Map<String, Storage> fileRepoMap = new HashMap<>();
@PostConstruct
public void init() {
fileRepoMap.put("native", applicationContext.getBean(NativeStorageImpl.class));
fileRepoMap.put("upyun", applicationContext.getBean(UpYunStorageImpl.class));
fileRepoMap.put("aliyun", applicationContext.getBean(AliyunStorageImpl.class));
fileRepoMap.put("qiniu", applicationContext.getBean(QiniuStorageImpl.class));
}
public Storage get() {
String scheme = siteOptions.getValue("storage_scheme");
if (StringUtils.isBlank(scheme)) {
scheme = "native";
}
return fileRepoMap.get(scheme);
}
}
@Slf4j
@Component
public class NativeStorageImpl extends AbstractStorage {
@Override
public void deleteFile(String storePath) {
File file = new File(getStoragePath() + storePath);
// 文件存在, 且不是目录
if (file.exists() && !file.isDirectory()) {
file.delete();
log.info("fileRepo delete " + storePath);
}
}
@Override
public String writeToStore(byte[] bytes, String pathAndFileName) throws Exception {
String dest = getStoragePath() + pathAndFileName;
FileKit.writeByteArrayToFile(bytes, dest);
return pathAndFileName;
}
private String getStoragePath() {
return options.getLocation();
}
}
@Slf4j
public abstract class AbstractStorage implements Storage {
@Autowired
protected SiteOptions options;
@Autowired
protected ResourceDao resourceDao;
protected void validateFile(MultipartFile file) {
if (file == null || file.isEmpty()) {
throw new MtonsException("文件不能为空");
}
if (!FileKit.checkFileType(file.getOriginalFilename())) {
throw new MtonsException("文件格式不支持");
}
}
@Override
public String store(MultipartFile file, String basePath) throws Exception {
validateFile(file);
return writeToStore(file.getBytes(), basePath, file.getOriginalFilename());
}
@Override
public String storeScale(MultipartFile file, String basePath, int maxWidth) throws Exception {
validateFile(file);
byte[] bytes = ImageUtils.scaleByWidth(file, maxWidth);
return writeToStore(bytes, basePath, file.getOriginalFilename());
}
@Override
public String storeScale(MultipartFile file, String basePath, int width, int height) throws Exception {
validateFile(file);
byte[] bytes = ImageUtils.scale(file, width, height);
return writeToStore(bytes, basePath, file.getOriginalFilename());
}
public String writeToStore(byte[] bytes, String src, String originalFilename) throws Exception {
String md5 = MD5.md5File(bytes);
md5=MD5.md5(md5+new Date());
Resource resource = resourceDao.findByMd5(md5);
if (resource != null){
return resource.getPath();
}
String path = FilePathUtils.wholePathName(src, originalFilename, md5);
path = writeToStore(bytes, path);
/*if(path.indexOf(".mp4")>=0){
String os = System.getProperty("os.name");
String newPath = FilePathUtils.wholePathName(Consts.videoPath, originalFilename, md5);
if(os.toLowerCase().startsWith("win")){
System.out.println("当前系统为:"+os);
Runtime rn = Runtime.getRuntime();
String pt=System.getProperty("user.dir")+"/storage/Bento4-SDK-win32/bin/mp4fragment.exe";
int p = rn.exec(pt+" "+System.getProperty("user.dir")+path+" "+System.getProperty("user.dir")+newPath).waitFor();
System.out.println("转换视频程序是否"+p);
}else{
System.out.println("当前系统为:"+os);
Runtime rn = Runtime.getRuntime();
String pt="mp4fragment";
int p = rn.exec(pt+" "+System.getProperty("user.dir")+path+" "+System.getProperty("user.dir")+newPath).waitFor();
System.out.println(System.getProperty("user.dir")+path);
System.out.println(System.getProperty("user.dir")+newPath);
System.out.println("转换视频程序是否"+p);
}
path=newPath;
}*/
// 图片入库
resource = new Resource();
resource.setMd5(md5);
resource.setPath(path);
resource.setCreateTime(LocalDateTime.now());
resourceDao.save(resource);
return path;
}
public static void main(String[] args) {
String pt=System.getProperty("user.dir");
System.out.println(pt);
}
}
public interface Storage {
/**
* 存储图片
* @param file
* @param basePath
* @return
* @throws IOException
*/
String store(MultipartFile file, String basePath) throws Exception;
/**
* 存储压缩图片
* @param file
* @param basePath
* @return
* @throws IOException
*/
String storeScale(MultipartFile file, String basePath, int maxWidth) throws Exception;
/**
* 存储压缩图片
* @param file
* @param basePath
* @return
* @throws IOException
*/
String storeScale(MultipartFile file, String basePath, int width, int height) throws Exception;
/**
* 存储路径
* @param storePath
*/
void deleteFile(String storePath);
String writeToStore(byte[] bytes, String pathAndFileName) throws Exception;
}
主要代码部分其他都是无关紧要,可以根据自己情况修改
写在最后
一健三联,希望和傻朋友永不分手,也希望在我们长长的人生里,还能遇到这种懂我们的人。懂你的人,才配得上你的余生。 所以,朋友啊,快来找我玩吧!