liyangzhi 4 роки тому
батько
коміт
3d63479fd3

Різницю між файлами не показано, бо вона завелика
+ 7 - 0
components/videoUpload/lib/aliyun-upload-sdk/aliyun-upload-sdk-1.5.2.min.js


Різницю між файлами не показано, бо вона завелика
+ 20 - 0
components/videoUpload/lib/aliyun-upload-sdk/lib/aliyun-oss-sdk-6.13.0.min.js


Різницю між файлами не показано, бо вона завелика
+ 1 - 0
components/videoUpload/lib/aliyun-upload-sdk/lib/es6-promise.min.js


+ 80 - 0
components/videoUpload/src/App.vue

@@ -0,0 +1,80 @@
+<template>
+  <div class="uploader">
+    <div class="upload-type-switch">
+      <input type="radio" id="one" value="one" v-model="picked">
+      <label for="one" style="margin-right: 100px;">使用 UploadAuth 上传</label>
+      <input type="radio" id="two" value="two" v-model="picked">
+      <label for="two">使用 STSToken 上传</label>
+    </div>
+    <UploadAuth v-show="picked === 'one'" />
+    <STSToken v-show="picked === 'two'" />
+  </div>
+</template>
+<script>
+  import axios from 'axios'
+  import STSToken from './STSToken'
+  import UploadAuth from './UploadAuth'
+
+  export default {
+    components: {
+      STSToken,
+      UploadAuth
+    },
+    data () {
+      return {
+        picked: 'one'
+      }
+    }
+  }
+</script>
+<style>
+  .upload-type-switch {
+    text-align: center;
+  }
+  .container {
+    width: 1200px;
+    margin: 0 auto;
+  }
+  .input-control {
+    margin: 5px 0;
+  }
+  .input-control label {
+    font-size: 14px;
+    color: #333;
+    width: 30%;
+    text-align: right;
+    display: inline-block;
+    vertical-align: middle;
+    margin-right: 10px;
+  }
+  .input-control input {
+    width: 30%;
+    height: 30px;
+    padding: 0 5px;
+  }
+  .upload {
+    padding: 30px 50px;
+  }
+  .progress {
+    font-size: 14px;
+  }
+  .progress i {
+    font-style: normal;
+  }
+  .upload-type {
+    color: #666;
+    font-size: 12px;
+    padding: 10px 0;
+  }
+  .upload-type button {
+    margin: 0 10px 0 20px;
+  }
+  .status {
+    font-size: 14px;
+    margin-left: 30px;
+  }
+  .info {
+    font-size: 14px;
+    padding-left: 30px;
+  }
+</style>

+ 213 - 0
components/videoUpload/src/STSToken.vue

