index.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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. ? "/document-center/fastdfs/upload"
  102. : "/drp-file/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. // 然后将数组转为对象数组
  119. // this.fileList = list.map((item) => {
  120. // if (typeof item === "string") {
  121. // item = { name: item, url: item };
  122. // }
  123. // item.uid = item.uid || new Date().getTime() + temp++;
  124. // return item;
  125. // });
  126. this.fileList = list.map((item) => {
  127. item = JSON.parse(item);
  128. console.log({
  129. ...item,
  130. uid: item.uid || new Date().getTime() + temp++,
  131. });
  132. return {
  133. ...item,
  134. uid: item.uid || new Date().getTime() + temp++,
  135. };
  136. });
  137. } else {
  138. this.fileList = [];
  139. return [];
  140. }
  141. },
  142. deep: true,
  143. immediate: true,
  144. },
  145. },
  146. computed: {
  147. // 是否显示提示
  148. showTip() {
  149. return this.isShowTip && (this.fileType || this.fileSize);
  150. },
  151. },
  152. methods: {
  153. // 上传前校检格式和大小
  154. handleBeforeUpload(file) {
  155. // 校检文件类型
  156. if (this.fileType) {
  157. const fileName = file.name.split(".");
  158. const fileExt = fileName[fileName.length - 1];
  159. const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
  160. if (!isTypeOk) {
  161. this.$modal.msgError(
  162. `文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`
  163. );
  164. return false;
  165. }
  166. }
  167. // 校检文件大小
  168. if (this.fileSize) {
  169. const isLt = file.size / 1024 / 1024 < this.fileSize;
  170. if (!isLt) {
  171. this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`);
  172. return false;
  173. }
  174. }
  175. this.$modal.loading("正在上传文件,请稍候...");
  176. this.number++;
  177. return true;
  178. },
  179. // 文件个数超出
  180. handleExceed() {
  181. this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
  182. },
  183. // 上传失败
  184. handleUploadError(err) {
  185. this.$modal.msgError("上传文件失败,请重试");
  186. this.$modal.closeLoading();
  187. },
  188. // 上传成功回调
  189. handleUploadSuccess(res, file) {
  190. if (res.code * 1 === 200) {
  191. this.uploadList.push({
  192. id: res.id,
  193. url: res.filepath,
  194. name: res.filename,
  195. });
  196. this.uploadedSuccessfully();
  197. } else {
  198. this.number--;
  199. this.$modal.closeLoading();
  200. this.$modal.msgError(res.msg);
  201. this.$refs.fileUpload.handleRemove(file);
  202. this.uploadedSuccessfully();
  203. }
  204. },
  205. // 删除文件
  206. handleDelete(index) {
  207. this.fileList.splice(index, 1);
  208. this.$emit("input", this.listToString(this.fileList, this.separator));
  209. },
  210. // 上传结束处理
  211. uploadedSuccessfully() {
  212. if (this.number > 0 && this.uploadList.length === this.number) {
  213. this.fileList = this.fileList.concat(this.uploadList);
  214. this.uploadList = [];
  215. this.number = 0;
  216. this.$emit("input", this.listToString(this.fileList, this.separator));
  217. this.$modal.closeLoading();
  218. }
  219. },
  220. // 获取文件名称
  221. getFileName(name) {
  222. if (name.lastIndexOf("/") > -1) {
  223. return name.slice(name.lastIndexOf("/") + 1);
  224. } else {
  225. return "";
  226. }
  227. },
  228. // 对象转成指定字符串分隔
  229. listToString(list, separator) {
  230. list = list.map((file) =>
  231. JSON.stringify({
  232. id: file.id,
  233. url: file.url,
  234. name: file.name,
  235. })
  236. );
  237. let strs = "";
  238. separator = separator || ",";
  239. for (let i in list) {
  240. strs += list[i] + separator;
  241. }
  242. return strs != "" ? strs.substr(0, strs.length - 1) : "";
  243. },
  244. },
  245. };
  246. </script>
  247. <style scoped lang="scss">
  248. .upload-file-uploader {
  249. margin-bottom: 5px;
  250. }
  251. .upload-file-list .el-upload-list__item {
  252. border: 1px solid #e4e7ed;
  253. line-height: 2;
  254. margin-bottom: 10px;
  255. position: relative;
  256. }
  257. .upload-file-list .ele-upload-list__item-content {
  258. display: flex;
  259. justify-content: space-between;
  260. align-items: center;
  261. color: inherit;
  262. }
  263. .ele-upload-list__item-content-action .el-link {
  264. margin-right: 10px;
  265. }
  266. </style>