uploadFilePopilar.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. <style></style>
  2. <style lang="scss" scoped></style>
  3. <template>
  4. <div class="upload-file">
  5. <a-upload
  6. name="file"
  7. :multiple="multiple"
  8. list-type="picture-card"
  9. class="avatar-uploader"
  10. action="https://media-1301855440.cos.ap-chongqing.myqcloud.com/"
  11. :before-upload="beforeUpload"
  12. @change="handleChange"
  13. :accept="uploadType + '/' + (uploadType == 'image' ? 'jpeg,image/jpg' : 'mp4')"
  14. :file-list="fileList"
  15. :remove="removeFile"
  16. @preview="handlePreview"
  17. :disabled="loadingElse || disabled"
  18. >
  19. <div v-if="fileList.length < fileCount || fileList.length < 1">
  20. <a-progress v-if="loadingElse" :percent="percent" :show-info="false" />
  21. <div class="ant-upload-text">点击上传</div>
  22. </div>
  23. </a-upload>
  24. <div style="color: red" v-if="sizeCheck">
  25. {{ uploadType == 'image' ? '请上传jpg格式的图片,并且大小在2m之内' : '请上传mp4格式,大小在100m之内' }}
  26. </div>
  27. <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
  28. <img alt="example" style="width: 100%" :src="previewImage" v-if="uploadType == 'image'" />
  29. <video :src="previewImage" v-else style="width: 100%" controls="controls">
  30. 您的浏览器不支持 video 标签。
  31. </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(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:
  263. '/external-videos/' +
  264. y +
  265. '' +
  266. MM +
  267. '' +
  268. d +
  269. '/' +
  270. str +
  271. '-' +
  272. timeElse +
  273. '.' +
  274. arr[arr.length - 1],
  275. /* 必须 */
  276. StorageClass: 'STANDARD',
  277. Body: file, // 上传文件对象
  278. onProgress: function (progressData) {
  279. //进度条方法
  280. that.percent = progressData.percent * 100
  281. },
  282. onTaskReady: function (tid) {
  283. // console.log('onTaskReady', tid);
  284. },
  285. onTaskStart: function (info) {
  286. //开始上传
  287. // console.log('onTaskStart', info);
  288. },
  289. },
  290. function (err, data) {
  291. if (err) {
  292. that.loadingElse = false
  293. that.$message.error('上传失败!!!' + err)
  294. return
  295. }
  296. // alert('成功')
  297. that.loadingElse = false
  298. if (that.fileList.length < that.fileCount) {
  299. that.fileList.push({
  300. uid: file.name,
  301. name: file.name,
  302. status: 'done',
  303. url: '//' + data.Location,
  304. })
  305. // that.$emit('overUpload', that.fileList.map(item => {
  306. // return item.url
  307. // }))
  308. that.$emit('overUpload', that.fileList)
  309. if (that.multiple) {
  310. let urlList = that.fileList.map((item) => {
  311. return item.url
  312. })
  313. that.$emit('update:value', urlList)
  314. } else {
  315. that.$emit(
  316. 'update:value',
  317. that.fileList.map((item) => {
  318. return item.url
  319. })[0]
  320. )
  321. }
  322. } else {
  323. that.$message.error('上传已达上限' + that.fileCount + '张')
  324. }
  325. }
  326. )
  327. },
  328. },
  329. }
  330. </script>
  331. <style scoped>
  332. @import '~@assets/less/common.less';
  333. </style>