@@ -0,0 +1,213 @@
+<template>
+  <div class="container">
+    <div class="setting">
+      <div class="input-control">
+        <label for="timeout">请求过期时间(构造参数 timeout, 默认 60000):</label>
+        <input type="text" id="timeout" v-model="timeout" placeholder="输入过期时间, 单位毫秒">
+      </div>
+
+      <div class="input-control">
+        <label for="partSize">分片大小(构造参数 partSize, 默认 1048576):</label>
+        <input type="text" class="form-control" id="partSize" v-model="partSize" placeholder="输入分片大小, 单位bit, 最小100k">
+      </div>
+
+      <div class="input-control">
+        <label for="parallel">上传分片数(构造参数 parallel, 默认 5):</label>
+        <input type="text" class="form-control" id="parallel" v-model="parallel" placeholder="输入并行上传分片个数, 默认为5">
+      </div>
+
+      <div class="input-control">
+        <label for="retryCount">网络失败重试次数(构造参数 retryCount, 默认 3):</label>
+        <input type="text" class="form-control" id="retryCount" v-model="retryCount" placeholder="输入网络失败重试次数, 默认为3">
+      </div>
+
+      <div class="input-control">
+        <label for="retryDuration">网络失败重试间隔(构造参数 retryDuration, 默认 2):</label>
+        <input type="text" class="form-control" id="retryDuration" v-model="retryDuration" placeholder="输入网络失败重试间隔, 默认2秒">
+      </div>
+
+      <div class="input-control">
+        <label for="region">配置项 region, 默认 cn-shanghai:</label>
+        <select v-model="region">
+          <option>cn-shanghai</option>
+          <option>eu-central-1</option>
+          <option>ap-southeast-1</option>
+        </select>
+      </div>
+
+      <div class="input-control">
+        <label for="userId">阿里云账号ID</label>
+        <input type="text" class="form-control" v-model="userId" disabled placeholder="输入阿里云账号ID">
+        userId必填,只需要有值即可
+      </div>
+
+    </div>
+
+    <div class="upload">
+      <div>
+        <input type="file" id="fileUpload" @change="fileChange($event)">
+        <label class="status">上传状态: <span>{{statusText}}</span></label>
+      </div>
+      <div class="upload-type">
+        上传方式二, 使用 STSToken 上传:
+        <button @click="stsUpload" :disabled="uploadDisabled">开始上传</button>
+        <button @click="pauseUpload" :disabled="pauseDisabled">暂停</button>
+        <button :disabled="resumeDisabled" @click="resumeUpload">恢复上传</button>
+        <span class="progress">上传进度: <i id="sts-progress">{{stsProgress}}</i> %</span>
+      </div>
+    </div>
+    <div class="info">点播STS参数如何获取,请查阅<a href="https://help.aliyun.com/document_detail/57114.html" target="_blakn">获取STS</a></div>
+  </div>
+</template>
+<script>
+  import axios from 'axios'
+
+  export default {
+    data () {
+      return {
+        timeout: '',
+        partSize: '',
+        parallel: '',
+        retryCount: '',
+        retryDuration: '',
+        region: 'cn-shanghai',
+        userId: '1303984639806000',        
+        file: null,
+        stsProgress: 0,
+        uploadDisabled: true,
+        resumeDisabled: true,
+        pauseDisabled: true,
+        statusText: '',
+        pauseDisabled: true,
+        uploader: null
+      }
+    },
+    methods: {
+      fileChange (e) {
+        this.file = e.target.files[0]
+        if (!this.file) {
+          alert("请先选择需要上传的文件!")
+          return
+        }
+        var Title = this.file.name
+        var userData = '{"Vod":{}}'
+        if (this.uploader) {
+          this.uploader.stopUpload()
+          this.authProgress = 0
+          this.statusText = ""
+        }
+        this.uploader = this.createUploader()
+        // 首先调用 uploader.addFile(event.target.files[i], null, null, null, userData)
+        console.log(userData)
+        this.uploader.addFile(this.file, null, null, null, userData)
+        this.uploadDisabled = false
+        this.pauseDisabled = true
+        this.resumeDisabled = false
+      },
+      // 开始上传
+      stsUpload () {
+        // 然后调用 startUpload 方法, 开始上传
+        if (this.uploader !== null) {
+          this.uploader.startUpload()
+          this.uploadDisabled = true
+          this.pauseDisabled = false
+        }
+      },
+      // 暂停上传
+      pauseUpload () {
+        if (this.uploader !== null) {
+          this.uploader.stopUpload()
+          this.resumeDisabled = false
+          this.pauseDisabled = true
+        }
+      },
+      // 恢复上传
+      resumeUpload () {
+        if (this.uploader !== null) {
+          this.uploader.startUpload()
+          this.resumeDisabled = true
+          this.pauseDisabled = false
+        }
+      },
+      createUploader () {
+        let self = this
+        let uploader = new AliyunUpload.Vod({
+          timeout: self.timeout || 60000,
+          partSize: self.partSize || 1048576,
+          parallel: self.parallel || 5,
+          retryCount: self.retryCount || 3,
+          retryDuration: self.retryDuration || 2,
+          region: self.region,
+          userId: self.userId,
+          // 添加文件成功
+          addFileSuccess: function (uploadInfo) {
+            self.uploadDisabled = false
+            self.resumeDisabled = false
+            self.statusText = '添加文件成功, 等待上传...'
+            console.log("addFileSuccess: " + uploadInfo.file.name)
+          },
+          // 开始上传
+          onUploadstarted: function (uploadInfo) {
+            // 如果是 STSToken 上传方式, 需要调用 uploader.setUploadAuthAndAddress 方法
+            // 用户需要自己获取 accessKeyId, accessKeySecret,secretToken
+            // 下面的 URL 只是测试接口, 用于获取 测试的 accessKeyId, accessKeySecret,secretToken
+            let stsUrl = 'http://demo-vod.cn-shanghai.aliyuncs.com/voddemo/CreateSecurityToken?BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=67999yyuuuy&AppVersion=1.0.0'
+            axios.get(stsUrl).then(({data}) => {
+              let info = data.SecurityTokenInfo
+              let accessKeyId = info.AccessKeyId
+              let accessKeySecret = info.AccessKeySecret
+              let secretToken = info.SecurityToken
+              uploader.setSTSToken(uploadInfo, accessKeyId, accessKeySecret, secretToken)
+            })
+            self.statusText = '文件开始上传...'
+            console.log("onUploadStarted:" + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)
+          },
+          // 文件上传成功
+          onUploadSucceed: function (uploadInfo) {
+            console.log("onUploadSucceed: " + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)
+            self.statusText = '文件上传成功!'
+          },
+          // 文件上传失败
+          onUploadFailed: function (uploadInfo, code, message) {
+            console.log("onUploadFailed: file:" + uploadInfo.file.name + ",code:" + code + ", message:" + message)
+            self.statusText = '文件上传失败!'
+          },
+          // 取消文件上传
+          onUploadCanceled: function (uploadInfo, code, message) {
+            console.log("Canceled file: " + uploadInfo.file.name + ", code: " + code + ", message:" + message)
+            self.statusText = '文件已暂停上传'
+          },
+          // 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上
+          onUploadProgress: function (uploadInfo, totalSize, progress) {
+            console.log("onUploadProgress:file:" + uploadInfo.file.name + ", fileSize:" + totalSize + ", percent:" + Math.ceil(progress * 100) + "%")
+            let progressPercent = Math.ceil(progress * 100)
+            self.stsProgress = progressPercent
+            self.statusText = '文件上传中...'
+          },
+          // 上传凭证超时
+          onUploadTokenExpired: function (uploadInfo) {
+            // 如果是上传方式二即根据 STSToken 实现时,从新获取STS临时账号用于恢复上传
+            // 上传文件过大时可能在上传过程中 sts token 就会失效, 所以需要在 token 过期的回调中调用 resumeUploadWithSTSToken 方法
+            // 这里是测试接口, 所以我直接获取了 STSToken
+            let stsUrl = 'http://demo-vod.cn-shanghai.aliyuncs.com/voddemo/CreateSecurityToken?BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=67999yyuuuy&AppVersion=1.0.0'
+            axios.get(stsUrl).then(({data}) => {
+              let info = data.SecurityTokenInfo
+              let accessKeyId = info.AccessKeyId
+              let accessKeySecret = info.AccessKeySecret
+              let secretToken = info.SecurityToken
+              let expiration = info.Expiration
+              uploader.resumeUploadWithSTSToken(accessKeyId, accessKeySecret, secretToken, expiration)
+            })
+            self.statusText = '文件超时...'
+          },
+          // 全部文件上传结束
+          onUploadEnd: function (uploadInfo) {
+            console.log("onUploadEnd: uploaded all the files")
+            self.statusText = '文件上传完毕'
+          }
+        })
+        return uploader
+      }
+    }
+  }
+</script>

+ 222 - 0
components/videoUpload/src/UploadAuth.vue

