index.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <template>
  2. <div class="upload-file">
  3. <el-upload
  4. drag
  5. multiple
  6. :action="uploadFileUrl"
  7. :before-upload="handleBeforeUpload"
  8. :file-list="fileList"
  9. :limit="limit"
  10. :on-error="handleUploadError"
  11. :on-exceed="handleExceed"
  12. :on-success="handleUploadSuccess"
  13. :show-file-list="false"
  14. :headers="headers"
  15. class="upload-file-uploader"
  16. ref="fileUpload"
  17. >
  18. <!-- 上传按钮 -->
  19. <!-- <el-button size="mini" type="primary">选取文件</el-button> -->
  20. <i class="el-icon-upload"></i>
  21. <div class="el-upload__text">
  22. 将文件拖到此处,或
  23. <em>点击上传</em>
  24. </div>
  25. <!-- 上传提示 -->
  26. <div class="el-upload__tip" slot="tip" v-if="showTip">
  27. 请上传
  28. <template v-if="fileSize">
  29. 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
  30. </template>
  31. <template v-if="fileType">
  32. 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
  33. </template>
  34. 的文件
  35. </div>
  36. </el-upload>
  37. <!-- 文件列表 -->
  38. <transition-group
  39. class="upload-file-list el-upload-list el-upload-list--text"
  40. name="el-fade-in-linear"
  41. tag="ul"
  42. >
  43. <li
  44. :key="file.url"
  45. class="el-upload-list__item ele-upload-list__item-content"
  46. v-for="(file, index) in fileList"
  47. >
  48. <el-link
  49. :href="`${baseUrl}?id=${file.id}`"
  50. :underline="false"
  51. target="_blank"
  52. >
  53. <!-- <span class="el-icon-document"> {{ getFileName(file.name) }} </span> -->
  54. <span class="el-icon-document"> {{ file.name }} </span>
  55. </el-link>
  56. <div class="ele-upload-list__item-content-action">
  57. <el-link :underline="false" @click="handleDelete(index)" type="danger"
  58. >删除</el-link
  59. >
  60. </div>
  61. </li>
  62. </transition-group>
  63. </div>
  64. </template>
  65. <script>
  66. import { getToken } from "@/utils/auth";
  67. export default {
  68. name: "FileUpload",
  69. props: {
  70. // 值
  71. value: [String, Object, Array],
  72. // 数量限制
  73. limit: {
  74. type: Number,
  75. default: 5,
  76. },
  77. // 大小限制(MB)
  78. fileSize: {
  79. type: Number,
  80. default: 5,
  81. },
  82. // 文件类型, 例如['png', 'jpg', 'jpeg']
  83. fileType: {
  84. type: Array,
  85. default: () => ["doc", "xls", "ppt", "txt", "pdf"],
  86. },
  87. // 是否显示提示
  88. isShowTip: {
  89. type: Boolean,
  90. default: true,
  91. },
  92. },
  93. data() {
  94. return {
  95. number: 0,
  96. separator: ";",
  97. uploadList: [],
  98. baseUrl: "https://sy.derom.com/document-center/fastdfs/download",
  99. uploadFileUrl:
  100. process.env.NODE_ENV == "development"
  101. ? "/drp-file/document-center/fastdfs/upload"
  102. : "/document-center/fastdfs/upload",
  103. headers: {
  104. Authorization: "Bearer " + getToken(),
  105. },
  106. fileList: [],
  107. };
  108. },
  109. watch: {
  110. value: {
  111. handler(val) {
  112. if (val) {
  113. let temp = 1;
  114. // 首先将值转为数组
  115. const list = Array.isArray(val)
  116. ? val
  117. : this.value.split(this.separator);
  118. this.fileList = list.map((item) => {
  119. item = JSON.parse(item);
  120. return {
  121. ...item,
  122. uid: item.uid || new Date().getTime() + temp++,
  123. };
  124. });
  125. } else {
  126. this.fileList = [];
  127. return [];
  128. }
  129. },
  130. deep: true,
  131. immediate: true,
  132. },
  133. },
  134. computed: {
  135. // 是否显示提示
  136. showTip() {
  137. return this.isShowTip && (this.fileType || this.fileSize);
  138. },
  139. },
  140. methods: {
  141. // 上传前校检格式和大小
  142. handleBeforeUpload(file) {
  143. // 校检文件类型
  144. if (this.fileType) {
  145. const fileName = file.name.split(".");
  146. const fileExt = fileName[fileName.length - 1];
  147. const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
  148. if (!isTypeOk) {
  149. this.$modal.msgError(
  150. `文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`
  151. );
  152. return false;
  153. }
  154. }
  155. // 校检文件大小
  156. if (this.fileSize) {
  157. const isLt = file.size / 1024 / 1024 < this.fileSize;
  158. if (!isLt) {
  159. this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`);
  160. return false;
  161. }
  162. }
  163. this.$modal.loading("正在上传文件,请稍候...");
  164. this.number++;
  165. return true;
  166. },
  167. // 文件个数超出
  168. handleExceed() {
  169. this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
  170. },
  171. // 上传失败
  172. handleUploadError(err) {
  173. this.$modal.msgError("上传文件失败,请重试");
  174. this.$modal.closeLoading();
  175. },
  176. // 上传成功回调
  177. handleUploadSuccess(res, file) {
  178. if (res.code * 1 === 200) {
  179. this.uploadList.push({
  180. id: res.id,
  181. url: res.filepath,
  182. name: res.filename,
  183. });
  184. this.uploadedSuccessfully();
  185. } else {
  186. this.number--;
  187. this.$modal.closeLoading();
  188. this.$modal.msgError(res.msg);
  189. this.$refs.fileUpload.handleRemove(file);
  190. this.uploadedSuccessfully();
  191. }
  192. },
  193. // 删除文件
  194. handleDelete(index) {
  195. this.fileList.splice(index, 1);
  196. this.$emit("input", this.listToString(this.fileList, this.separator));
  197. },
  198. // 上传结束处理
  199. uploadedSuccessfully() {
  200. if (this.number > 0 && this.uploadList.length === this.number) {
  201. this.fileList = this.fileList.concat(this.uploadList);
  202. this.uploadList = [];
  203. this.number = 0;
  204. this.$emit("input", this.listToString(this.fileList, this.separator));
  205. this.$modal.closeLoading();
  206. }
  207. },
  208. // 获取文件名称
  209. getFileName(name) {
  210. if (name.lastIndexOf("/") > -1) {
  211. return name.slice(name.lastIndexOf("/") + 1);
  212. } else {
  213. return "";
  214. }
  215. },
  216. // 对象转成指定字符串分隔
  217. listToString(list, separator) {
  218. list = list.map((file) =>
  219. JSON.stringify({
  220. id: file.id,
  221. url: file.url,
  222. name: file.name,
  223. })
  224. );
  225. let strs = "";
  226. separator = separator || ",";
  227. for (let i in list) {
  228. strs += list[i] + separator;
  229. }
  230. return strs != "" ? strs.substr(0, strs.length - 1) : "";
  231. },
  232. },
  233. };
  234. </script>
  235. <style lang="scss">
  236. .el-form-item.is-error .el-upload-dragger {
  237. border: 1px dashed #ff4949;
  238. }
  239. </style>
  240. <style scoped lang="scss">
  241. .upload-file-uploader {
  242. margin-bottom: 5px;
  243. }
  244. .upload-file-list .el-upload-list__item {
  245. border: 1px solid #e4e7ed;
  246. line-height: 2;
  247. margin-bottom: 10px;
  248. position: relative;
  249. }
  250. .upload-file-list .ele-upload-list__item-content {
  251. display: flex;
  252. justify-content: space-between;
  253. align-items: center;
  254. color: inherit;
  255. }
  256. .ele-upload-list__item-content-action .el-link {
  257. margin-right: 10px;
  258. }
  259. </style>