uploadFile.vue 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  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/*' : '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格式,大小在'+(size/1024)+'m之内' }}
  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. var data = {
  160. uid: 1,
  161. name: '回显',
  162. status: 'done',
  163. url: n,
  164. }
  165. this.fileList.push(data)
  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(file)
  214. var image = new Image()
  215. var reader = new FileReader()
  216. var height = 0
  217. var width = 0
  218. reader.readAsDataURL(file)
  219. //文件读取结束时间
  220. reader.onload = function (e) {
  221. image.src = reader.result
  222. }
  223. var that = this
  224. //图片读取事件
  225. image.onload = function () {
  226. height = image.naturalHeight
  227. width = image.naturalWidth
  228. }
  229. if (image.complete) {
  230. height = image.naturalHeight
  231. width = image.naturalWidth
  232. }
  233. setTimeout(() => {
  234. if (height != 450 || width != 450) {
  235. that.$message.error('请上传450*450大小的图片')
  236. this.loadingElse = false
  237. return
  238. }
  239. // console.log(fileOvesize)
  240. if (fileOvesize && this.sizeCheck) {
  241. this.onOversize()
  242. this.loadingElse = false
  243. return
  244. } else {
  245. if (file.type.includes('jpg') || file.type.includes('png') || file.type.includes('jpeg')) {
  246. this.checkFile(file)
  247. .then((res) => {
  248. this.cosUpload(file)
  249. })
  250. .catch(() => {
  251. this.loadingElse = false
  252. })
  253. } else {
  254. this.$message.error('请上传正确格式')
  255. this.loadingElse = false
  256. }
  257. return new Promise(function (resolve, reject) {
  258. reject()
  259. })
  260. }
  261. }, 200)
  262. },
  263. clearAll() {
  264. this.fileList = []
  265. },
  266. cosUpload(file) {
  267. var that = this
  268. let date = new Date()
  269. let y = date.getFullYear()
  270. let MM = date.getMonth() + 1
  271. MM = MM < 10 ? '0' + MM : MM
  272. let d = date.getDate()
  273. d = d < 10 ? '0' + d : d
  274. var timeElse = new Date().getTime()
  275. var arr = file.name.split('.')
  276. var str = ''
  277. for (let i = 0; i < arr.length; i++) {
  278. if (i == arr.length - 1) {
  279. } else {
  280. if (i == arr.length - 2) {
  281. str += arr[i]
  282. } else {
  283. str += arr[i] + '.'
  284. }
  285. }
  286. }
  287. // console.log(str + '-' + timeElse + '.' + arr[arr.length - 1])
  288. cos.putObject(
  289. {
  290. Bucket: 'media-1301855440',
  291. /* 必须 */
  292. Region: 'ap-chongqing',
  293. /* 存储桶所在地域,必须字段 */
  294. Key: that.uploadType + '/' + y + '-' + MM + '-' + d + '/' + str + '-' + timeElse + '.' + arr[arr.length - 1],
  295. /* 必须 */
  296. StorageClass: 'STANDARD',
  297. Body: file, // 上传文件对象
  298. onProgress: function (progressData) {
  299. //进度条方法
  300. that.percent = progressData.percent * 100
  301. },
  302. onTaskReady: function (tid) {
  303. // console.log('onTaskReady', tid);
  304. },
  305. onTaskStart: function (info) {
  306. //开始上传
  307. // console.log('onTaskStart', info);
  308. },
  309. },
  310. function (err, data) {
  311. if (err) {
  312. that.loadingElse = false
  313. that.$message.error('上传失败!!!' + err)
  314. return
  315. }
  316. // alert('成功')
  317. that.loadingElse = false
  318. if (that.fileList.length < that.fileCount) {
  319. that.fileList.push({
  320. uid: file.name,
  321. name: file.name,
  322. status: 'done',
  323. url: '//' + data.Location,
  324. })
  325. // that.$emit('overUpload', that.fileList.map(item => {
  326. // return item.url
  327. // }))
  328. that.$emit('overUpload', that.fileList)
  329. if (that.multiple) {
  330. that.$emit(
  331. 'update:value',
  332. that.fileList.map((item) => {
  333. return item.url
  334. })
  335. )
  336. } else {
  337. that.$emit(
  338. 'update:value',
  339. that.fileList.map((item) => {
  340. return item.url
  341. })[0]
  342. )
  343. }
  344. } else {
  345. that.$message.error('上传已达上限' + that.fileCount + '张')
  346. }
  347. }
  348. )
  349. },
  350. },
  351. }
  352. </script>
  353. <style scoped>
  354. @import '~@assets/less/common.less';
  355. </style>