作者 RuoYi

组件fileUpload支持多文件同时选择上传

@@ -531,4 +531,53 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils @@ -531,4 +531,53 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
531 { 531 {
532 return (T) obj; 532 return (T) obj;
533 } 533 }
  534 +
  535 + /**
  536 + * 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。
  537 + *
  538 + * @param num 数字对象
  539 + * @param size 字符串指定长度
  540 + * @return 返回数字的字符串格式,该字符串为指定长度。
  541 + */
  542 + public static final String padl(final Number num, final int size)
  543 + {
  544 + return padl(num.toString(), size, '0');
  545 + }
  546 +
  547 + /**
  548 + * 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。
  549 + *
  550 + * @param s 原始字符串
  551 + * @param size 字符串指定长度
  552 + * @param c 用于补齐的字符
  553 + * @return 返回指定长度的字符串,由原字符串左补齐或截取得到。
  554 + */
  555 + public static final String padl(final String s, final int size, final char c)
  556 + {
  557 + final StringBuilder sb = new StringBuilder(size);
  558 + if (s != null)
  559 + {
  560 + final int len = s.length();
  561 + if (s.length() <= size)
  562 + {
  563 + for (int i = size - len; i > 0; i--)
  564 + {
  565 + sb.append(c);
  566 + }
  567 + sb.append(s);
  568 + }
  569 + else
  570 + {
  571 + return s.substring(len - size, len);
  572 + }
  573 + }
  574 + else
  575 + {
  576 + for (int i = size; i > 0; i--)
  577 + {
  578 + sb.append(c);
  579 + }
  580 + }
  581 + return sb.toString();
  582 + }
534 } 583 }
@@ -12,7 +12,7 @@ import com.ruoyi.common.exception.file.FileSizeLimitExceededException; @@ -12,7 +12,7 @@ import com.ruoyi.common.exception.file.FileSizeLimitExceededException;
12 import com.ruoyi.common.exception.file.InvalidExtensionException; 12 import com.ruoyi.common.exception.file.InvalidExtensionException;
13 import com.ruoyi.common.utils.DateUtils; 13 import com.ruoyi.common.utils.DateUtils;
14 import com.ruoyi.common.utils.StringUtils; 14 import com.ruoyi.common.utils.StringUtils;
15 -import com.ruoyi.common.utils.uuid.IdUtils; 15 +import com.ruoyi.common.utils.uuid.Seq;
16 16
17 /** 17 /**
18 * 文件上传工具类 18 * 文件上传工具类
@@ -121,7 +121,8 @@ public class FileUploadUtils @@ -121,7 +121,8 @@ public class FileUploadUtils
121 */ 121 */
122 public static final String extractFilename(MultipartFile file) 122 public static final String extractFilename(MultipartFile file)
123 { 123 {
124 - return DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + getExtension(file); 124 + return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
  125 + FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file));
