1、文件上传功能重构
2、实现签到删除 3、实现签到表格处弹性布局 4、库存删除问题修正
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
package com.ruoyi.web.controller.common;
|
||||
|
||||
import com.ruoyi.common.config.RuoYiConfig;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.core.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.file.FileUploadUtils;
|
||||
import com.ruoyi.common.utils.file.FileUtils;
|
||||
import com.ruoyi.framework.config.ServerConfig;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通用请求处理
|
||||
*
|
||||
* @author industry
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/common")
|
||||
public class CommonController
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(CommonController.class);
|
||||
|
||||
@Autowired
|
||||
private ServerConfig serverConfig;
|
||||
|
||||
private static final String FILE_DELIMETER = ",";
|
||||
|
||||
/**
|
||||
* 通用下载请求
|
||||
*
|
||||
* @param fileName 文件名称
|
||||
* @param delete 是否删除
|
||||
*/
|
||||
@GetMapping("/download")
|
||||
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!FileUtils.checkAllowDownload(fileName))
|
||||
{
|
||||
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
|
||||
}
|
||||
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
|
||||
String filePath = RuoYiConfig.getDownloadPath() + fileName;
|
||||
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
FileUtils.setAttachmentResponseHeader(response, realFileName);
|
||||
FileUtils.writeBytes(filePath, response.getOutputStream());
|
||||
if (delete)
|
||||
{
|
||||
FileUtils.deleteFile(filePath);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("下载文件失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用上传请求(单个)
|
||||
*/
|
||||
@PostMapping("/upload")
|
||||
public AjaxResult uploadFile(MultipartFile file) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
// 上传文件路径
|
||||
String filePath = RuoYiConfig.getUploadPath();
|
||||
|
||||
// 上传并返回新文件名称
|
||||
String fileName = FileUploadUtils.upload(filePath, file);
|
||||
System.out.println(fileName);
|
||||
String url = serverConfig.getUrl() + fileName;
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("url", url);
|
||||
ajax.put("fileName", fileName);
|
||||
ajax.put("newFileName", FileUtils.getName(fileName));
|
||||
ajax.put("originalFilename", file.getOriginalFilename());
|
||||
return ajax;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用上传请求(多个)
|
||||
*/
|
||||
@PostMapping("/uploads")
|
||||
public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
// 上传文件路径
|
||||
String filePath = RuoYiConfig.getUploadPath();
|
||||
List<String> urls = new ArrayList<String>();
|
||||
List<String> fileNames = new ArrayList<String>();
|
||||
List<String> newFileNames = new ArrayList<String>();
|
||||
List<String> originalFilenames = new ArrayList<String>();
|
||||
for (MultipartFile file : files)
|
||||
{
|
||||
// 上传并返回新文件名称
|
||||
String fileName = FileUploadUtils.upload(filePath, file);
|
||||
String url = serverConfig.getUrl() + fileName;
|
||||
urls.add(url);
|
||||
fileNames.add(fileName);
|
||||
newFileNames.add(FileUtils.getName(fileName));
|
||||
originalFilenames.add(file.getOriginalFilename());
|
||||
}
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
|
||||
ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
|
||||
ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
|
||||
ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
|
||||
return ajax;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地资源通用下载
|
||||
*/
|
||||
@GetMapping("/download/resource")
|
||||
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!FileUtils.checkAllowDownload(resource))
|
||||
{
|
||||
throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
|
||||
}
|
||||
// 本地资源路径
|
||||
String localPath = RuoYiConfig.getProfile();
|
||||
// 数据库资源地址
|
||||
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
|
||||
// 下载名称
|
||||
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
FileUtils.setAttachmentResponseHeader(response, downloadName);
|
||||
FileUtils.writeBytes(downloadPath, response.getOutputStream());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("下载文件失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -12,6 +12,8 @@ ruoyi:
|
||||
addressEnabled: true
|
||||
# 缓存懒加载
|
||||
cacheLazy: false
|
||||
# 文件路径
|
||||
profile: D:/code/java_work/fad_ad/uploadPath
|
||||
|
||||
captcha:
|
||||
# 页面 <参数设置> 可开启关闭 验证码校验
|
||||
|
||||
@@ -41,6 +41,10 @@ public class RuoYiConfig {
|
||||
*/
|
||||
private boolean cacheLazy;
|
||||
|
||||
/** 上传路径 */
|
||||
@Getter
|
||||
private static String profile = "/home/wy/oa/uploadPath";
|
||||
|
||||
/**
|
||||
* 获取地址开关
|
||||
*/
|
||||
@@ -51,4 +55,37 @@ public class RuoYiConfig {
|
||||
RuoYiConfig.addressEnabled = addressEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取导入上传路径
|
||||
*/
|
||||
public static String getImportPath()
|
||||
{
|
||||
return getProfile() + "/import";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取头像上传路径
|
||||
*/
|
||||
public static String getAvatarPath()
|
||||
{
|
||||
return getProfile() + "/avatar";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下载路径
|
||||
*/
|
||||
public static String getDownloadPath()
|
||||
{
|
||||
return getProfile() + "/download/";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上传路径
|
||||
*/
|
||||
public static String getUploadPath()
|
||||
{
|
||||
return getProfile() + "/upload";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -72,5 +72,11 @@ public interface Constants {
|
||||
*/
|
||||
String TOKEN = "token";
|
||||
|
||||
|
||||
/**
|
||||
* 资源映射路径 前缀
|
||||
*/
|
||||
public static final String RESOURCE_PREFIX = "/profile";
|
||||
|
||||
}
|
||||
|
||||
|
||||
216
ruoyi-common/src/main/java/com/ruoyi/common/core/AjaxResult.java
Normal file
216
ruoyi-common/src/main/java/com/ruoyi/common/core/AjaxResult.java
Normal file
@@ -0,0 +1,216 @@
|
||||
package com.ruoyi.common.core;
|
||||
|
||||
import com.ruoyi.common.constant.HttpStatus;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 操作消息提醒
|
||||
*
|
||||
* @author industry
|
||||
*/
|
||||
public class AjaxResult extends HashMap<String, Object>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 状态码 */
|
||||
public static final String CODE_TAG = "code";
|
||||
|
||||
/** 返回内容 */
|
||||
public static final String MSG_TAG = "msg";
|
||||
|
||||
/** 数据对象 */
|
||||
public static final String DATA_TAG = "data";
|
||||
|
||||
/**
|
||||
* 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
|
||||
*/
|
||||
public AjaxResult()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化一个新创建的 AjaxResult 对象
|
||||
*
|
||||
* @param code 状态码
|
||||
* @param msg 返回内容
|
||||
*/
|
||||
public AjaxResult(int code, String msg)
|
||||
{
|
||||
super.put(CODE_TAG, code);
|
||||
super.put(MSG_TAG, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化一个新创建的 AjaxResult 对象
|
||||
*
|
||||
* @param code 状态码
|
||||
* @param msg 返回内容
|
||||
* @param data 数据对象
|
||||
*/
|
||||
public AjaxResult(int code, String msg, Object data)
|
||||
{
|
||||
super.put(CODE_TAG, code);
|
||||
super.put(MSG_TAG, msg);
|
||||
if (StringUtils.isNotNull(data))
|
||||
{
|
||||
super.put(DATA_TAG, data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功消息
|
||||
*
|
||||
* @return 成功消息
|
||||
*/
|
||||
public static AjaxResult success()
|
||||
{
|
||||
return AjaxResult.success("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功数据
|
||||
*
|
||||
* @return 成功消息
|
||||
*/
|
||||
public static AjaxResult success(Object data)
|
||||
{
|
||||
return AjaxResult.success("操作成功", data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @return 成功消息
|
||||
*/
|
||||
public static AjaxResult success(String msg)
|
||||
{
|
||||
return AjaxResult.success(msg, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @param data 数据对象
|
||||
* @return 成功消息
|
||||
*/
|
||||
public static AjaxResult success(String msg, Object data)
|
||||
{
|
||||
return new AjaxResult(HttpStatus.SUCCESS, msg, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回警告消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @return 警告消息
|
||||
*/
|
||||
public static AjaxResult warn(String msg)
|
||||
{
|
||||
return AjaxResult.warn(msg, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回警告消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @param data 数据对象
|
||||
* @return 警告消息
|
||||
*/
|
||||
public static AjaxResult warn(String msg, Object data)
|
||||
{
|
||||
return new AjaxResult(HttpStatus.WARN, msg, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @return 错误消息
|
||||
*/
|
||||
public static AjaxResult error()
|
||||
{
|
||||
return AjaxResult.error("操作失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @return 错误消息
|
||||
*/
|
||||
public static AjaxResult error(String msg)
|
||||
{
|
||||
return AjaxResult.error(msg, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @param msg 返回内容
|
||||
* @param data 数据对象
|
||||
* @return 错误消息
|
||||
*/
|
||||
public static AjaxResult error(String msg, Object data)
|
||||
{
|
||||
return new AjaxResult(HttpStatus.ERROR, msg, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @param code 状态码
|
||||
* @param msg 返回内容
|
||||
* @return 错误消息
|
||||
*/
|
||||
public static AjaxResult error(int code, String msg)
|
||||
{
|
||||
return new AjaxResult(code, msg, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为成功消息
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean isSuccess()
|
||||
{
|
||||
return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为警告消息
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean isWarn()
|
||||
{
|
||||
return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为错误消息
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean isError()
|
||||
{
|
||||
return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG));
|
||||
}
|
||||
|
||||
/**
|
||||
* 方便链式调用
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return 数据对象
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult put(String key, Object value)
|
||||
{
|
||||
super.put(key, value);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.ruoyi.common.exception.file;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* 文件上传异常类
|
||||
*
|
||||
* @author industry
|
||||
*/
|
||||
public class FileUploadException extends Exception
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Throwable cause;
|
||||
|
||||
public FileUploadException()
|
||||
{
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
public FileUploadException(final String msg)
|
||||
{
|
||||
this(msg, null);
|
||||
}
|
||||
|
||||
public FileUploadException(String msg, Throwable cause)
|
||||
{
|
||||
super(msg);
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printStackTrace(PrintStream stream)
|
||||
{
|
||||
super.printStackTrace(stream);
|
||||
if (cause != null)
|
||||
{
|
||||
stream.println("Caused by:");
|
||||
cause.printStackTrace(stream);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printStackTrace(PrintWriter writer)
|
||||
{
|
||||
super.printStackTrace(writer);
|
||||
if (cause != null)
|
||||
{
|
||||
writer.println("Caused by:");
|
||||
cause.printStackTrace(writer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Throwable getCause()
|
||||
{
|
||||
return cause;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.ruoyi.common.exception.file;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 文件上传 误异常类
|
||||
*
|
||||
* @author industry
|
||||
*/
|
||||
public class InvalidExtensionException extends FileUploadException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String[] allowedExtension;
|
||||
private String extension;
|
||||
private String filename;
|
||||
|
||||
public InvalidExtensionException(String[] allowedExtension, String extension, String filename)
|
||||
{
|
||||
super("文件[" + filename + "]后缀[" + extension + "]不正确,请上传" + Arrays.toString(allowedExtension) + "格式");
|
||||
this.allowedExtension = allowedExtension;
|
||||
this.extension = extension;
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
public String[] getAllowedExtension()
|
||||
{
|
||||
return allowedExtension;
|
||||
}
|
||||
|
||||
public String getExtension()
|
||||
{
|
||||
return extension;
|
||||
}
|
||||
|
||||
public String getFilename()
|
||||
{
|
||||
return filename;
|
||||
}
|
||||
|
||||
public static class InvalidImageExtensionException extends InvalidExtensionException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename)
|
||||
{
|
||||
super(allowedExtension, extension, filename);
|
||||
}
|
||||
}
|
||||
|
||||
public static class InvalidFlashExtensionException extends InvalidExtensionException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename)
|
||||
{
|
||||
super(allowedExtension, extension, filename);
|
||||
}
|
||||
}
|
||||
|
||||
public static class InvalidMediaExtensionException extends InvalidExtensionException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename)
|
||||
{
|
||||
super(allowedExtension, extension, filename);
|
||||
}
|
||||
}
|
||||
|
||||
public static class InvalidVideoExtensionException extends InvalidExtensionException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename)
|
||||
{
|
||||
super(allowedExtension, extension, filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -322,4 +322,28 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* * 判断一个对象是否为空
|
||||
*
|
||||
* @param object Object
|
||||
* @return true:为空 false:非空
|
||||
*/
|
||||
public static boolean isNull(Object object)
|
||||
{
|
||||
return object == null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* * 判断一个对象是否非空
|
||||
*
|
||||
* @param object Object
|
||||
* @return true:非空 false:空
|
||||
*/
|
||||
public static boolean isNotNull(Object object)
|
||||
{
|
||||
return !isNull(object);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.ruoyi.common.utils.file;
|
||||
|
||||
import java.io.File;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* 文件类型工具类
|
||||
*
|
||||
* @author industry
|
||||
*/
|
||||
public class FileTypeUtils
|
||||
{
|
||||
/**
|
||||
* 获取文件类型
|
||||
* <p>
|
||||
* 例如: industry.txt, 返回: txt
|
||||
*
|
||||
* @param file 文件名
|
||||
* @return 后缀(不含".")
|
||||
*/
|
||||
public static String getFileType(File file)
|
||||
{
|
||||
if (null == file)
|
||||
{
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
return getFileType(file.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件类型
|
||||
* <p>
|
||||
* 例如: industry.txt, 返回: txt
|
||||
*
|
||||
* @param fileName 文件名
|
||||
* @return 后缀(不含".")
|
||||
*/
|
||||
public static String getFileType(String fileName)
|
||||
{
|
||||
int separatorIndex = fileName.lastIndexOf(".");
|
||||
if (separatorIndex < 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return fileName.substring(separatorIndex + 1).toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件类型
|
||||
*
|
||||
* @param photoByte 文件字节码
|
||||
* @return 后缀(不含".")
|
||||
*/
|
||||
public static String getFileExtendName(byte[] photoByte)
|
||||
{
|
||||
String strFileExtendName = "JPG";
|
||||
if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
|
||||
&& ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97))
|
||||
{
|
||||
strFileExtendName = "GIF";
|
||||
}
|
||||
else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70))
|
||||
{
|
||||
strFileExtendName = "JPG";
|
||||
}
|
||||
else if ((photoByte[0] == 66) && (photoByte[1] == 77))
|
||||
{
|
||||
strFileExtendName = "BMP";
|
||||
}
|
||||
else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71))
|
||||
{
|
||||
strFileExtendName = "PNG";
|
||||
}
|
||||
return strFileExtendName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
package com.ruoyi.common.utils.file;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Objects;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.ruoyi.common.config.RuoYiConfig;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.exception.file.FileNameLengthLimitExceededException;
|
||||
import com.ruoyi.common.exception.file.FileSizeLimitExceededException;
|
||||
import com.ruoyi.common.exception.file.InvalidExtensionException;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.uuid.Seq;
|
||||
|
||||
/**
|
||||
* 文件上传工具类
|
||||
*
|
||||
* @author industry
|
||||
*/
|
||||
public class FileUploadUtils
|
||||
{
|
||||
/**
|
||||
* 默认大小 50M
|
||||
*/
|
||||
public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;
|
||||
|
||||
/**
|
||||
* 默认的文件名最大长度 100
|
||||
*/
|
||||
public static final int DEFAULT_FILE_NAME_LENGTH = 100;
|
||||
|
||||
/**
|
||||
* 默认上传的地址
|
||||
*/
|
||||
private static String defaultBaseDir = RuoYiConfig.getProfile();
|
||||
|
||||
public static void setDefaultBaseDir(String defaultBaseDir)
|
||||
{
|
||||
FileUploadUtils.defaultBaseDir = defaultBaseDir;
|
||||
}
|
||||
|
||||
public static String getDefaultBaseDir()
|
||||
{
|
||||
return defaultBaseDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* 以默认配置进行文件上传
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @return 文件名称
|
||||
* @throws Exception
|
||||
*/
|
||||
public static final String upload(MultipartFile file) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
return upload(getDefaultBaseDir(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new IOException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件路径上传
|
||||
*
|
||||
* @param baseDir 相对应用的基目录
|
||||
* @param file 上传的文件
|
||||
* @return 文件名称
|
||||
* @throws IOException
|
||||
*/
|
||||
public static final String upload(String baseDir, MultipartFile file) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new IOException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*
|
||||
* @param baseDir 相对应用的基目录
|
||||
* @param file 上传的文件
|
||||
* @param allowedExtension 上传文件类型
|
||||
* @return 返回上传成功的文件名
|
||||
* @throws FileSizeLimitExceededException 如果超出最大大小
|
||||
* @throws FileNameLengthLimitExceededException 文件名太长
|
||||
* @throws IOException 比如读写文件出错时
|
||||
* @throws InvalidExtensionException 文件校验异常
|
||||
*/
|
||||
public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
|
||||
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
|
||||
InvalidExtensionException
|
||||
{
|
||||
int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
|
||||
if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
|
||||
{
|
||||
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
|
||||
}
|
||||
|
||||
assertAllowed(file, allowedExtension);
|
||||
|
||||
String fileName = extractFilename(file);
|
||||
|
||||
String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
|
||||
file.transferTo(Paths.get(absPath));
|
||||
return getPathFileName(baseDir, fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编码文件名
|
||||
*/
|
||||
public static final String extractFilename(MultipartFile file)
|
||||
{
|
||||
return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
|
||||
FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file));
|
||||
}
|
||||
|
||||
public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
|
||||
{
|
||||
File desc = new File(uploadDir + File.separator + fileName);
|
||||
|
||||
if (!desc.exists())
|
||||
{
|
||||
if (!desc.getParentFile().exists())
|
||||
{
|
||||
desc.getParentFile().mkdirs();
|
||||
}
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
||||
public static final String getPathFileName(String uploadDir, String fileName) throws IOException
|
||||
{
|
||||
int dirLastIndex = RuoYiConfig.getProfile().length() + 1;
|
||||
String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
|
||||
return Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件大小校验
|
||||
*
|
||||
* @param file 上传的文件
|
||||
* @return
|
||||
* @throws FileSizeLimitExceededException 如果超出最大大小
|
||||
* @throws InvalidExtensionException
|
||||
*/
|
||||
public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
|
||||
throws FileSizeLimitExceededException, InvalidExtensionException
|
||||
{
|
||||
long size = file.getSize();
|
||||
if (size > DEFAULT_MAX_SIZE)
|
||||
{
|
||||
throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
|
||||
}
|
||||
|
||||
String fileName = file.getOriginalFilename();
|
||||
String extension = getExtension(file);
|
||||
if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
|
||||
{
|
||||
if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION)
|
||||
{
|
||||
throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
|
||||
fileName);
|
||||
}
|
||||
else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION)
|
||||
{
|
||||
throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
|
||||
fileName);
|
||||
}
|
||||
else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION)
|
||||
{
|
||||
throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
|
||||
fileName);
|
||||
}
|
||||
else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION)
|
||||
{
|
||||
throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
|
||||
fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidExtensionException(allowedExtension, extension, fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断MIME类型是否是允许的MIME类型
|
||||
*
|
||||
* @param extension
|
||||
* @param allowedExtension
|
||||
* @return
|
||||
*/
|
||||
public static final boolean isAllowedExtension(String extension, String[] allowedExtension)
|
||||
{
|
||||
for (String str : allowedExtension)
|
||||
{
|
||||
if (str.equalsIgnoreCase(extension))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件名的后缀
|
||||
*
|
||||
* @param file 表单文件
|
||||
* @return 后缀名
|
||||
*/
|
||||
public static final String getExtension(MultipartFile file)
|
||||
{
|
||||
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
|
||||
if (StringUtils.isEmpty(extension))
|
||||
{
|
||||
extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType()));
|
||||
}
|
||||
return extension;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
package com.ruoyi.common.utils.file;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@@ -49,4 +52,82 @@ public class FileUtils extends FileUtil {
|
||||
String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
|
||||
return encode.replaceAll("\\+", "%20");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查文件是否可下载
|
||||
*
|
||||
* @param resource 需要下载的文件
|
||||
* @return true 正常 false 非法
|
||||
*/
|
||||
public static boolean checkAllowDownload(String resource)
|
||||
{
|
||||
// 禁止目录上跳级别
|
||||
if (StringUtils.contains(resource, ".."))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查允许下载的文件规则
|
||||
if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 不在允许下载的文件规则
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @param filePath 文件
|
||||
* @return
|
||||
*/
|
||||
public static boolean deleteFile(String filePath)
|
||||
{
|
||||
boolean flag = false;
|
||||
File file = new File(filePath);
|
||||
// 路径为文件且不为空则进行删除
|
||||
if (file.isFile() && file.exists())
|
||||
{
|
||||
flag = file.delete();
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出指定文件的byte数组
|
||||
*
|
||||
* @param filePath 文件路径
|
||||
* @param os 输出流
|
||||
* @return
|
||||
*/
|
||||
public static void writeBytes(String filePath, OutputStream os) throws IOException
|
||||
{
|
||||
FileInputStream fis = null;
|
||||
try
|
||||
{
|
||||
File file = new File(filePath);
|
||||
if (!file.exists())
|
||||
{
|
||||
throw new FileNotFoundException(filePath);
|
||||
}
|
||||
fis = new FileInputStream(file);
|
||||
byte[] b = new byte[1024];
|
||||
int length;
|
||||
while ((length = fis.read(b)) > 0)
|
||||
{
|
||||
os.write(b, 0, length);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtils.close(os);
|
||||
IOUtils.close(fis);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,4 +37,23 @@ public class MimeTypeUtils {
|
||||
// pdf
|
||||
"pdf"};
|
||||
|
||||
|
||||
public static String getExtension(String prefix)
|
||||
{
|
||||
switch (prefix)
|
||||
{
|
||||
case IMAGE_PNG:
|
||||
return "png";
|
||||
case IMAGE_JPG:
|
||||
return "jpg";
|
||||
case IMAGE_JPEG:
|
||||
return "jpeg";
|
||||
case IMAGE_BMP:
|
||||
return "bmp";
|
||||
case IMAGE_GIF:
|
||||
return "gif";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.ruoyi.common.utils.uuid;
|
||||
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* @author industry 序列生成类
|
||||
*/
|
||||
public class Seq
|
||||
{
|
||||
// 通用序列类型
|
||||
public static final String commSeqType = "COMMON";
|
||||
|
||||
// 上传序列类型
|
||||
public static final String uploadSeqType = "UPLOAD";
|
||||
|
||||
// 通用接口序列数
|
||||
private static AtomicInteger commSeq = new AtomicInteger(1);
|
||||
|
||||
// 上传接口序列数
|
||||
private static AtomicInteger uploadSeq = new AtomicInteger(1);
|
||||
|
||||
// 机器标识
|
||||
private static final String machineCode = "A";
|
||||
|
||||
/**
|
||||
* 获取通用序列号
|
||||
*
|
||||
* @return 序列值
|
||||
*/
|
||||
public static String getId()
|
||||
{
|
||||
return getId(commSeqType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认16位序列号 yyMMddHHmmss + 一位机器标识 + 3长度循环递增字符串
|
||||
*
|
||||
* @return 序列值
|
||||
*/
|
||||
public static String getId(String type)
|
||||
{
|
||||
AtomicInteger atomicInt = commSeq;
|
||||
if (uploadSeqType.equals(type))
|
||||
{
|
||||
atomicInt = uploadSeq;
|
||||
}
|
||||
return getId(atomicInt, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用接口序列号 yyMMddHHmmss + 一位机器标识 + length长度循环递增字符串
|
||||
*
|
||||
* @param atomicInt 序列数
|
||||
* @param length 数值长度
|
||||
* @return 序列值
|
||||
*/
|
||||
public static String getId(AtomicInteger atomicInt, int length)
|
||||
{
|
||||
String result = DateUtils.dateTimeNow();
|
||||
result += machineCode;
|
||||
result += getSeq(atomicInt, length);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 序列循环递增字符串[1, 10 的 (length)幂次方), 用0左补齐length位数
|
||||
*
|
||||
* @return 序列值
|
||||
*/
|
||||
private synchronized static String getSeq(AtomicInteger atomicInt, int length)
|
||||
{
|
||||
// 先取值再+1
|
||||
int value = atomicInt.getAndIncrement();
|
||||
|
||||
// 如果更新后值>=10 的 (length)幂次方则重置为1
|
||||
int maxSeq = (int) Math.pow(10, length);
|
||||
if (atomicInt.get() >= maxSeq)
|
||||
{
|
||||
atomicInt.set(1);
|
||||
}
|
||||
// 转字符串,用0左补齐
|
||||
return StringUtils.padl(value, length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.ruoyi.framework.config;
|
||||
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.ruoyi.common.utils.ServletUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 服务相关配置
|
||||
*
|
||||
* @author industry
|
||||
*/
|
||||
@Component
|
||||
public class ServerConfig
|
||||
{
|
||||
/**
|
||||
* 获取完整的请求路径,包括:域名,端口,上下文访问路径
|
||||
*
|
||||
* @return 服务地址
|
||||
*/
|
||||
public String getUrl()
|
||||
{
|
||||
HttpServletRequest request = ServletUtils.getRequest();
|
||||
return getDomain(request);
|
||||
}
|
||||
|
||||
public static String getDomain(HttpServletRequest request)
|
||||
{
|
||||
StringBuffer url = request.getRequestURL();
|
||||
String contextPath = request.getServletContext().getContextPath();
|
||||
return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString();
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
<!-- 文件列表 -->
|
||||
<transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
|
||||
<li :key="file.url" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
|
||||
<el-link :href="`${file.url}`" :underline="false" target="_blank">
|
||||
<el-link :href="`${baseUrl}${file.url}`" :underline="false" target="_blank">
|
||||
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
|
||||
</el-link>
|
||||
<div class="ele-upload-list__item-content-action">
|
||||
@@ -41,7 +41,6 @@
|
||||
|
||||
<script>
|
||||
import { getToken } from "@/utils/auth";
|
||||
import { listByIds, delOss } from "@/api/system/oss";
|
||||
|
||||
export default {
|
||||
name: "FileUpload",
|
||||
@@ -56,12 +55,12 @@ export default {
|
||||
// 大小限制(MB)
|
||||
fileSize: {
|
||||
type: Number,
|
||||
default: 100,
|
||||
default: 5,
|
||||
},
|
||||
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
||||
fileType: {
|
||||
type: Array,
|
||||
default: () => ["doc", "docx", "xls","pdf","xlsx"],
|
||||
default: () => ["doc", "xls", "ppt", "txt", "pdf","docx", "xlsx"],
|
||||
},
|
||||
// 是否显示提示
|
||||
isShowTip: {
|
||||
@@ -74,7 +73,7 @@ export default {
|
||||
number: 0,
|
||||
uploadList: [],
|
||||
baseUrl: process.env.VUE_APP_BASE_API,
|
||||
uploadFileUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上传文件服务器地址
|
||||
uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传文件服务器地址
|
||||
headers: {
|
||||
Authorization: "Bearer " + getToken(),
|
||||
},
|
||||
@@ -83,24 +82,16 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
async handler(val) {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
let temp = 1;
|
||||
// 首先将值转为数组
|
||||
let list;
|
||||
if (Array.isArray(val)) {
|
||||
list = val;
|
||||
} else {
|
||||
await listByIds(val).then(res => {
|
||||
list = res.data.map(oss => {
|
||||
oss = { name: oss.originalName, url: oss.url, ossId: oss.ossId };
|
||||
return oss;
|
||||
});
|
||||
})
|
||||
}
|
||||
const list = Array.isArray(val) ? val : this.value.split(',');
|
||||
// 然后将数组转为对象数组
|
||||
this.fileList = list.map(item => {
|
||||
item = { name: item.name, url: item.url, ossId: item.ossId };
|
||||
if (typeof item === "string") {
|
||||
item = { name: item, url: item };
|
||||
}
|
||||
item.uid = item.uid || new Date().getTime() + temp++;
|
||||
return item;
|
||||
});
|
||||
@@ -156,7 +147,7 @@ export default {
|
||||
// 上传成功回调
|
||||
handleUploadSuccess(res, file) {
|
||||
if (res.code === 200) {
|
||||
this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
|
||||
this.uploadList.push({ name: res.fileName, url: res.fileName });
|
||||
this.uploadedSuccessfully();
|
||||
} else {
|
||||
this.number--;
|
||||
@@ -168,8 +159,6 @@ export default {
|
||||
},
|
||||
// 删除文件
|
||||
handleDelete(index) {
|
||||
let ossId = this.fileList[index].ossId;
|
||||
delOss(ossId);
|
||||
this.fileList.splice(index, 1);
|
||||
this.$emit("input", this.listToString(this.fileList));
|
||||
},
|
||||
@@ -197,11 +186,11 @@ export default {
|
||||
let strs = "";
|
||||
separator = separator || ",";
|
||||
for (let i in list) {
|
||||
strs += list[i].ossId + separator;
|
||||
strs += list[i].url + separator;
|
||||
}
|
||||
return strs != "" ? strs.substr(0, strs.length - 1) : "";
|
||||
},
|
||||
},
|
||||
return strs != '' ? strs.substr(0, strs.length - 1) : '';
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
|
||||
<script>
|
||||
import { getToken } from "@/utils/auth";
|
||||
import { listByIds, delOss } from "@/api/system/oss";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
@@ -56,7 +55,7 @@ export default {
|
||||
},
|
||||
// 大小限制(MB)
|
||||
fileSize: {
|
||||
type: Number,
|
||||
type: Number,
|
||||
default: 5,
|
||||
},
|
||||
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
||||
@@ -78,7 +77,7 @@ export default {
|
||||
dialogVisible: false,
|
||||
hideUpload: false,
|
||||
baseUrl: process.env.VUE_APP_BASE_API,
|
||||
uploadImgUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上传的图片服务器地址
|
||||
uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
|
||||
headers: {
|
||||
Authorization: "Bearer " + getToken(),
|
||||
},
|
||||
@@ -87,21 +86,19 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
async handler(val) {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
// 首先将值转为数组
|
||||
let list;
|
||||
if (Array.isArray(val)) {
|
||||
list = val;
|
||||
} else {
|
||||
await listByIds(val).then(res => {
|
||||
list = res.data;
|
||||
})
|
||||
}
|
||||
const list = Array.isArray(val) ? val : this.value.split(',');
|
||||
// 然后将数组转为对象数组
|
||||
this.fileList = list.map(item => {
|
||||
// 此处name使用ossId 防止删除出现重名
|
||||
item = { name: item.ossId, url: item.url, ossId: item.ossId };
|
||||
if (typeof item === "string") {
|
||||
if (item.indexOf(this.baseUrl) === -1) {
|
||||
item = { name: this.baseUrl + item, url: this.baseUrl + item };
|
||||
} else {
|
||||
item = { name: item, url: item };
|
||||
}
|
||||
}
|
||||
return item;
|
||||
});
|
||||
} else {
|
||||
@@ -128,7 +125,7 @@ export default {
|
||||
if (file.name.lastIndexOf(".") > -1) {
|
||||
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
|
||||
}
|
||||
isImg = this.fileType.some((type) => {
|
||||
isImg = this.fileType.some(type => {
|
||||
if (file.type.indexOf(type) > -1) return true;
|
||||
if (fileExtension && fileExtension.indexOf(type) > -1) return true;
|
||||
return false;
|
||||
@@ -158,7 +155,7 @@ export default {
|
||||
// 上传成功回调
|
||||
handleUploadSuccess(res, file) {
|
||||
if (res.code === 200) {
|
||||
this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
|
||||
this.uploadList.push({name: res.fileName, url: res.fileName});
|
||||
this.uploadedSuccessfully();
|
||||
} else {
|
||||
this.number--;
|
||||
@@ -171,15 +168,13 @@ export default {
|
||||
// 删除图片
|
||||
handleDelete(file) {
|
||||
const findex = this.fileList.map(f => f.name).indexOf(file.name);
|
||||
if(findex > -1) {
|
||||
let ossId = this.fileList[findex].ossId;
|
||||
delOss(ossId);
|
||||
if (findex > -1) {
|
||||
this.fileList.splice(findex, 1);
|
||||
this.$emit("input", this.listToString(this.fileList));
|
||||
}
|
||||
},
|
||||
// 上传失败
|
||||
handleUploadError(res) {
|
||||
handleUploadError() {
|
||||
this.$modal.msgError("上传图片失败,请重试");
|
||||
this.$modal.closeLoading();
|
||||
},
|
||||
@@ -203,11 +198,11 @@ export default {
|
||||
let strs = "";
|
||||
separator = separator || ",";
|
||||
for (let i in list) {
|
||||
if (list[i].ossId) {
|
||||
strs += list[i].ossId + separator;
|
||||
if (list[i].url) {
|
||||
strs += list[i].url.replace(this.baseUrl, "") + separator;
|
||||
}
|
||||
}
|
||||
return strs != "" ? strs.substr(0, strs.length - 1) : "";
|
||||
return strs != '' ? strs.substr(0, strs.length - 1) : '';
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -215,12 +210,13 @@ export default {
|
||||
<style scoped lang="scss">
|
||||
// .el-upload--picture-card 控制加号部分
|
||||
::v-deep.hide .el-upload--picture-card {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
// 去掉动画效果
|
||||
::v-deep .el-list-enter-active,
|
||||
::v-deep .el-list-leave-active {
|
||||
transition: all 0s;
|
||||
transition: all 0s;
|
||||
}
|
||||
|
||||
::v-deep .el-list-enter, .el-list-leave-active {
|
||||
|
||||
@@ -9,8 +9,44 @@ const baseURL = process.env.VUE_APP_BASE_API
|
||||
let downloadLoadingInstance;
|
||||
|
||||
export default {
|
||||
oss(ossId) {
|
||||
var url = baseURL + '/system/oss/download/' + ossId
|
||||
name(name, isDelete = false) {
|
||||
var url = baseURL + "/common/download?fileName=" + encodeURIComponent(name) + "&delete=" + isDelete
|
||||
axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
responseType: 'blob',
|
||||
headers: { 'Authorization': 'Bearer ' + getToken() }
|
||||
}).then((res) => {
|
||||
const isBlob = blobValidate(res.data);
|
||||
if (isBlob) {
|
||||
const blob = new Blob([res.data])
|
||||
this.saveAs(blob, decodeURIComponent(res.headers['download-filename']))
|
||||
} else {
|
||||
this.printErrMsg(res.data);
|
||||
}
|
||||
})
|
||||
},
|
||||
resource(resource) {
|
||||
console.log(resource)
|
||||
var url = baseURL + "/common/download/resource?resource=" + encodeURIComponent(resource);
|
||||
console.log(url)
|
||||
axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
responseType: 'blob',
|
||||
headers: { 'Authorization': 'Bearer ' + getToken() }
|
||||
}).then((res) => {
|
||||
const isBlob = blobValidate(res.data);
|
||||
if (isBlob) {
|
||||
const blob = new Blob([res.data])
|
||||
this.saveAs(blob, decodeURIComponent(res.headers['download-filename']))
|
||||
} else {
|
||||
this.printErrMsg(res.data);
|
||||
}
|
||||
})
|
||||
},
|
||||
zip(url, name) {
|
||||
var url = baseURL + url
|
||||
downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
|
||||
axios({
|
||||
method: 'get',
|
||||
@@ -20,8 +56,8 @@ export default {
|
||||
}).then((res) => {
|
||||
const isBlob = blobValidate(res.data);
|
||||
if (isBlob) {
|
||||
const blob = new Blob([res.data], { type: 'application/octet-stream' })
|
||||
this.saveAs(blob, decodeURIComponent(res.headers['download-filename']))
|
||||
const blob = new Blob([res.data], { type: 'application/zip' })
|
||||
this.saveAs(blob, name)
|
||||
} else {
|
||||
this.printErrMsg(res.data);
|
||||
}
|
||||
@@ -32,26 +68,6 @@ export default {
|
||||
downloadLoadingInstance.close();
|
||||
})
|
||||
},
|
||||
zip(url, name) {
|
||||
var url = baseURL + url
|
||||
axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
responseType: 'blob',
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + getToken(),
|
||||
'datasource': localStorage.getItem("dataName")
|
||||
}
|
||||
}).then((res) => {
|
||||
const isBlob = blobValidate(res.data);
|
||||
if (isBlob) {
|
||||
const blob = new Blob([res.data], { type: 'application/zip' })
|
||||
this.saveAs(blob, name)
|
||||
} else {
|
||||
this.printErrMsg(res.data);
|
||||
}
|
||||
})
|
||||
},
|
||||
saveAs(text, name, opts) {
|
||||
saveAs(text, name, opts);
|
||||
},
|
||||
|
||||
@@ -170,7 +170,7 @@ export default {
|
||||
};
|
||||
// 点击文件列表中已上传的文件时的钩子
|
||||
cur['on-preview'] = (file) => {
|
||||
this.$download.oss(file.ossId)
|
||||
this.$download(file.ossId)
|
||||
}
|
||||
}
|
||||
if (config.children) {
|
||||
|
||||
@@ -574,7 +574,9 @@
|
||||
<el-descriptions-item label="附件" :span="3" :labelStyle="lableBg">
|
||||
<!--附件-->
|
||||
<template v-if="form.accessory">
|
||||
<ImageOss :name="form.accessory"/>
|
||||
<el-tooltip class="item" effect="dark" content="点击下载" placement="bottom">
|
||||
<el-link type="primary" @click="downloadFile(form.accessory)">{{form.accessory.match('[^/]+(?!.*/)')[0]}}</el-link>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span style="color: #999999">暂无附件</span>
|
||||
@@ -1217,6 +1219,11 @@ export default {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
/** 下载文件 */
|
||||
downloadFile(filePath){
|
||||
this.$download.resource(filePath)
|
||||
|
||||
},
|
||||
|
||||
// 多选框选中数据
|
||||
/* handleSelectionChange(selection) {
|
||||
|
||||
@@ -454,7 +454,9 @@
|
||||
<el-descriptions-item label="附件" :span="4" :labelStyle="lableBg">
|
||||
<!--附件-->
|
||||
<template v-if="form.accessory">
|
||||
<ImageOss :name="form.accessory"/>
|
||||
<el-tooltip class="item" effect="dark" content="点击下载" placement="bottom">
|
||||
<el-link type="primary" @click="downloadFile(form.accessory)">{{form.accessory.match('[^/]+(?!.*/)')[0]}}</el-link>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span style="color: #999999">暂无附件</span>
|
||||
@@ -1335,6 +1337,11 @@ export default {
|
||||
this.download('oa/finance/export', {
|
||||
...this.queryParams
|
||||
}, `finance_${new Date().getTime()}.xlsx`)
|
||||
},
|
||||
/** 下载文件 */
|
||||
downloadFile(filePath){
|
||||
this.$download.resource(filePath)
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -422,7 +422,9 @@
|
||||
|
||||
<!--附件-->
|
||||
<template v-if="form.accessory">
|
||||
<ImageOss :name="form.accessory"/>
|
||||
<el-tooltip class="item" effect="dark" content="点击下载" placement="bottom">
|
||||
<el-link type="primary" @click="downloadFile(form.accessory)">{{form.accessory.match('[^/]+(?!.*/)')[0]}}</el-link>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span style="color: #999999">暂无附件</span>
|
||||
@@ -876,6 +878,11 @@ export default {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
/** 下载文件 */
|
||||
downloadFile(filePath){
|
||||
this.$download.resource(filePath)
|
||||
|
||||
},
|
||||
//tabs标签
|
||||
handleClick(tab, event) {
|
||||
// console.log(tab, event);
|
||||
|
||||
@@ -235,7 +235,9 @@
|
||||
</template>
|
||||
<!--附件-->
|
||||
<template v-if="form.accessory">
|
||||
<ImageOss :name="form.accessory"/>
|
||||
<el-tooltip class="item" effect="dark" content="点击下载" placement="bottom">
|
||||
<el-link type="primary" @click="downloadFile(form.accessory)">{{form.accessory.match('[^/]+(?!.*/)')[0]}}</el-link>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span style="color: #999999">暂无附件</span>
|
||||
@@ -519,6 +521,11 @@ export default {
|
||||
this.title = "修改合同管理";
|
||||
});
|
||||
},
|
||||
/** 下载文件 */
|
||||
downloadFile(filePath){
|
||||
this.$download.resource(filePath)
|
||||
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
|
||||
@@ -225,7 +225,9 @@
|
||||
</template>
|
||||
<!--附件-->
|
||||
<template v-if="form.accessory">
|
||||
<ImageOss :name="form.accessory"/>
|
||||
<el-tooltip class="item" effect="dark" content="点击下载" placement="bottom">
|
||||
<el-link type="primary" @click="downloadFile(form.accessory)">{{form.accessory.match('[^/]+(?!.*/)')[0]}}</el-link>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span style="color: #999999">暂无附件</span>
|
||||
@@ -585,7 +587,9 @@
|
||||
</template>
|
||||
<!--附件-->
|
||||
<template v-if="form.accessory">
|
||||
<ImageOss :name="form.accessory"/>
|
||||
<el-tooltip class="item" effect="dark" content="点击下载" placement="bottom">
|
||||
<el-link type="primary" @click="downloadFile(form.accessory)">{{form.accessory.match('[^/]+(?!.*/)')[0]}}</el-link>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span style="color: #999999">暂无附件</span>
|
||||
@@ -742,6 +746,7 @@ export default {
|
||||
//点击添加按钮状态
|
||||
addBottomStatus: false,
|
||||
openForm: false,
|
||||
downLoadUrl :process.env.VUE_APP_BASE_API+'/common/download' ,
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 按钮loading
|
||||
@@ -1069,6 +1074,12 @@ export default {
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
|
||||
/** 下载文件 */
|
||||
downloadFile(filePath){
|
||||
this.$download.resource(filePath)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +313,9 @@
|
||||
</template>
|
||||
<!--附件-->
|
||||
<template v-if="form.accessory">
|
||||
<ImageOss :name="form.accessory"/>
|
||||
<el-tooltip class="item" effect="dark" content="点击下载" placement="bottom">
|
||||
<el-link type="primary" @click="downloadFile(form.accessory)">{{form.accessory.match('[^/]+(?!.*/)')[0]}}</el-link>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span style="color: #999999">暂无附件</span>
|
||||
@@ -634,7 +636,9 @@
|
||||
</template>
|
||||
<!--附件-->
|
||||
<template v-if="item.accessory">
|
||||
<ImageOss :name="item.accessory"/>
|
||||
<el-tooltip class="item" effect="dark" content="点击下载" placement="bottom">
|
||||
<el-link type="primary" @click="downloadFile(form.accessory)">{{form.accessory.match('[^/]+(?!.*/)')[0]}}</el-link>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span style="color: #999999">暂无附件</span>
|
||||
@@ -887,7 +891,9 @@
|
||||
</template>
|
||||
<!--附件-->
|
||||
<template v-if="contractForm.accessory">
|
||||
<ImageOss :name="contractForm.accessory"/>
|
||||
<el-tooltip class="item" effect="dark" content="点击下载" placement="bottom">
|
||||
<el-link type="primary" @click="downloadFile(form.accessory)">{{form.accessory.match('[^/]+(?!.*/)')[0]}}</el-link>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span style="color: #999999">暂无附件</span>
|
||||
@@ -1165,7 +1171,9 @@
|
||||
</template>
|
||||
<!--附件-->
|
||||
<template v-if="contractForm.accessory">
|
||||
<ImageOss :name="contractForm.accessory"/>
|
||||
<el-tooltip class="item" effect="dark" content="点击下载" placement="bottom">
|
||||
<el-link type="primary" @click="downloadFile(form.accessory)">{{form.accessory.match('[^/]+(?!.*/)')[0]}}</el-link>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span style="color: #999999">暂无附件</span>
|
||||
@@ -1520,6 +1528,11 @@ export default {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 下载文件 */
|
||||
downloadFile(filePath){
|
||||
this.$download.resource(filePath)
|
||||
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.searchTime = [];
|
||||
|
||||
@@ -156,7 +156,9 @@
|
||||
<el-descriptions-item label="附件" span="4" :labelStyle="lableBg">
|
||||
<!--附件-->
|
||||
<template v-if="formQuery.accessory">
|
||||
<ImageOss :name="formQuery.accessory"/>
|
||||
<el-tooltip class="item" effect="dark" content="点击下载" placement="bottom">
|
||||
<el-link type="primary" @click="downloadFile(form.accessory)">{{form.accessory.match('[^/]+(?!.*/)')[0]}}</el-link>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span style="color: #999999">暂无附件</span>
|
||||
@@ -341,6 +343,11 @@ export default {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
/** 下载文件 */
|
||||
downloadFile(filePath){
|
||||
this.$download.resource(filePath)
|
||||
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.purposeId)
|
||||
|
||||
@@ -146,7 +146,9 @@
|
||||
</template>
|
||||
<!--附件-->
|
||||
<template v-if="lookRemind.accessory">
|
||||
<ImageOss :name="lookRemind.accessory"/>
|
||||
<el-tooltip class="item" effect="dark" content="点击下载" placement="bottom">
|
||||
<el-link type="primary" @click="downloadFile(form.accessory)">{{form.accessory.match('[^/]+(?!.*/)')[0]}}</el-link>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span style="color: #999999">暂无附件</span>
|
||||
@@ -186,7 +188,9 @@
|
||||
</template>
|
||||
<!--附件-->
|
||||
<template v-if="form.accessory">
|
||||
<ImageOss :name="form.accessory"/>
|
||||
<el-tooltip class="item" effect="dark" content="点击下载" placement="bottom">
|
||||
<el-link type="primary" @click="downloadFile(form.accessory)">{{form.accessory.match('[^/]+(?!.*/)')[0]}}</el-link>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span style="color: #999999">暂无附件</span>
|
||||
@@ -470,7 +474,11 @@ export default {
|
||||
this.openTask = false;
|
||||
this.reset();
|
||||
},
|
||||
/** 下载文件 */
|
||||
downloadFile(filePath){
|
||||
this.$download.resource(filePath)
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +151,9 @@
|
||||
<el-descriptions-item label="附件" :labelStyle="lableBg" span="4">
|
||||
<!--附件-->
|
||||
<template v-if="formLook.accessory">
|
||||
<ImageOss :name="formLook.accessory"/>
|
||||
<el-tooltip class="item" effect="dark" content="点击下载" placement="bottom">
|
||||
<el-link type="primary" @click="downloadFile(form.accessory)">{{form.accessory.match('[^/]+(?!.*/)')[0]}}</el-link>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span style="color: #999999">暂无附件</span>
|
||||
@@ -415,6 +417,11 @@ export default {
|
||||
this.download('oa/remind/export', {
|
||||
...this.queryParams
|
||||
}, `remind_${new Date().getTime()}.xlsx`)
|
||||
},
|
||||
/** 下载文件 */
|
||||
downloadFile(filePath){
|
||||
this.$download.resource(filePath)
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -383,7 +383,7 @@ export default {
|
||||
},
|
||||
/** 下载按钮操作 */
|
||||
handleDownload(row) {
|
||||
this.$download.oss(row.ossId)
|
||||
this.$download(row.ossId)
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
|
||||
Reference in New Issue
Block a user