@@ -0,0 +1,222 @@
+<template>
+  <div class="container">
+    <div class="setting">
+      <div class="input-control">
+        <label for="timeout">请求过期时间(构造参数 timeout, 默认 60000):</label>
+        <input type="text" id="timeout" v-model="timeout" placeholder="输入过期时间, 单位毫秒">
+      </div>
+
+      <div class="input-control">
+        <label for="partSize">分片大小(构造参数 partSize, 默认 1048576):</label>
+        <input type="text" class="form-control" id="partSize" v-model="partSize" placeholder="输入分片大小, 单位bit, 最小100k">
+      </div>
+
+      <div class="input-control">
+        <label for="parallel">上传分片数(构造参数 parallel, 默认 5):</label>
+        <input type="text" class="form-control" id="parallel" v-model="parallel" placeholder="输入并行上传分片个数, 默认为5">
+      </div>
+
+      <div class="input-control">
+        <label for="retryCount">网络失败重试次数(构造参数 retryCount, 默认 3):</label>
+        <input type="text" class="form-control" id="retryCount" v-model="retryCount" placeholder="输入网络失败重试次数, 默认为3">
+      </div>
+
+      <div class="input-control">
+        <label for="retryDuration">网络失败重试间隔(构造参数 retryDuration, 默认 2):</label>
+        <input type="text" class="form-control" id="retryDuration" v-model="retryDuration" placeholder="输入网络失败重试间隔, 默认2秒">
+      </div>
+
+      <div class="input-control">
+        <label for="region">配置项 region, 默认 cn-shanghai:</label>
+        <select v-model="region">
+          <option>cn-shanghai</option>
+          <option>eu-central-1</option>
+          <option>ap-southeast-1</option>
+        </select>
+      </div>
+
+      <div class="input-control">
+        <label for="userId">阿里云账号ID</label>
+        <input type="text" class="form-control" v-model="userId" disabled placeholder="输入阿里云账号ID">
+        
+      </div>
+
+    </div>
+
+    <div class="upload">
+      <div>
+        <input type="file" id="fileUpload" @change="fileChange($event)">
+        <label class="status">上传状态: <span>{{statusText}}</span></label>
+      </div>
+      <div class="upload-type">
+        上传方式一, 使用 UploadAuth 上传:
+        <button @click="authUpload" :disabled="uploadDisabled">开始上传</button>
+        <button @click="pauseUpload" :disabled="pauseDisabled">暂停</button>
+        <button :disabled="resumeDisabled" @click="resumeUpload">恢复上传</button>
+        <span class="progress">上传进度: <i id="auth-progress">{{authProgress}}</i> %</span>
+      </div>
+    </div>
+    <div class="info">uploadAuth及uploadAddress参数请查看<a href="https://help.aliyun.com/document_detail/55407.html" target="_blank">获取上传地址和凭证</a></div>
+  </div>
+</template>
+
+<script>
+  import '../lib/aliyun-upload-sdk/lib/es6-promise.min.js'
+  import '../lib/aliyun-upload-sdk/lib/aliyun-oss-sdk-6.13.0.min.js'
+  import '../lib/aliyun-upload-sdk/aliyun-upload-sdk-1.5.2.min.js'
+  import axios from 'axios'
+
+  export default {
+    data () {
+      return {
+        timeout: '',
+        partSize: '',
+        parallel: '',
+        retryCount: '',
+        retryDuration: '',
+        region: 'cn-shanghai',
+        userId: '1303984639806000',
+        file: null,
+        authProgress: 0,
+        uploadDisabled: true,
+        resumeDisabled: true,
+        pauseDisabled: true,
+        uploader: null,
+        statusText: '',
+      }
+    },
+    props: {
+      getUserData: {
+        type: Function
+      }
+    },
+    methods: {
+      fileChange (e) {
+        this.file = e.target.files[0]
+        if (!this.file) {
+          alert("请先选择需要上传的文件!")
+          return
+        }
+        var title = this.file.name;
+        var that = this;
+        this.getUserData(title, function (userData) {
+          if (that.uploader) {
+            that.uploader.stopUpload()
+            that.authProgress = 0
+            that.statusText = ""
+          }
+          that.uploader = that.createUploader()
+          
+          that.uploader.addFile(that.file, null, null, null)
+          that.uploadDisabled = false
+          that.pauseDisabled = true
+          that.resumeDisabled = true
+        });
+
+      },
+      authUpload () {
+        // 然后调用 startUpload 方法, 开始上传
+        if (this.uploader !== null) {
+          this.uploader.startUpload()
+          this.uploadDisabled = true
+          this.pauseDisabled = false
+        }
+      },
+      // 暂停上传
+      pauseUpload () {
+        if (this.uploader !== null) {
+          this.uploader.stopUpload()
+          this.resumeDisabled = false
+          this.pauseDisabled = true
+        }
+      },
+      // 恢复上传
+      resumeUpload () {
+        if (this.uploader !== null) {
+          this.uploader.startUpload()
+          this.resumeDisabled = true
+          this.pauseDisabled = false
+        }
+      },
+      createUploader (type) {
+        let self = this
+        let uploader = new AliyunUpload.Vod({
+          timeout: self.timeout || 60000,
+          partSize: self.partSize || 1048576,
+          parallel: self.parallel || 5,
+          retryCount: self.retryCount || 3,
+          retryDuration: self.retryDuration || 2,
+          region: self.region,
+          userId: self.userId,
+          // 添加文件成功
+          addFileSuccess: function (uploadInfo) {
+            self.uploadDisabled = false
+            self.resumeDisabled = false
+            self.statusText = '添加文件成功, 等待上传...'
+            console.log("addFileSuccess: " + uploadInfo.file.name)
+          },
+          // 开始上传
+          onUploadstarted: function (uploadInfo) {
+
+            self.$post("/api/admin/upload/video", {filename: uploadInfo.file.name}).then(({data}) => {
+              console.log(data);
+              let uploadAuth = data.UploadAuth
+              let uploadAddress = data.UploadAddress
+              let videoId = data.VideoId
+              uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress,videoId);
+               self.statusText = '文件开始上传...'
+              console.log("onUploadStarted:" + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)            
+            })
+           
+          
+            // let uploadAuth = uploadInfo.videoInfo.UploadAuth;
+            // let uploadAddress = uploadInfo.videoInfo.UploadAddress;
+            // let videoId = uploadInfo.videoInfo.VideoId;
+            // uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress,videoId)
+          },
+          // 文件上传成功
+          onUploadSucceed: function (uploadInfo) {
+            console.log("onUploadSucceed: " + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)
+            self.statusText = '文件上传成功!'
+          },
+          // 文件上传失败
+          onUploadFailed: function (uploadInfo, code, message) {
+            console.log("onUploadFailed: file:" + uploadInfo.file.name + ",code:" + code + ", message:" + message)
+            self.statusText = '文件上传失败!'
+          },
+          // 取消文件上传
+          onUploadCanceled: function (uploadInfo, code, message) {
+            console.log("Canceled file: " + uploadInfo.file.name + ", code: " + code + ", message:" + message)
+            self.statusText = '文件已暂停上传'
+          },
+          // 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上
+          onUploadProgress: function (uploadInfo, totalSize, progress) {
+            console.log("onUploadProgress:file:" + uploadInfo.file.name + ", fileSize:" + totalSize + ", percent:" + Math.ceil(progress * 100) + "%")
+            let progressPercent = Math.ceil(progress * 100)
+            self.authProgress = progressPercent
+            self.statusText = '文件上传中...'
+          },
+          // 上传凭证超时
+          onUploadTokenExpired: function (uploadInfo) {
+            // 上传大文件超时, 如果是上传方式一即根据 UploadAuth 上传时
+            // 需要根据 uploadInfo.videoId 调用刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)重新获取 UploadAuth
+            // 然后调用 resumeUploadWithAuth 方法, 这里是测试接口, 所以我直接获取了 UploadAuth
+            let refreshUrl = 'https://demo-vod.cn-shanghai.aliyuncs.com/voddemo/RefreshUploadVideo?BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=59ECA-4193-4695-94DD-7E1247288&AppVersion=1.0.0&Title=haha1&FileName=xxx.mp4&VideoId=' + uploadInfo.videoId
+            axios.get(refreshUrl).then(({data}) => {
+              let uploadAuth = data.UploadAuth
+              uploader.resumeUploadWithAuth(uploadAuth)
+              console.log('upload expired and resume upload with uploadauth ' + uploadAuth)
+            })
+            self.statusText = '文件超时...'
+          },
+          // 全部文件上传结束
+          onUploadEnd: function (uploadInfo) {
+            console.log("onUploadEnd: uploaded all the files")
+            self.statusText = '文件上传完毕'
+          }
+        })
+        return uploader
+      }
+    }
+  }
+</script>