125 } 126 }
126 127
127 public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException 128 public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
  1 +package com.ruoyi.common.utils.uuid;
  2 +
  3 +import java.util.concurrent.atomic.AtomicInteger;
  4 +import com.ruoyi.common.utils.DateUtils;
  5 +import com.ruoyi.common.utils.StringUtils;
  6 +
  7 +/**
  8 + * @author ruoyi 序列生成类
  9 + */
  10 +public class Seq
  11 +{
  12 + // 通用序列类型
  13 + public static final String commSeqType = "COMMON";
  14 +
  15 + // 上传序列类型
  16 + public static final String uploadSeqType = "UPLOAD";
  17 +
  18 + // 通用接口序列数
  19 + private static AtomicInteger commSeq = new AtomicInteger(1);
  20 +
  21 + // 上传接口序列数
  22 + private static AtomicInteger uploadSeq = new AtomicInteger(1);
  23 +
  24 + // 机器标识
  25 + private static String machineCode = "A";
  26 +
  27 + /**
  28 + * 获取通用序列号
  29 + *
  30 + * @return 序列值
  31 + */
  32 + public static String getId()
  33 + {
  34 + return getId(commSeqType);
  35 + }
  36 +
  37 + /**
  38 + * 默认16位序列号 yyMMddHHmmss + 一位机器标识 + 3长度循环递增字符串
  39 + *
  40 + * @return 序列值
  41 + */
  42 + public static String getId(String type)
  43 + {
  44 + AtomicInteger atomicInt = commSeq;
  45 + if (uploadSeqType.equals(type))
  46 + {
  47 + atomicInt = uploadSeq;
  48 + }
  49 + return getId(atomicInt, 3);
  50 + }
  51 +
  52 + /**
  53 + * 通用接口序列号 yyMMddHHmmss + 一位机器标识 + length长度循环递增字符串
  54 + *
  55 + * @param atomicInt 序列数
  56 + * @param length 数值长度
  57 + * @return 序列值
  58 + */
  59 + public static String getId(AtomicInteger atomicInt, int length)
  60 + {
  61 + String result = DateUtils.dateTimeNow();
  62 + result += machineCode;
  63 + result += getSeq(atomicInt, length);
  64 + return result;
  65 + }
  66 +
  67 + /**
  68 + * 序列循环递增字符串[1, 10 的 (length)幂次方), 用0左补齐length位数
  69 + *
  70 + * @return 序列值
  71 + */
  72 + private synchronized static String getSeq(AtomicInteger atomicInt, int length)
  73 + {
  74 + // 先取值再+1
  75 + int value = atomicInt.getAndIncrement();
  76 +
  77 + // 如果更新后值>=10 的 (length)幂次方则重置为1
  78 + int maxSeq = (int) Math.pow(10, length);
  79 + if (atomicInt.get() >= maxSeq)
  80 + {
  81 + atomicInt.set(1);
  82 + }
  83 + // 转字符串,用0左补齐
  84 + return StringUtils.padl(value, length);
  85 + }
  86 +}
1 <template> 1 <template>
2 <div class="upload-file"> 2 <div class="upload-file">
3 <el-upload 3 <el-upload
  4 + multiple
