index.vue 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. <template>
  2. <div class="upload-file">
  3. <el-upload
  4. multiple
  5. :action="uploadFileUrl"
  6. :before-upload="handleBeforeUpload"
  7. :file-list="fileList"
  8. :data="data"
  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. v-if="!disabled"
  18. >
  19. <!-- 上传按钮 -->
  20. <el-tooltip class="item" effect="dark" :content="'大小不超过' + fileSize +'MB,格式为' + slgegse " placement="top">
  21. <el-button size="mini" type="primary">上传</el-button>
  22. </el-tooltip>
  23. <!-- 上传提示 -->
  24. <!-- <div class="el-upload__tip" slot="tip" v-if="isShowTip">
  25. <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
  26. <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
  27. 的文件
  28. </div> -->
  29. </el-upload>
  30. <!-- 文件列表 -->
  31. <ul ref="uploadFileList" class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
  32. <template v-for="(file, index) in fileList">
  33. <li :key="file.fjUrl" v-if="file.type==data.type&&file.bigType==data.bigType" class="el-upload-list__item ele-upload-list__item-content" >
  34. <el-link :href="`${baseUrl}${file.fjUrl}`" :underline="false" target="_blank">
  35. <span class="el-icon-document"> {{ getFileName(file.fjName) }} </span>
  36. </el-link>
  37. <div class="ele-upload-list__item-content-action">
  38. <el-link :underline="false" @click="handleDelete(index)" type="danger" v-if="!disabled">删除</el-link>
  39. </div>
  40. </li>
  41. </template>
  42. </ul>
  43. </div>
  44. </template>
  45. <script>
  46. import { getToken } from "@/utils/auth"
  47. import Sortable from 'sortablejs'
  48. export default {
  49. name: "FileUpload",
  50. props: {
  51. // 值
  52. value: [String, Object, Array],
  53. // 上传接口地址
  54. action: {
  55. type: String,
  56. default: "/common/uploadNew"
  57. },
  58. // 上传携带的参数
  59. data: {
  60. type: Object
  61. },
  62. datam:{
  63. type: Object
  64. },
  65. // 数量限制
  66. limit: {
  67. type: Number,
  68. default: 5
  69. },
  70. // 大小限制(MB)
  71. fileSize: {
  72. type: Number,
  73. default: 5
  74. },
  75. // 文件类型, 例如['png', 'jpg', 'jpeg']
  76. fileType: {
  77. type: Array,
  78. default: () => ["doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "pdf","png","jpg"]
  79. },
  80. // 是否显示提示
  81. isShowTip: {
  82. type: Boolean,
  83. default: true
  84. },
  85. // 禁用组件(仅查看文件)
  86. disabled: {
  87. type: Boolean,
  88. default: false
  89. },
  90. // 拖动排序
  91. drag: {
  92. type: Boolean,
  93. default: true
  94. },
  95. },
  96. data() {
  97. return {
  98. number: 0,
  99. uploadList: [],
  100. baseUrl: process.env.VUE_APP_BASE_API,
  101. uploadFileUrl: process.env.VUE_APP_BASE_API + this.action, // 上传文件服务器地址
  102. headers: {
  103. Authorization: "Bearer " + getToken(),
  104. },
  105. fileList: [],
  106. slgegse:''
  107. }
  108. },
  109. watch:{
  110. },
  111. created() {
  112. this.slgegse = this.fileType.join(',')
  113. },
  114. mounted() {
  115. if (this.drag && !this.disabled) {
  116. this.$nextTick(() => {
  117. const element = this.$refs.uploadFileList?.$el || this.$refs.uploadFileList
  118. Sortable.create(element, {
  119. ghostClass: 'file-upload-darg',
  120. onEnd: (evt) => {
  121. const movedItem = this.fileList.splice(evt.oldIndex, 1)[0]
  122. this.fileList.splice(evt.newIndex, 0, movedItem)
  123. // this.$emit("input", this.listToString(this.fileList))
  124. this.$emit("input", this.fileList)
  125. }
  126. })
  127. })
  128. }
  129. },
  130. watch: {
  131. value: {
  132. handler(val) {
  133. if (val) {
  134. let temp = 1
  135. // 首先将值转为数组
  136. const list = Array.isArray(val) ? val : this.value.split(',')
  137. // 然后将数组转为对象数组
  138. this.fileList = list.map(item => {
  139. if (typeof item === "string") {
  140. item = { name: item, url: item }
  141. }
  142. item.uid = item.uid || new Date().getTime() + temp++
  143. return item
  144. })
  145. } else {
  146. this.fileList = []
  147. return []
  148. }
  149. },
  150. deep: true,
  151. immediate: true
  152. }
  153. },
  154. computed: {
  155. // 是否显示提示
  156. showTip() {
  157. return this.isShowTip && (this.fileType || this.fileSize)
  158. },
  159. },
  160. methods: {
  161. // 上传前校检格式和大小
  162. handleBeforeUpload(file) {
  163. // 校检文件类型
  164. if (this.fileType) {
  165. const fileName = file.name.split('.')
  166. const fileExt = fileName[fileName.length - 1]
  167. const isTypeOk = this.fileType.indexOf(fileExt) >= 0
  168. if (!isTypeOk) {
  169. this.$modal.msgError(`文件格式不正确,请上传${this.fileType.join("/")}格式文件!`)
  170. return false
  171. }
  172. }
  173. // 校检文件名是否包含特殊字符
  174. if (file.name.includes(',')) {
  175. this.$modal.msgError('文件名不正确,不能包含英文逗号!')
  176. return false
  177. }
  178. // 校检文件大小
  179. if (this.fileSize) {
  180. const isLt = file.size / 1024 / 1024 < this.fileSize
  181. if (!isLt) {
  182. this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`)
  183. return false
  184. }
  185. }
  186. this.data.fileName=file.name
  187. this.$modal.loading("正在上传文件,请稍候...")
  188. this.number++
  189. return true
  190. },
  191. // 文件个数超出
  192. handleExceed() {
  193. this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`)
  194. },
  195. // 上传失败
  196. handleUploadError(err) {
  197. this.$modal.msgError("上传文件失败,请重试")
  198. this.$modal.closeLoading()
  199. },
  200. // 上传成功回调
  201. handleUploadSuccess(res, file) {
  202. if (res.code === 200) {
  203. var obj={ fjName: res.newFileName, fjUrl: res.fileName,bigType:this.data.bigType,type:this.data.type,xmbh:this.data.xmbh }
  204. this.uploadList.push(obj)
  205. this.uploadedSuccessfully()
  206. } else {
  207. this.number--
  208. this.$modal.closeLoading()
  209. this.$modal.msgError(res.msg)
  210. this.$refs.fileUpload.handleRemove(file)
  211. this.uploadedSuccessfully()
  212. }
  213. },
  214. // 删除文件
  215. handleDelete(index) {
  216. this.fileList.splice(index, 1)
  217. // this.$emit("input", this.listToString(this.fileList))
  218. this.$emit("input", this.fileList)
  219. },
  220. // 上传结束处理
  221. uploadedSuccessfully() {
  222. if (this.number > 0 && this.uploadList.length === this.number) {
  223. this.fileList = this.fileList.concat(this.uploadList)
  224. this.uploadList = []
  225. this.number = 0
  226. // this.$emit("input", this.listToString(this.fileList))
  227. this.$emit("input", this.fileList)
  228. this.$modal.closeLoading()
  229. }
  230. },
  231. // 获取文件名称
  232. getFileName(name) {
  233. // 如果是url那么取最后的名字 如果不是直接返回
  234. if (name.lastIndexOf("/") > -1) {
  235. return name.slice(name.lastIndexOf("/") + 1)
  236. } else {
  237. return name
  238. }
  239. },
  240. // 对象转成指定字符串分隔
  241. listToString(list, separator) {
  242. let strs = ""
  243. separator = separator || ","
  244. for (let i in list) {
  245. strs += list[i].url + separator
  246. }
  247. return strs != '' ? strs.substr(0, strs.length - 1) : ''
  248. }
  249. }
  250. }
  251. </script>
  252. <style scoped lang="scss">
  253. .file-upload-darg {
  254. opacity: 0.5;
  255. background: #c8ebfb;
  256. }
  257. .upload-file-uploader {
  258. margin-bottom: 5px;
  259. }
  260. .upload-file-list .el-upload-list__item {
  261. border: 1px solid #e4e7ed;
  262. line-height: 2;
  263. margin-bottom: 10px;
  264. position: relative;
  265. }
  266. .upload-file-list .ele-upload-list__item-content {
  267. display: flex;
  268. justify-content: space-between;
  269. align-items: center;
  270. color: inherit;
  271. }
  272. .ele-upload-list__item-content-action .el-link {
  273. margin-right: 10px;
  274. }
  275. </style>