uploadFile.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. <style>
  2. </style>
  3. <style lang="scss" scoped>
  4. </style>
  5. <template>
  6. <div class="upload-file">
  7. <a-upload
  8. name="file"
  9. :multiple="multiple"
  10. list-type="picture-card"
  11. class="avatar-uploader"
  12. action="https://media-1301855440.cos.ap-chongqing.myqcloud.com/"
  13. :before-upload="beforeUpload"
  14. @change="handleChange"
  15. :accept="uploadType + '/' + (uploadType == 'image' ? 'jpeg,image/jpg' : 'mp4')"
  16. :file-list="fileList"
  17. :remove="removeFile"
  18. @preview="handlePreview"
  19. :disabled="loadingElse || disabled"
  20. >
  21. <div v-if="fileList.length < fileCount || fileList.length < 1">
  22. <a-progress v-if="loadingElse" :percent="percent" :show-info="false" />
  23. <div class="ant-upload-text">点击上传</div>
  24. </div>
  25. </a-upload>
  26. <div style="color: red" v-if="sizeCheck">
  27. {{ uploadType == 'image' ? '请上传jpg格式的图片,并且大小在2m之内' : '请上传mp4格式,大小在100m之内' }}
  28. </div>
  29. <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
  30. <img alt="example" style="width: 100%" :src="previewImage" v-if="uploadType == 'image'" />
  31. <video :src="previewImage" v-else style="width: 100%" controls="controls">您的浏览器不支持 video 标签。</video>
  32. </a-modal>
  33. </div>
  34. </template>
  35. <script>
  36. import { stopOtherVideo, closeAllVideoFun } from '@/utils/videoControl' // 停止除当前外的其他视频播放,及停止所有视频播放的方法
  37. import { mapGetters } from 'vuex'
  38. import moment from 'moment'
  39. import BMF from 'browser-md5-file'
  40. import qs from 'qs'
  41. var COS = require('cos-js-sdk-v5')
  42. var cos = new COS({
  43. SecretId: 'AKIDE6IpMi8fJQRCg1iuWzFajjRs43kbbets',
  44. SecretKey: 'tXzuwMfplTTK3c9GFUyETilasvQfePu9',
  45. })
  46. var i = 0
  47. const oneKB = 1024
  48. function getBase64(file) {
  49. return new Promise((resolve, reject) => {
  50. const reader = new FileReader()
  51. reader.readAsDataURL(file)
  52. reader.onload = () => resolve(reader.result)
  53. reader.onerror = (error) => reject(error)
  54. })
  55. }
  56. export default {
  57. name: 'upload-file',
  58. components: {},
  59. props: {
  60. uploadType: {
  61. //上传类型 值为 image/video,同时目录名称也是这样
  62. type: String,
  63. default() {
  64. return 'image'
  65. },
  66. },
  67. multiple: {
  68. // true 可以批量上传 false 不可以
  69. type: Boolean,
  70. default() {
  71. return true
  72. },
  73. },
  74. fileCount: {
  75. //最大上传数量
  76. type: Number,
  77. default() {
  78. return 10
  79. },
  80. },
  81. checkFile: {
  82. //返回promise方法,判读文件是否上传过,进行上传拦截
  83. type: Function,
  84. default() {
  85. return Promise.resolve()
  86. },
  87. },
  88. disabled: {
  89. type: Boolean,
  90. default() {
  91. return false
  92. },
  93. },
  94. value: {
  95. required: true,
  96. default() {
  97. return ''
  98. },
  99. },
  100. size: {
  101. type: Number,
  102. default() {
  103. if (this.sizeCheck) {
  104. if (this.uploadType == 'image') {
  105. return 2048
  106. } else {
  107. return 102400
  108. }
  109. }
  110. },
  111. },
  112. sizeCheck: {
  113. type: Boolean,
  114. default() {
  115. return true
  116. },
  117. },
  118. onOversize: {
  119. type: Function,
  120. default() {
  121. alert(`请选择${this.size}KB内的文件!`)
  122. },
  123. },
  124. },
  125. data() {
  126. return {
  127. fileList: [],
  128. loadingElse: false,
  129. imageUrl: '',
  130. percent: 0,
  131. previewVisible: false,
  132. previewImage: '',
  133. }
  134. },
  135. filters: {},
  136. computed: {},
  137. mounted() {},
  138. watch: {
  139. // fileListAll
  140. value: {
  141. immediate: true,
  142. handler(n, o) {
  143. this.$nextTick(() => {
  144. if (this.fileList && this.fileList.length == 0) {
  145. if (typeof n == 'object') {
  146. this.fileList = n.map((item, index) => {
  147. return {
  148. uid: index + 1,
  149. name: index + 1,
  150. status: 'done',
  151. url: item,
  152. }
  153. })
  154. } else {
  155. if (n == '') {
  156. this.fileList = []
  157. } else {
  158. this.fileList = [
  159. {
  160. uid: 1,
  161. name: 1,
  162. status: 'done',
  163. url: n,
  164. },
  165. ]
  166. }
  167. }
  168. } else {
  169. if (n.length == 0 || n == '') {
  170. this.clearAll()
  171. }
  172. }
  173. })
  174. },
  175. deep: true,
  176. },
  177. },
  178. methods: {
  179. handleCancel() {
  180. closeAllVideoFun()
  181. this.previewVisible = false
  182. },
  183. handleChange(info) {
  184. if (info.file.status === 'uploading') {
  185. this.loading = true
  186. return
  187. }
  188. if (info.file.status === 'done') {
  189. // Get this url from response in real world.
  190. getBase64(info.file.originFileObj, (imageUrl) => {
  191. this.imageUrl = imageUrl
  192. this.loading = false
  193. })
  194. }
  195. },
  196. removeFile(file) {
  197. // console.log(file)
  198. var index = this.fileList.findIndex((v) => v.uid === file.uid)
  199. this.fileList.splice(index, 1)
  200. this.$emit('removeUpload', file)
  201. },
  202. async handlePreview(file) {
  203. if (!file.url && !file.preview) {
  204. file.preview = await getBase64(file.originFileObj)
  205. }
  206. this.previewImage = file.url || file.preview
  207. this.previewVisible = true
  208. },
  209. beforeUpload(file) {
  210. this.percent = 0
  211. this.loadingElse = true
  212. const fileOvesize = file.size > this.size * oneKB
  213. // console.log(fileOvesize)
  214. if (fileOvesize && this.sizeCheck) {
  215. this.onOversize()
  216. this.loadingElse = false
  217. return
  218. } else {
  219. this.checkFile(file)
  220. .then((res) => {
  221. this.cosUpload(file)
  222. })
  223. .catch(() => {
  224. this.loadingElse = false
  225. })
  226. return new Promise(function (resolve, reject) {
  227. reject()
  228. })
  229. }
  230. },
  231. clearAll() {
  232. this.fileList = []
  233. },
  234. cosUpload(file) {
  235. var that = this
  236. let date = new Date()
  237. let y = date.getFullYear()
  238. let MM = date.getMonth() + 1
  239. MM = MM < 10 ? '0' + MM : MM
  240. let d = date.getDate()
  241. d = d < 10 ? '0' + d : d
  242. var timeElse = new Date().getTime()
  243. var arr = file.name.split('.')
  244. var str = ''
  245. for (let i = 0; i < arr.length; i++) {
  246. if (i == arr.length - 1) {
  247. } else {
  248. if (i == arr.length - 2) {
  249. str += arr[i]
  250. } else {
  251. str += arr[i] + '.'
  252. }
  253. }
  254. }
  255. // console.log(str + '-' + timeElse + '.' + arr[arr.length - 1])
  256. cos.putObject(
  257. {
  258. Bucket: 'media-1301855440',
  259. /* 必须 */
  260. Region: 'ap-chongqing',
  261. /* 存储桶所在地域,必须字段 */
  262. Key: that.uploadType + '/' + y + '-' + MM + '-' + d + '/' + str + '-' + timeElse + '.' + arr[arr.length - 1],
  263. /* 必须 */
  264. StorageClass: 'STANDARD',
  265. Body: file, // 上传文件对象
  266. onProgress: function (progressData) {
  267. //进度条方法
  268. that.percent = progressData.percent * 100
  269. },
  270. onTaskReady: function (tid) {
  271. // console.log('onTaskReady', tid);
  272. },
  273. onTaskStart: function (info) {
  274. //开始上传
  275. // console.log('onTaskStart', info);
  276. },
  277. },
  278. function (err, data) {
  279. if (err) {
  280. that.loadingElse = false
  281. that.$message.error('上传失败!!!' + err)
  282. return
  283. }
  284. // alert('成功')
  285. that.loadingElse = false
  286. if (that.fileList.length < that.fileCount) {
  287. that.fileList.push({
  288. uid: file.name,
  289. name: file.name,
  290. status: 'done',
  291. url: '//' + data.Location,
  292. })
  293. // that.$emit('overUpload', that.fileList.map(item => {
  294. // return item.url
  295. // }))
  296. that.$emit('overUpload', that.fileList)
  297. if (that.multiple) {
  298. that.$emit(
  299. 'update:value',
  300. that.fileList.map((item) => {
  301. return item.url
  302. })
  303. )
  304. } else {
  305. that.$emit(
  306. 'update:value',
  307. that.fileList.map((item) => {
  308. return item.url
  309. })[0]
  310. )
  311. }
  312. } else {
  313. that.$message.error('上传已达上限' + that.fileCount + '张')
  314. }
  315. }
  316. )
  317. },
  318. },
  319. }
  320. </script>
  321. <style scoped>
  322. @import '~@assets/less/common.less';
  323. </style>