+ 225 - 0
components/videoUpload/src/UploadAuth3.vue

@@ -0,0 +1,225 @@
+<template>
+  <div class="container">
+    <div class="setting">
+      <div class="input-control">
+        <label for="timeout">请求过期时间(构造参数 timeout, 默认 60000):</label>
+        <input type="text" id="timeout" v-model="timeout" placeholder="输入过期时间, 单位毫秒">
+      </div>
+
+      <div class="input-control">
+        <label for="partSize">分片大小(构造参数 partSize, 默认 1048576):</label>
+        <input type="text" class="form-control" id="partSize" v-model="partSize" placeholder="输入分片大小, 单位bit, 最小100k">
+      </div>
+
+      <div class="input-control">
+        <label for="parallel">上传分片数(构造参数 parallel, 默认 5):</label>
+        <input type="text" class="form-control" id="parallel" v-model="parallel" placeholder="输入并行上传分片个数, 默认为5">
+      </div>
+
+      <div class="input-control">
+        <label for="retryCount">网络失败重试次数(构造参数 retryCount, 默认 3):</label>
+        <input type="text" class="form-control" id="retryCount" v-model="retryCount" placeholder="输入网络失败重试次数, 默认为3">
+      </div>
+
+      <div class="input-control">
+        <label for="retryDuration">网络失败重试间隔(构造参数 retryDuration, 默认 2):</label>
+        <input type="text" class="form-control" id="retryDuration" v-model="retryDuration" placeholder="输入网络失败重试间隔, 默认2秒">
+      </div>
+
+      <div class="input-control">
+        <label for="region">配置项 region, 默认 cn-shanghai:</label>
+        <select v-model="region">
+          <option>cn-shanghai</option>
+          <option>eu-central-1</option>
+          <option>ap-southeast-1</option>
+        </select>
+      </div>
+
+      <div class="input-control">
+        <label for="userId">阿里云账号ID</label>
+        <input type="text" class="form-control" v-model="userId" disabled placeholder="输入阿里云账号ID">
+        
+      </div>
+
+    </div>
+
+    <div class="upload">
+      <div>
+        <input type="file" id="fileUpload" @change="fileChange($event)">
+        <label class="status">上传状态: <span>{{statusText}}</span></label>
+      </div>
+      <div class="upload-type">
+        上传方式一, 使用 UploadAuth 上传:
+        <button @click="authUpload" :disabled="uploadDisabled">开始上传</button>
+        <button @click="pauseUpload" :disabled="pauseDisabled">暂停</button>
+        <button :disabled="resumeDisabled" @click="resumeUpload">恢复上传</button>
+        <span class="progress">上传进度: <i id="auth-progress">{{authProgress}}</i> %</span>
+      </div>
+    </div>
+    <div class="info">uploadAuth及uploadAddress参数请查看<a href="https://help.aliyun.com/document_detail/55407.html" target="_blank">获取上传地址和凭证</a></div>
+  </div>
+</template>
+<script>
+  import '../lib/aliyun-upload-sdk/lib/es6-promise.min.js'
+  import '../lib/aliyun-upload-sdk/lib/aliyun-oss-sdk-6.13.0.min.js'
+  import '../lib/aliyun-upload-sdk/aliyun-upload-sdk-1.5.2.min.js'
+  import axios from 'axios'
+
+  export default {
+    data () {
+      return {
+        timeout: '',
+        partSize: '',
+        parallel: '',
+        retryCount: '',
+        retryDuration: '',
+        region: 'cn-shanghai',
+        userId: '1303984639806000',
+        file: null,
+        authProgress: 0,
+        uploadDisabled: true,
+        resumeDisabled: true,
+        pauseDisabled: true,
+        uploader: null,
+        statusText: '',
+      }
+    },
+    methods: {
+      fileChange (e) {
+        this.file = e.target.files[0]
+        if (!this.file) {
+          alert("请先选择需要上传的文件!")
+          return
+        }
+        var Title = this.file.name
+        var userData = '{"Vod":{}}'
+        if (this.uploader) {
+          this.uploader.stopUpload()
+          this.authProgress = 0
+          this.statusText = ""
+        }
+        this.uploader = this.createUploader()
+        console.log(userData)
+        this.uploader.addFile(this.file, null, null, null, userData)
+        this.uploadDisabled = false
+        this.pauseDisabled = true
+        this.resumeDisabled = true
+      },
+      authUpload () {
+        // 然后调用 startUpload 方法, 开始上传
+        if (this.uploader !== null) {
+          this.uploader.startUpload()
+          this.uploadDisabled = true
+          this.pauseDisabled = false
+        }
+      },
+      // 暂停上传
+      pauseUpload () {
+        if (this.uploader !== null) {
+          this.uploader.stopUpload()
+          this.resumeDisabled = false
+          this.pauseDisabled = true
+        }
+      },
+      // 恢复上传
+      resumeUpload () {
+        if (this.uploader !== null) {
+          this.uploader.startUpload()
+          this.resumeDisabled = true
+          this.pauseDisabled = false
+        }
+      },
+      createUploader (type) {
+        let self = this
+        let uploader = new AliyunUpload.Vod({
+          timeout: self.timeout || 60000,
+          partSize: self.partSize || 1048576,
+          parallel: self.parallel || 5,
+          retryCount: self.retryCount || 3,
+          retryDuration: self.retryDuration || 2,
+          region: self.region,
+          userId: self.userId,
+          // 添加文件成功
+          addFileSuccess: function (uploadInfo) {
+            self.uploadDisabled = false
+            self.resumeDisabled = false
+            self.statusText = '添加文件成功, 等待上传...'
+            console.log("addFileSuccess: " + uploadInfo.file.name)
+          },
+          // 开始上传
+          onUploadstarted: function (uploadInfo) {
+            // 如果是 UploadAuth 上传方式, 需要调用 uploader.setUploadAuthAndAddress 方法
+            // 如果是 UploadAuth 上传方式, 需要根据 uploadInfo.videoId是否有值,调用点播的不同接口获取uploadauth和uploadAddress
+            // 如果 uploadInfo.videoId 有值,调用刷新视频上传凭证接口,否则调用创建视频上传凭证接口
+            // 注意: 这里是测试 demo 所以直接调用了获取 UploadAuth 的测试接口, 用户在使用时需要判断 uploadInfo.videoId 存在与否从而调用 openApi
+            // 如果 uploadInfo.videoId 存在, 调用 刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)
+            // 如果 uploadInfo.videoId 不存在,调用 获取视频上传地址和凭证接口(https://help.aliyun.com/document_detail/55407.html)
+            if (!uploadInfo.videoId) {
+              let createUrl = 'https://demo-vod.cn-shanghai.aliyuncs.com/voddemo/CreateUploadVideo?Title=testvod1&FileName=aa.mp4&BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=59ECA-4193-4695-94DD-7E1247288&AppVersion=1.0.0&VideoId=5bfcc7864fc14b96972842172207c9e6'
+              self.$post("/api/admin/upload/video", {filename: uploadInfo.file.name}).then(({data}) => {
+                console.log(data);
+                let uploadAuth = data.UploadAuth
+                let uploadAddress = data.UploadAddress
+                let videoId = data.VideoId
+                uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress,videoId)                
+              })
+              self.statusText = '文件开始上传...'
+              console.log("onUploadStarted:" + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)
+            } else {
+              // 如果videoId有值,根据videoId刷新上传凭证
+              // https://help.aliyun.com/document_detail/55408.html?spm=a2c4g.11186623.6.630.BoYYcY
+              let refreshUrl = 'https://demo-vod.cn-shanghai.aliyuncs.com/voddemo/RefreshUploadVideo?BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=59ECA-4193-4695-94DD-7E1247288&AppVersion=1.0.0&Title=haha1&FileName=xxx.mp4&VideoId=' + uploadInfo.videoId
+              axios.get(refreshUrl).then(({data}) => {
+                let uploadAuth = data.UploadAuth
+                let uploadAddress = data.UploadAddress
+                let videoId = data.VideoId
+                uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress,videoId)
+              })
+            }
+          },
+          // 文件上传成功
+          onUploadSucceed: function (uploadInfo) {
+            console.log("onUploadSucceed: " + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)
+            self.statusText = '文件上传成功!'
+          },
+          // 文件上传失败
+          onUploadFailed: function (uploadInfo, code, message) {
+            console.log("onUploadFailed: file:" + uploadInfo.file.name + ",code:" + code + ", message:" + message)
+            self.statusText = '文件上传失败!'
+          },
+          // 取消文件上传
+          onUploadCanceled: function (uploadInfo, code, message) {
+            console.log("Canceled file: " + uploadInfo.file.name + ", code: " + code + ", message:" + message)
+            self.statusText = '文件已暂停上传'
+          },
+          // 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上
+          onUploadProgress: function (uploadInfo, totalSize, progress) {
+            console.log("onUploadProgress:file:" + uploadInfo.file.name + ", fileSize:" + totalSize + ", percent:" + Math.ceil(progress * 100) + "%")
+            let progressPercent = Math.ceil(progress * 100)
+            self.authProgress = progressPercent
+            self.statusText = '文件上传中...'
+          },
+          // 上传凭证超时
+          onUploadTokenExpired: function (uploadInfo) {
+            // 上传大文件超时, 如果是上传方式一即根据 UploadAuth 上传时
+            // 需要根据 uploadInfo.videoId 调用刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)重新获取 UploadAuth
+            // 然后调用 resumeUploadWithAuth 方法, 这里是测试接口, 所以我直接获取了 UploadAuth
+            let refreshUrl = 'https://demo-vod.cn-shanghai.aliyuncs.com/voddemo/RefreshUploadVideo?BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=59ECA-4193-4695-94DD-7E1247288&AppVersion=1.0.0&Title=haha1&FileName=xxx.mp4&VideoId=' + uploadInfo.videoId
+            axios.get(refreshUrl).then(({data}) => {
+              let uploadAuth = data.UploadAuth
+              uploader.resumeUploadWithAuth(uploadAuth)
+              console.log('upload expired and resume upload with uploadauth ' + uploadAuth)
+            })
+            self.statusText = '文件超时...'
+          },
+          // 全部文件上传结束
+          onUploadEnd: function (uploadInfo) {
+            console.log("onUploadEnd: uploaded all the files")
+            self.statusText = '文件上传完毕'
+          }
+        })
+        return uploader
+      }
+    }
+  }
+</script>

