index.vue 6.5 KB

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