多媒体信息发布平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

352 lines
11 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. <template>
  2. <div class="components_upload">
  3. <!-- <div v-if="isTheme">
  4. <el-button class="cont_upload_btn" round type="primary">选择文件</el-button>
  5. <input id="upFile" ref="inputfile" type="file" name="upFile" @change="changeFile($event)" />
  6. </div> -->
  7. <el-button class="cont_upload_btn" round type="primary">{{ isTheme ? '选择文件' : '上传' }}</el-button>
  8. <input id="upFile" type="file" name="upFile" @change="changeFile($event)" />
  9. <input v-if="isTheme" type="button" name="开始上传" value="开始上传" class="start_upload" @click="uploadFile()" />
  10. <!-- 上传列表layer -->
  11. <div v-if="!isTheme" class="upload_layer">
  12. <el-dialog
  13. title="上传列表"
  14. :close-on-click-modal="false"
  15. :show-close="false"
  16. :visible.sync="uploadListVisible"
  17. height="384px"
  18. >
  19. <el-table :data="fileData" :header-cell-style="{ color: '#333' }">
  20. <el-table-column align="center" prop="fileNames" label="文件名" />
  21. <el-table-column align="center" prop="formatType" label="类型" />
  22. <el-table-column align="center" prop="fileSize" label="大小" />
  23. <el-table-column align="center" prop="filePercentTxt" label="状态">
  24. <template slot-scope="scope">
  25. <div class="loadingModal" :style="{ 'height': '100%' }">
  26. <el-progress
  27. v-if="scope.row.filePercent != 0 && scope.row.filePercent != 100"
  28. :stroke-width="6"
  29. :percentage="scope.row.filePercent"
  30. />
  31. <span v-else>{{ scope.row.filePercentTxt }}</span>
  32. </div>
  33. </template>
  34. </el-table-column>
  35. <el-table-column align="center" prop="handle" label="操作">
  36. <template slot-scope="scope">
  37. <!-- <el-button
  38. type="primary"
  39. round
  40. class="on_off_btn"
  41. style="width: 50px; display: inline-block;"
  42. @click="controlUpload(scope.$index)"
  43. >{{ uploadStatus ?'暂停':'继续' }}</el-button> -->
  44. <el-button
  45. type="info"
  46. round
  47. style="width: 50px; display: inline-block;"
  48. class="upload_delt"
  49. @click="deltUpload(scope.$index)"
  50. >删除</el-button>
  51. </template>
  52. </el-table-column>
  53. </el-table>
  54. <div class="upload_list_right">
  55. <div class="upload_list_btn">
  56. <el-button>点击上传</el-button>
  57. <input id="upLoadFile" ref="inputfile" type="file" name="upFile" @change="changeFile($event)" />
  58. </div>
  59. <div class="upload_return" @click="uploadListVisible=false">返回</div>
  60. </div>
  61. </el-dialog>
  62. </div>
  63. </div>
  64. </template>
  65. <script>
  66. import * as qiniu from 'qiniu-js'
  67. import { getQiniuToken, FectchUploadTokenAndOps } from '@/api/upload/upload'
  68. let observable
  69. export default {
  70. name: 'Qiniu',
  71. props: {
  72. isTheme: {
  73. type: Boolean,
  74. required: true
  75. }
  76. },
  77. data() {
  78. return {
  79. file: null,
  80. token: '',
  81. baseurl: 'qiniu.aiyxlib.com',
  82. fileData: [],
  83. fileNames: '',
  84. formatType: '',
  85. postfix: '',
  86. fileSize: '',
  87. duration: 0,
  88. uploadListVisible: false,
  89. subscription: '',
  90. uploadFileUrl: null,
  91. filePercent: 0,
  92. uploadStatus: false,
  93. isActiveType: null
  94. }
  95. },
  96. mounted() {
  97. this.getQiniuToken()
  98. localStorage.removeItem('compareName')
  99. },
  100. methods: {
  101. changeFile(e) {
  102. // 获取文件
  103. this.file = e.target.files[0]
  104. this.$emit('getName', this.file.name)
  105. this.formatType = this.file.type.substring(0, this.file.type.indexOf('/'))
  106. if (this.isActiveType == 0) {
  107. if (this.formatType != 'image') {
  108. this.$message.error('请上传图片文件!')
  109. return
  110. }
  111. } else if (this.isActiveType == 1) {
  112. if (this.formatType != 'video') {
  113. this.$message.error('请上传视频文件!')
  114. return
  115. }
  116. } else if (this.isActiveType == 2) {
  117. if (this.formatType != 'audio') {
  118. this.$message.error('请上传音频文件!')
  119. return
  120. }
  121. }
  122. this.fileNames = this.file.name
  123. this.postfix = this.fileNames.substring(
  124. this.fileNames.lastIndexOf('.') + 1,
  125. this.fileNames.length
  126. )
  127. this.fileSize = this.file.size
  128. if (this.formatType === 'image') {
  129. const isJPG = this.file.type === 'image/jpeg' || this.file.type === 'image/png' || this.file.type === 'image/bmp' || this.file.type === 'image/gif'
  130. const isLt2M = this.file.size / 1024 / 1024 < 4
  131. if (!isJPG) {
  132. this.$message.error('图片只支持bmp、jpg、png、gif格式的文件')
  133. }
  134. if (!isLt2M) {
  135. this.$message.error('图片大小不能超过 4MB !')
  136. }
  137. }
  138. const isRepeat = this.fileData.map(item => item.key).indexOf(this.fileNames)
  139. if (isRepeat == -1) {
  140. this.fileData.push({
  141. fileNames: this.fileNames,
  142. formatType: this.formatType,
  143. fileSize: this.fileSize,
  144. filePercent: 0,
  145. filePercentTxt: '上传中',
  146. key: this.fileNames,
  147. uploadStatus: false
  148. })
  149. if (!this.isTheme) {
  150. setTimeout(() => {
  151. this.uploadFile()
  152. }, 1000)
  153. }
  154. } else {
  155. if (!this.isTheme) {
  156. this.$message({
  157. message: '该素材上传列表内已存在~',
  158. type: 'info'
  159. })
  160. }
  161. }
  162. // this.getOpsToken()
  163. this.uploadListVisible = true
  164. },
  165. getQiniuToken() {
  166. getQiniuToken().then(res => {
  167. this.token = res.data
  168. })
  169. },
  170. getOpsToken() {
  171. const name = Date.parse(new Date()) + '.mp4'
  172. const name1 = Date.parse(new Date())
  173. const param = {
  174. tFileName: name1,
  175. tExtName: this.postfix
  176. }
  177. FectchUploadTokenAndOps(param).then(res => {
  178. this.token = res.data
  179. const _this = this
  180. const putExtra = {
  181. fname: name1,
  182. params: {},
  183. mimeType: null
  184. }
  185. const config = {
  186. useCdnDomain: true,
  187. region: qiniu.region.z0,
  188. concurrentRequestLimit: 3,
  189. checkByMD5: true,
  190. retryCount: 3
  191. }
  192. const token = this.token
  193. observable = qiniu.upload(
  194. this.file,
  195. name,
  196. token,
  197. putExtra,
  198. config
  199. )
  200. _this.percentage = 10
  201. })
  202. },
  203. getVideoDuration(fileUrl) {
  204. const _this = this
  205. const audioElement = new Audio(fileUrl)
  206. audioElement.addEventListener('loadedmetadata', function() {
  207. _this.duration = parseInt(audioElement.duration) // 得到时长为秒,小数,182.36
  208. // self.ruleForm.videoDuration = parseInt(result) // 转为int值
  209. })
  210. },
  211. uploadFile() {
  212. // 当前VUE中的this 是指向实例,相当于父级,指向指不到子级中。所需需要一个变量 _this 存储this得指向。
  213. const _this = this
  214. _this.filePercent = 0
  215. _this.uploadStatus = false
  216. let compareChunks = []
  217. var finishedAttr = []
  218. // 获取身份的token
  219. const token = _this.token
  220. // 上传时的配置
  221. var config = {
  222. useCdnDomain: true
  223. }
  224. // 设置文件的配置
  225. var putExtra = {
  226. fname: '',
  227. params: {},
  228. mimeType: null
  229. }
  230. // 实例化七牛云的上传实例
  231. observable = qiniu.upload(_this.file, _this.file.name, token, putExtra, { resumingByFileSize: 4 * 1024 * 1024 }, config)
  232. // 设置实例的监听对象
  233. localStorage.setItem('currentFile', _this.file.name)
  234. // 接收上传进度信息
  235. var next = function(res) {
  236. const currentFile = localStorage.getItem('currentFile')
  237. const index = _this.fileData.map((item) => item.key).indexOf(currentFile)
  238. var chunks = res.chunks || []
  239. var total = res.total
  240. // 这里对每个chunk更新进度,并记录已经更新好的避免重复更新,同时对未开始更新的跳过
  241. for (var i = 0; i < chunks.length; i++) {
  242. if (chunks[i].percent === 0 || finishedAttr[i]) {
  243. continue
  244. }
  245. if (compareChunks[i].percent === chunks[i].percent) {
  246. continue
  247. }
  248. if (chunks[i].percent === 100) {
  249. finishedAttr[i] = true
  250. }
  251. }
  252. compareChunks = chunks
  253. _this.filePercent = parseInt(total.percent)
  254. _this.$nextTick(function() {
  255. _this.fileData[index].filePercent = _this.filePercent
  256. })
  257. }
  258. // 接收上传错误信息
  259. var error = function(err) {
  260. console.log(err)
  261. }
  262. // 接收上传完成后的信息
  263. var complete = function(res) {
  264. const index = _this.fileData.map((item) => item.key).indexOf(res.key)
  265. _this.uploadFileUrl = 'http://' + _this.baseurl + '/' + res.key
  266. // 上传完成后调用保存素材方法
  267. _this.getVideoDuration(_this.uploadFileUrl)
  268. _this.$nextTick(function() {
  269. _this.fileData[index].filePercentTxt = '上传成功'
  270. _this.fileData[index].filePercent = 100
  271. })
  272. setTimeout(() => {
  273. _this.$emit('saveMaterial')
  274. }, 200)
  275. document.getElementById('upFile').value = ''
  276. document.getElementById('upLoadFile').value = ''
  277. localStorage.removeItem('currentFile')
  278. // localStorage.removeItem('currentCompareName')
  279. }
  280. var subObject = {
  281. next: next,
  282. error: error,
  283. complete: complete
  284. }
  285. _this.controlUpload = function() {
  286. _this.uploadStatus = !_this.uploadStatus
  287. if (_this.uploadStatus) {
  288. _this.subscription = observable.subscribe(subObject) // 调用sdk上传接口获得相应的observable,控制上传和暂停
  289. } else {
  290. _this.subscription.unsubscribe()
  291. }
  292. }
  293. _this.controlUpload()
  294. // 上传开始
  295. // subscription = observable.subscribe(observer)
  296. },
  297. deltUpload(index) {
  298. this.subscription.unsubscribe()
  299. this.fileData.splice(index, 1)
  300. }
  301. }
  302. }
  303. </script>
  304. <style lang="scss" scoped>
  305. .components_upload{
  306. position: relative;
  307. }
  308. #upFile,
  309. #upLoadFile{
  310. display: block;
  311. width: 114px;
  312. height: 34px;
  313. padding: 0;
  314. font-size: 14px;
  315. border: none;
  316. opacity: 0;
  317. }
  318. .cont_upload_btn{
  319. position: absolute;
  320. left: 0;
  321. top: 0;
  322. }
  323. .upload_list_btn{
  324. position: relative;
  325. ::v-deep .el-button {
  326. position: absolute;
  327. left: 0;
  328. top: 0;
  329. width: auto;
  330. height: auto;
  331. margin: 0;
  332. padding: 0;
  333. font-size: 14px;
  334. font-weight: bold;
  335. color: #3a8aeb;
  336. }
  337. #upLoadFile{
  338. width: 60px;
  339. }
  340. }
  341. ::v-deep .el-progress-bar__outer{
  342. background-color: transparent;
  343. }
  344. ::v-deep .el-progress-bar__inner {
  345. background-image: linear-gradient(to right, #40cbfe, #3a8aeb)
  346. }
  347. </style>