+ 21 - 0
components/videoUpload/src/index.html

@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>阿里云点播上传demo (使用vue)</title>
+    <meta name="description" content="">
+    <meta name="keywords" content="">
+    <meta http-equiv="Cache-Control" content="no-siteapp">
+    <meta http-equiv="cleartype" content="on">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
+    <meta name="HandheldFriendly" content="True">
+    <meta name="MobileOptimized" content="320">
+    <script src="/lib/aliyun-upload-sdk/lib/es6-promise.min.js"></script>
+    <script src="/lib/aliyun-upload-sdk/lib/aliyun-oss-sdk-6.13.0.min.js"></script>
+    <script src="/lib/aliyun-upload-sdk/aliyun-upload-sdk-1.5.2.min.js"></script>
+  </head>
+  <body>
+    <div id="app"></div>
+  </body>
+</html>

+ 29 - 0
components/videoUpload/src/main.js

@@ -0,0 +1,29 @@
+import Vue from 'vue'
+import App from './App.vue'
+import "@babel/polyfill"
+import axios from 'axios'
+//兼容IE11
+if (!FileReader.prototype.readAsBinaryString) {
+    FileReader.prototype.readAsBinaryString = function (fileData) {
+       var binary = "";
+       var pt = this;
+       var reader = new FileReader();      
+       reader.onload = function (e) {
+           var bytes = new Uint8Array(reader.result);
+           var length = bytes.byteLength;
+           for (var i = 0; i < length; i++) {
+               binary += String.fromCharCode(bytes[i]);
+           }
+        //pt.result  - readonly so assign binary
+        pt.content = binary;
+        pt.onload()
+    }
+    reader.readAsArrayBuffer(fileData);
+    }
+}
+
+new Vue({
+  el: '#app',
+  template: '<App/>',
+  components: { App }
+})