4 :action="uploadFileUrl" 5 :action="uploadFileUrl"
5 :before-upload="handleBeforeUpload" 6 :before-upload="handleBeforeUpload"
6 :file-list="fileList" 7 :file-list="fileList"
@@ -69,6 +70,8 @@ export default { @@ -69,6 +70,8 @@ export default {
69 }, 70 },
70 data() { 71 data() {
71 return { 72 return {
  73 + number: 0,
  74 + uploadList: [],
72 baseUrl: process.env.VUE_APP_BASE_API, 75 baseUrl: process.env.VUE_APP_BASE_API,
73 uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址 76 uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
74 headers: { 77 headers: {
@@ -122,7 +125,7 @@ export default { @@ -122,7 +125,7 @@ export default {
122 return false; 125 return false;
123 }); 126 });
124 if (!isTypeOk) { 127 if (!isTypeOk) {
125 - this.$message.error(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`); 128 + this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
126 return false; 129 return false;
127 } 130 }
128 } 131 }
@@ -130,25 +133,33 @@ export default { @@ -130,25 +133,33 @@ export default {
130 if (this.fileSize) { 133 if (this.fileSize) {
131 const isLt = file.size / 1024 / 1024 < this.fileSize; 134 const isLt = file.size / 1024 / 1024 < this.fileSize;
132 if (!isLt) { 135 if (!isLt) {
133 - this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`); 136 + this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`);
134 return false; 137 return false;
135 } 138 }
136 } 139 }
  140 + this.$modal.loading("正在上传文件,请稍候...");
  141 + this.number++;
137 return true; 142 return true;
138 }, 143 },
139 // 文件个数超出 144 // 文件个数超出
140 handleExceed() { 145 handleExceed() {
141 - this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`); 146 + this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
142 }, 147 },
143 // 上传失败 148 // 上传失败
144 handleUploadError(err) { 149 handleUploadError(err) {
145 - this.$message.error("上传失败, 请重试"); 150 + this.$modal.msgError("上传图片失败,请重试");
  151 + this.$modal.closeLoading()
146 }, 152 },
147 // 上传成功回调 153 // 上传成功回调
148 - handleUploadSuccess(res, file) {  
149 - this.$message.success("上传成功");  
150 - this.fileList.push({ name: res.fileName, url: res.fileName });  
151 - this.$emit("input", this.listToString(this.fileList)); 154 + handleUploadSuccess(res) {
  155 + this.uploadList.push({ name: res.fileName, url: res.fileName });
  156 + if (this.uploadList.length === this.number) {
  157 + this.fileList = this.fileList.concat(this.uploadList);
  158 + this.uploadList = [];
  159 + this.number = 0;
  160 + this.$emit("input", this.listToString(this.fileList));
  161 + this.$modal.closeLoading();
  162 + }
152 }, 163 },
153 // 删除文件 164 // 删除文件
154 handleDelete(index) { 165 handleDelete(index) {
@@ -158,7 +169,7 @@ export default { @@ -158,7 +169,7 @@ export default {
158 // 获取文件名称 169 // 获取文件名称
159 getFileName(name) { 170 getFileName(name) {
160 if (name.lastIndexOf("/") > -1) { 171 if (name.lastIndexOf("/") > -1) {
161 - return name.slice(name.lastIndexOf("/") + 1).toLowerCase(); 172 + return name.slice(name.lastIndexOf("/") + 1);
162 } else { 173 } else {
163 return ""; 174 return "";
164 } 175 }
@@ -133,7 +133,7 @@ export default { @@ -133,7 +133,7 @@ export default {
133 this.uploadList = []; 133 this.uploadList = [];
134 this.number = 0; 134 this.number = 0;
135 this.$emit("input", this.listToString(this.fileList)); 135 this.$emit("input", this.listToString(this.fileList));
136 - this.loading.close(); 136 + this.$modal.closeLoading();
137 } 137 }
138 }, 138 },
139 // 上传前loading加载 139 // 上传前loading加载
@@ -154,36 +154,27 @@ export default { @@ -154,36 +154,27 @@ export default {
154 } 154 }
155 155
156 if (!isImg) { 156 if (!isImg) {
157 - this.$message.error(  
158 - `文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`  
159 - ); 157 + this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`);
160 return false; 158 return false;
161 } 159 }
162 if (this.fileSize) { 160 if (this.fileSize) {
163 const isLt = file.size / 1024 / 1024 < this.fileSize; 161 const isLt = file.size / 1024 / 1024 < this.fileSize;
164 if (!isLt) { 162 if (!isLt) {
165 - this.$message.error(`上传头像图片大小不能超过 ${this.fileSize} MB!`); 163 + this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`);
166 return false; 164 return false;
167 } 165 }
168 } 166 }
169 - this.loading = this.$loading({  
170 - lock: true,  
171 - text: "上传中",  
172 - background: "rgba(0, 0, 0, 0.7)",  
173 - }); 167 + this.$modal.loading("正在上传图片,请稍候...");
174 this.number++; 168 this.number++;
175 }, 169 },
176 // 文件个数超出 170 // 文件个数超出
177 handleExceed() { 171 handleExceed() {
178 - this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`); 172 + this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
179 }, 173 },
180 // 上传失败 174 // 上传失败
181 handleUploadError() { 175 handleUploadError() {
182 - this.$message({  
183 - type: "error",  
184 - message: "上传失败",  
185 - });  
186 - this.loading.close(); 176 + this.$modal.msgError("上传图片失败,请重试");
  177 + this.$modal.closeLoading();
187 }, 178 },
188 // 预览 179 // 预览
189 handlePictureCardPreview(file) { 180 handlePictureCardPreview(file) {
@@ -443,7 +443,7 @@ export default { @@ -443,7 +443,7 @@ export default {
443 email: [ 443 email: [
444 { 444 {
445 type: "email", 445 type: "email",
446 - message: "'请输入正确的邮箱地址", 446 + message: "请输入正确的邮箱地址",
447 trigger: ["blur", "change"] 447 trigger: ["blur", "change"]
448 } 448 }
449 ], 449 ],