+ 333 - 0
pages/main/index/sale_vod_publish.vue

@@ -0,0 +1,333 @@
+<template>
+  <div class="mainContainer">
+
+    <div class="pform-head">
+      <h3>发布课程</h3>
+    </div>
+
+    <div class="pform-body">
+      <el-form :model="vodForm" label-width="100px">
+        <el-form-item label="课程所属UID">
+          <el-input v-model="vodForm.uid" placeholder="用户UID" style="width:200px"></el-input>
+        </el-form-item>
+        <el-form-item label="课程标题">
+          <el-input v-model="vodForm.title"></el-input>
+        </el-form-item>
+        <el-form-item label="课程大纲">
+          <el-input type="textarea" v-model="vodForm.content" placeholder="请输入内容"
+                    minlength="5"
+                    maxlength="5000" rows="6"
+                    show-word-limit></el-input>
+        </el-form-item>
+        <el-form-item label="课程价格">
+          <el-input v-model="vodForm.price" placeholder="单位:元" style="width:200px"></el-input>
+        </el-form-item>
+        <el-form-item label="课程首页图" prop="img">
+          <el-upload
+            class="img-uploader"
+            action="/api/admin/cert/uploadImg"
+            :show-file-list="false"
+            :on-success="handleAvatarSuccess"
+            :before-upload="beforeAvatarUpload"
+          >
+          <img v-if="vodForm.img_icon" :src="vodForm.img_icon" class="img" />
+          <i v-else class="el-icon-plus img-uploader-icon"></i>
+          </el-upload>
+        </el-form-item>
+      </el-form>
+      <div class="uploader">
+        <div class="upload">
+          <div>
+            <input type="file" id="fileUpload" @change="fileChange($event)">
+            <label class="status">上传状态: <span>{{statusText}}</span></label>
+          </div>
+          <div class="upload-type">
+            上传方式一, 使用 UploadAuth 上传:
+            <button @click="authUpload" :disabled="uploadDisabled">开始上传</button>
+            <button @click="pauseUpload" :disabled="pauseDisabled">暂停</button>
+            <button :disabled="resumeDisabled" @click="resumeUpload">恢复上传</button>
+            <span class="progress">上传进度: <i id="auth-progress">{{authProgress}}</i> %</span>
+          </div>
+        </div>
+      </div>
+      <div slot="footer">
+        <el-button type="primary" style="margin-left: 100px;">确认发布</el-button>
+      </div>
+    </div>
+
+  </div>
+</template>
+
+<script>
+  import '../../../components/videoUpload/lib/aliyun-upload-sdk/lib/es6-promise.min.js';
+  import '../../../components/videoUpload/lib/aliyun-upload-sdk/lib/aliyun-oss-sdk-6.13.0.min.js';
+  import '../../../components/videoUpload/lib/aliyun-upload-sdk/aliyun-upload-sdk-1.5.2.min.js';
+
+  export default {
+    data() {
+      return {
+        vodForm:{
+          title:'',
+          content:'',
+          uid:'',
+          price:'',
+          img_icon:''
+        },
+        timeout: '',
+        partSize: '',
+        parallel: '',
+        retryCount: '',
+        retryDuration: '',
+        region: 'cn-shanghai',
+        userId: '1333062367014248',
+        file: null,
+        authProgress: 0,
+        uploadDisabled: true,
+        resumeDisabled: true,
+        pauseDisabled: true,
+        uploader: null,
+        statusText: ''
+      }
+    },
+    computed: {
+
+    },
+    mounted() {
+
+    },
+    methods: {
+      handleAvatarSuccess(res, file) {
+        this.vodForm.img_icon = res.data.img_icon
+      },
+      beforeAvatarUpload(file) {
+        return true
+      },
+      // async getUserData(filename, callback) {
+      //   let res = await this.$post("/api/admin/upload/video", {filename: filename});
+      //   if (res && res.status === 1) {
+      //     let data = res.data;
+      //     callback(JSON.stringify({Vod:data}));
+      //   }
+      // },
+
+      fileChange (e) {
+        this.file = e.target.files[0]
+        if (!this.file) {
+          alert("请先选择需要上传的文件!")
+          return
+        }
+        var Title = this.file.name
+        var userData = '{"Vod":{}}'
+        if (this.uploader) {
+          this.uploader.stopUpload()
+          this.authProgress = 0
+          this.statusText = ""
+        }
+        this.uploader = this.createUploader()
+        console.log(userData)
+        this.uploader.addFile(this.file, null, null, null, userData)
+        this.uploadDisabled = false
+        this.pauseDisabled = true
+        this.resumeDisabled = true
+      },
+      authUpload () {
+        // 然后调用 startUpload 方法, 开始上传
+        if (this.uploader !== null) {
+          this.uploader.startUpload()
+          this.uploadDisabled = true
+          this.pauseDisabled = false
+        }
+      },
+      // 暂停上传
+      pauseUpload () {
+        if (this.uploader !== null) {
+          this.uploader.stopUpload()
+          this.resumeDisabled = false
+          this.pauseDisabled = true
+        }
+      },
+      // 恢复上传
+      resumeUpload () {
+        if (this.uploader !== null) {
+          this.uploader.startUpload()
+          this.resumeDisabled = true
+          this.pauseDisabled = false
+        }
+      },
+      createUploader (type) {
+        let self = this
+        let uploader = new AliyunUpload.Vod({
+          timeout: self.timeout || 60000,
+          partSize: self.partSize || 1048576,
+          parallel: self.parallel || 5,
+          retryCount: self.retryCount || 3,
+          retryDuration: self.retryDuration || 2,
+          region: self.region,
+          userId: self.userId,
+          // 添加文件成功
+          addFileSuccess: function (uploadInfo) {
+            self.uploadDisabled = false
+            self.resumeDisabled = false
+            self.statusText = '添加文件成功, 等待上传...'
+            console.log("addFileSuccess: " + uploadInfo.file.name)
+          },
+          // 开始上传
+          onUploadstarted: function (uploadInfo) {
+            // 如果是 UploadAuth 上传方式, 需要调用 uploader.setUploadAuthAndAddress 方法
+            // 如果是 UploadAuth 上传方式, 需要根据 uploadInfo.videoId是否有值,调用点播的不同接口获取uploadauth和uploadAddress
+            // 如果 uploadInfo.videoId 有值,调用刷新视频上传凭证接口,否则调用创建视频上传凭证接口
+            // 注意: 这里是测试 demo 所以直接调用了获取 UploadAuth 的测试接口, 用户在使用时需要判断 uploadInfo.videoId 存在与否从而调用 openApi
+            // 如果 uploadInfo.videoId 存在, 调用 刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)
+            // 如果 uploadInfo.videoId 不存在,调用 获取视频上传地址和凭证接口(https://help.aliyun.com/document_detail/55407.html)
+            if (!uploadInfo.videoId) {
+              let createUrl = 'https://demo-vod.cn-shanghai.aliyuncs.com/voddemo/CreateUploadVideo?Title=testvod1&FileName=aa.mp4&BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=59ECA-4193-4695-94DD-7E1247288&AppVersion=1.0.0&VideoId=5bfcc7864fc14b96972842172207c9e6'
+              self.$post("/api/admin/upload/video", {filename: uploadInfo.file.name}).then(({data}) => {
+                console.log(data);
+                let uploadAuth = data.UploadAuth
+                let uploadAddress = data.UploadAddress
+                let videoId = data.VideoId
+                uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress,videoId)                
+              })
+              self.statusText = '文件开始上传...'
+              console.log("onUploadStarted:" + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)
+            } else {
+              // 如果videoId有值,根据videoId刷新上传凭证
+              // https://help.aliyun.com/document_detail/55408.html?spm=a2c4g.11186623.6.630.BoYYcY
+              let refreshUrl = 'https://demo-vod.cn-shanghai.aliyuncs.com/voddemo/RefreshUploadVideo?BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=59ECA-4193-4695-94DD-7E1247288&AppVersion=1.0.0&Title=haha1&FileName=xxx.mp4&VideoId=' + uploadInfo.videoId
+              axios.get(refreshUrl).then(({data}) => {
+                let uploadAuth = data.UploadAuth
+                let uploadAddress = data.UploadAddress
+                let videoId = data.VideoId
+                uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress,videoId)
+              })
+            }
+          },
+          // 文件上传成功
+          onUploadSucceed: function (uploadInfo) {
+            console.log("onUploadSucceed: " + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)
+            self.statusText = '文件上传成功!'
+          },
+          // 文件上传失败
+          onUploadFailed: function (uploadInfo, code, message) {
+            console.log("onUploadFailed: file:" + uploadInfo.file.name + ",code:" + code + ", message:" + message)
+            self.statusText = '文件上传失败!'
+          },
+          // 取消文件上传
+          onUploadCanceled: function (uploadInfo, code, message) {
+            console.log("Canceled file: " + uploadInfo.file.name + ", code: " + code + ", message:" + message)
+            self.statusText = '文件已暂停上传'
+          },
+          // 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上
+          onUploadProgress: function (uploadInfo, totalSize, progress) {
+            console.log("onUploadProgress:file:" + uploadInfo.file.name + ", fileSize:" + totalSize + ", percent:" + Math.ceil(progress * 100) + "%")
+            let progressPercent = Math.ceil(progress * 100)
+            self.authProgress = progressPercent
+            self.statusText = '文件上传中...'
+          },
+          // 上传凭证超时
+          onUploadTokenExpired: function (uploadInfo) {
+            // 上传大文件超时, 如果是上传方式一即根据 UploadAuth 上传时
+            // 需要根据 uploadInfo.videoId 调用刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)重新获取 UploadAuth
+            // 然后调用 resumeUploadWithAuth 方法, 这里是测试接口, 所以我直接获取了 UploadAuth
+            let refreshUrl = 'https://demo-vod.cn-shanghai.aliyuncs.com/voddemo/RefreshUploadVideo?BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=59ECA-4193-4695-94DD-7E1247288&AppVersion=1.0.0&Title=haha1&FileName=xxx.mp4&VideoId=' + uploadInfo.videoId
+            axios.get(refreshUrl).then(({data}) => {
+              let uploadAuth = data.UploadAuth
+              uploader.resumeUploadWithAuth(uploadAuth)
+              console.log('upload expired and resume upload with uploadauth ' + uploadAuth)
+            })
+            self.statusText = '文件超时...'
+          },
+          // 全部文件上传结束
+          onUploadEnd: function (uploadInfo) {
+            console.log("onUploadEnd: uploaded all the files")
+            self.statusText = '文件上传完毕'
+          }
+        })
+        return uploader
+      }
+
+    }
+  };
+</script>
+
+<style>
+  .pform-head{
+    text-align: center;
+  }
+  .pform-body{
+    margin: 20px 200px;
+  }
+  .img-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+  }
+  .img-uploader .el-upload:hover {
+    border-color: #409eff;
+  }
+  .img-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 178px;
+    height: 178px;
+    line-height: 178px;
+    text-align: center;
+  }
+  .img {
+    width: 270px;
+    height: 190px;
+    display: block;
+  }
+
+  .upload-type-switch {
+    text-align: center;
+  }
+  .container {
+    width: 1200px;
+    margin: 0 auto;
+  }
+  .input-control {
+    margin: 5px 0;
+  }
+  .input-control label {
+    font-size: 14px;
+    color: #333;
+    width: 30%;
+    text-align: right;
+    display: inline-block;
+    vertical-align: middle;
+    margin-right: 10px;
+  }
+  .input-control input {
+    width: 30%;
+    height: 30px;
+    padding: 0 5px;
+  }
+  .upload {
+    padding: 30px 50px;
+  }
+  .progress {
+    font-size: 14px;
+  }
+  .progress i {
+    font-style: normal;
+  }
+  .upload-type {
+    color: #666;
+    font-size: 12px;
+    padding: 10px 0;
+  }
+  .upload-type button {
+    margin: 0 10px 0 20px;
+  }
+  .status {
+    font-size: 14px;
+    margin-left: 30px;
+  }
+  .info {
+    font-size: 14px;
+    padding-left: 30px;
+  }
+</style>

+ 172 - 0
pages/main/index/sale_vod_publish_bk.vue

@@ -0,0 +1,172 @@
+<template>
+  <div class="mainContainer">
+
+    <div class="pform-head">
+      <h3>发布课程</h3>
+    </div>
+
+    <div class="pform-body">
+      <el-form :model="vodForm" label-width="100px">
+        <el-form-item label="课程所属UID">
+          <el-input v-model="vodForm.uid" placeholder="用户UID" style="width:200px"></el-input>
+        </el-form-item>
+        <el-form-item label="课程标题">
+          <el-input v-model="vodForm.title"></el-input>
+        </el-form-item>
+        <el-form-item label="课程大纲">
+          <el-input type="textarea" v-model="vodForm.content" placeholder="请输入内容"
+                    minlength="5"
+                    maxlength="5000" rows="6"
+                    show-word-limit></el-input>
+        </el-form-item>
+        <el-form-item label="课程价格">
+          <el-input v-model="vodForm.price" placeholder="单位:元" style="width:200px"></el-input>
+        </el-form-item>
+        <el-form-item label="课程首页图" prop="img">
+          <el-upload
+            class="img-uploader"
+            action="/api/admin/cert/uploadImg"
+            :show-file-list="false"
+            :on-success="handleAvatarSuccess"
+            :before-upload="beforeAvatarUpload"
+          >
+          <img v-if="vodForm.img_icon" :src="vodForm.img_icon" class="img" />
+          <i v-else class="el-icon-plus img-uploader-icon"></i>
+          </el-upload>
+        </el-form-item>
+      </el-form>
+      <div class="uploader">
+        <UploadAuth :getUserData="getUserData" />
+      </div>
+      <div slot="footer">
+        <el-button type="primary" style="margin-left: 100px;">确认发布</el-button>
+      </div>
+    </div>
+
+  </div>
+</template>
+
+<script>
+
+  import UploadAuth from "@/components/videoUpload/src/UploadAuth";
+
+  export default {
+    data() {
+      return {
+        vodForm:{
+          title:'',
+          content:'',
+          uid:'',
+          price:'',
+          img_icon:''
+        }
+      }
+    },
+    components: {
+      UploadAuth
+    },
+    computed: {
+
+    },
+    mounted() {
+
+    },
+    methods: {
+      handleAvatarSuccess(res, file) {
+        this.vodForm.img_icon = res.data.img_icon
+      },
+      beforeAvatarUpload(file) {
+        return true
+      },
+      async getUserData(filename, callback) {
+        let res = await this.$post("/api/admin/upload/video", {filename: filename});
+        if (res && res.status === 1) {
+          let data = res.data;
+          callback(JSON.stringify({Vod:data}));
+        }
+      },
+    }
+  };
+</script>
+
+<style>
+  .pform-head{
+    text-align: center;
+  }
+  .pform-body{
+    margin: 20px 200px;
+  }
+  .img-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+  }
+  .img-uploader .el-upload:hover {
+    border-color: #409eff;
+  }
+  .img-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 178px;
+    height: 178px;
+    line-height: 178px;
+    text-align: center;
+  }
+  .img {
+    width: 270px;
+    height: 190px;
+    display: block;
+  }
+
+  .upload-type-switch {
+    text-align: center;
+  }
+  .container {
+    width: 1200px;
+    margin: 0 auto;
+  }
+  .input-control {
+    margin: 5px 0;
+  }
+  .input-control label {
+    font-size: 14px;
+    color: #333;
+    width: 30%;
+    text-align: right;
+    display: inline-block;
+    vertical-align: middle;
+    margin-right: 10px;
+  }
+  .input-control input {
+    width: 30%;
+    height: 30px;
+    padding: 0 5px;
+  }
+  .upload {
+    padding: 30px 50px;
+  }
+  .progress {
+    font-size: 14px;
+  }
+  .progress i {
+    font-style: normal;
+  }
+  .upload-type {
+    color: #666;
+    font-size: 12px;
+    padding: 10px 0;
+  }
+  .upload-type button {
+    margin: 0 10px 0 20px;
+  }
+  .status {
+    font-size: 14px;
+    margin-left: 30px;
+  }
+  .info {
+    font-size: 14px;
+    padding-left: 30px;
+  }
+</style>