Parcourir la source

添加音频相关代码

reghao il y a 3 ans
Parent
commit
b3ee1d51db

Fichier diff supprimé car celui-ci est trop grand
+ 811 - 8
package-lock.json


+ 3 - 2
package.json

@@ -8,10 +8,12 @@
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "@liripeng/vue-audio-player": "^1.5.0",
     "core-js": "^3.6.5",
     "crypto-js": "^4.1.1",
     "dashjs": "^4.2.0",
     "dplayer": "^1.26.0",
+    "element-ui": "2.13.2",
     "filepond": "^4.20.1",
     "filepond-plugin-file-validate-size": "^2.2.1",
     "filepond-plugin-file-validate-type": "^1.2.5",
@@ -22,7 +24,6 @@
     "hls.js": "^1.1.2",
     "js-cookie": "2.2.0",
     "jsencrypt": "^3.2.1",
-    "element-ui": "2.13.2",
     "shaka-player": "^3.2.1",
     "v-viewer": "^1.6.4",
     "vue": "^2.6.12",
@@ -30,9 +31,9 @@
     "vue-filepond": "^6.0.3",
     "vue-infinite-scroll": "^2.0.2",
     "vue-router": "^3.4.5",
+    "vue-simple-uploader": "^0.7.6",
     "vuetify": "^2.3.12",
     "vuex": "^3.4.0",
-    "vue-simple-uploader": "^0.7.6",
     "vuex-persistedstate": "^4.1.0"
   },
   "devDependencies": {

+ 16 - 0
src/api/media/audio.js

@@ -0,0 +1,16 @@
+import $axios from '../index'
+
+const audioApi = {
+  audioPostSubmitApi: '/api/media/audio/post/submit',
+  userAudioListApi: '/api/media/audio/post/user'
+}
+
+// 音频发布接口
+export function submitAudioPost(audioPost) {
+  return $axios.post(audioApi.audioPostSubmitApi, audioPost)
+}
+
+// 用户音频列表
+export function userAudioList(page, userId) {
+  return $axios.get(audioApi.userAudioListApi + '?page=' + page + '&userId=' + userId)
+}

+ 84 - 0
src/components/card/audio-card.vue

@@ -0,0 +1,84 @@
+<template>
+  <div style="width: 640px">
+    <v-card
+      color="white"
+    >
+      <v-card-title>
+        <!--        <v-avatar>
+          <img
+            :src="item.avatarUrl"
+            alt="social"
+          >
+        </v-avatar>-->
+        <span class="text-body-1 font-weight-light">{{ item.userId }}</span>
+        <span class="text-body-1 font-weight-light">{{ item.pubDate }}</span>
+      </v-card-title>
+
+      <v-card-text class-name="text-h5 font-weight-bold">
+        <span v-html="item.title" />
+        <div>
+          <audio-player
+            ref="audioPlayer"
+            :show-prev-button="false"
+            :show-next-button="false"
+            :show-playback-rate="false"
+            :audio-list="audioList.map(elm => elm.url)"
+            :before-play="handleBeforePlay"
+            theme-color="#87CEFA"
+          />
+        </div>
+      </v-card-text>
+      <v-icon
+        small
+        left
+      >
+        mdi-twitter
+      </v-icon>
+    </v-card>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'AudioCard',
+  props: {
+    item: {
+      type: Object,
+      default: () => {
+      }
+    }
+  },
+  data() {
+    return {
+      currentAudioName: '',
+      audioList: []
+    }
+  },
+  created() {
+    this.audioList = [
+      { name: this.item.title, url: this.item.audioUrl }
+    ]
+  },
+  methods: {
+    // 播放前做的事
+    handleBeforePlay(next) {
+      // 这里可以做一些事情...
+      this.currentAudioName = this.audioList[this.$refs.audioPlayer.currentPlayIndex].name
+
+      next() // 开始播放
+    },
+    handlePlaySpecify() {
+      this.$refs.audioPlayer.currentPlayIndex = 1
+      this.$nextTick(() => {
+        this.$refs.audioPlayer.play()
+        this.title = this.audioList[
+          this.$refs.audioPlayer.currentPlayIndex
+        ].name
+      })
+    }
+  }
+}
+</script>
+
+<style>
+</style>

+ 2 - 0
src/main.js

@@ -8,11 +8,13 @@ import infiniteScroll from 'vue-infinite-scroll'
 import 'viewerjs/dist/viewer.css'
 import VueViewer from 'v-viewer'
 import uploader from 'vue-simple-uploader'
+import AudioPlayer from '@liripeng/vue-audio-player'
 
 Vue.use(VueCookies)
 Vue.use(infiniteScroll)
 Vue.use(VueViewer)
 Vue.use(uploader)
+Vue.use(AudioPlayer)
 
 Vue.config.productionTip = false
 

+ 1 - 1
src/router/index.js

@@ -34,7 +34,7 @@ const routes = [
           {
             path: '/studio/upload',
             name: 'Upload',
-            component: () => import('@/views/studio/upload.vue'),
+            component: () => import('@/views/studio/upload1.vue'),
             meta: {
               title: '投稿',
               requireAuth: true

+ 196 - 0
src/views/studio/upload1.vue

@@ -0,0 +1,196 @@
+<template>
+  <v-row justify="center" align="center">
+    <v-col>
+      <v-card
+        class="mx-auto"
+        outlined
+      >
+        <v-row justify="center">
+          <v-col cols="10">
+            <h2>发布音频贴</h2>
+          </v-col>
+        </v-row>
+        <v-row justify="center">
+          <v-col>
+            <uploader
+              class="uploader-example"
+              :options="options"
+              :auto-start="true"
+              @file-added="onFileAdded"
+              @file-success="onFileSuccess"
+              @file-progress="onFileProgress"
+              @file-error="onFileError"
+            >
+              <uploader-unsupport />
+              <uploader-drop>
+                <p>拖动音频文件到此处或</p>
+                <uploader-btn :attrs="attrs">选择音频文件</uploader-btn>
+              </uploader-drop>
+              <uploader-list />
+            </uploader>
+          </v-col>
+        </v-row>
+        <v-divider />
+        <v-row justify="center">
+          <v-col cols="10">
+            <h2>稿件信息</h2>
+          </v-col>
+        </v-row>
+        <v-row justify="center">
+          <v-col cols="10">
+            <v-text-field
+              v-model="audioPost.title"
+              placeholder="标题"
+              label="标题(50字以内)"
+              clearable
+            />
+          </v-col>
+        </v-row>
+        <v-row justify="center">
+          <v-col cols="10">
+            <v-btn large color="primary" @click="publish">立即投稿</v-btn>
+          </v-col>
+        </v-row>
+      </v-card>
+    </v-col>
+
+    <v-snackbar
+      v-model="showMessage"
+      :top="true"
+      :timeout="3000"
+    >
+      {{ message }}
+      <template v-slot:action="{ attrs }">
+        <v-btn
+          color="pink"
+          text
+          v-bind="attrs"
+          @click="showMessage = false"
+        >
+          关闭
+        </v-btn>
+      </template>
+    </v-snackbar>
+  </v-row>
+</template>
+
+<script>
+import { submitAudioPost } from '@/api/media/audio'
+
+export default {
+  data() {
+    return {
+      options: {
+        target: '//api.reghao.cn' + '/api/file/upload/audio',
+        chunkSize: 1024 * 1024 * 1024 * 5, // 分片大小 5GiB
+        forceChunkSize: true,
+        fileParameterName: 'file',
+        maxChunkRetries: 3,
+        testChunks: true,
+        checkChunkUploadedByResponse: function(chunk, message) {
+          const objMessage = JSON.parse(message)
+          console.log('分片文件检验')
+          console.log(objMessage)
+          if (objMessage.skipUpload) {
+            return true
+          }
+
+          return (objMessage.uploaded || []).indexOf(chunk.offset + 1) >= 0
+        },
+        headers: {
+          Authorization: 'Bearer ' + this.$store.getters.token
+        }
+      },
+      attrs: {
+        accept: 'audio/*'
+      },
+      rules: [
+        value => !value || value.size < 1024 * 1024 * 100 || 'Avatar size should be less than 100 MB!'
+      ],
+      // 提交给后端的数据
+      audioPost: {
+        audioFileId: null,
+        audioUrl: null,
+        title: null
+      },
+      showMessage: false,
+      message: ''
+    }
+  },
+  created() {
+  },
+  methods: {
+    onFileAdded(file) {
+      this.setTitle(file.file.name)
+    },
+    onFileProgress(rootFile, file, chunk) {
+    },
+    onFileSuccess(rootFile, file, response, chunk) {
+      const res = JSON.parse(response)
+      if (res.code === 0) {
+        const resData = res.data
+        this.message = '音频文件已上传'
+        this.showMessage = true
+        this.audioPost.audioFileId = resData.audioFileId
+        this.audioPost.audioUrl = resData.url
+      }
+    },
+    onFileError(rootFile, file, response, chunk) {
+      console.log('文件上传错误')
+    },
+    publish() {
+      if (!this.audioPost.audioFileId) {
+        this.message = '你还没有上传音频'
+        this.showMessage = true
+        return
+      }
+
+      if (this.audioPost.title === '') {
+        this.message = '稿件标题不能为空'
+        this.showMessage = true
+        return
+      }
+      submitAudioPost(this.audioPost)
+        .then(res => {
+          if (res.code === 0) {
+            this.message = '投稿成功,等待审核通过后其他人就可以看到你的视频了'
+            this.showMessage = true
+            this.$router.push('/studio')
+          } else {
+            this.message = res.msg
+            this.showMessage = true
+          }
+        })
+        .catch(error => {
+          console.error(error.message)
+        })
+    },
+    setTitle(title) {
+      if (title.length > 50) {
+        this.audioPost.title = title.substring(0, 50)
+      } else {
+        this.audioPost.title = title
+      }
+    }
+  }
+}
+</script>
+
+<style>
+  .uploader-example {
+    width: 500px;
+    padding: 15px;
+    margin: 40px auto 0;
+    font-size: 12px;
+    box-shadow: 0 0 10px rgba(0, 0, 0, .4);
+  }
+  .uploader-example .uploader-btn {
+    margin-right: 4px;
+  }
+  .uploader-example .uploader-list {
+    max-height: 440px;
+    overflow: auto;
+    overflow-x: hidden;
+    overflow-y: auto;
+  }
+</style>

+ 37 - 10
src/views/user/home.vue

@@ -53,7 +53,7 @@
       <v-tabs>
         <v-tab @click="selectTab(0)">视频</v-tab>
         <v-tab @click="selectTab(1)">状态</v-tab>
-        <v-tab @click="selectTab(2)">回答</v-tab>
+        <v-tab @click="selectTab(2)">音频</v-tab>
       </v-tabs>
     </v-container>
     <v-divider />
@@ -107,6 +107,14 @@
           <status-card :item="item" />
         </v-col>
       </v-row>
+      <v-row v-if="cardType === 'answer'">
+        <v-col
+          v-for="item in cardList"
+          :key="item.audioId"
+        >
+          <audio-card :item="item" />
+        </v-col>
+      </v-row>
       <v-row justify="center">
         <v-pagination
           v-model="page"
@@ -120,19 +128,23 @@
 </template>
 
 <script>
+import { userAudioList } from '@/api/media/audio'
 import { userVideoList } from '@/api/media/video'
 import { getUserInfo } from '@/api/user/user'
 import { userStatus } from '@/api/mblog/status'
 import Power from '@/utils/check-power.vue'
+import TimeUtil from '@/utils/time-util.vue'
+
 import StatusCard from '@/components/card/status-card'
 import VideoCard from '@/components/card/video-card.vue'
-import TimeUtil from '@/utils/time-util.vue'
+import AudioCard from '@/components/card/audio-card.vue'
 
 export default {
   name: 'UserHome',
   components: {
     StatusCard,
-    VideoCard
+    VideoCard,
+    AudioCard
   },
   data() {
     return {
@@ -185,9 +197,11 @@ export default {
         this.getStatusList(1)
         this.$vuetify.goTo(type)
       } else if (type === 2) {
-        this.initPagerParam()
+        console.log(this.userId)
+        this.$router.push('/vip/plan')
+        /* this.initPagerParam()
         this.getAnswerList(1)
-        this.$vuetify.goTo(type)
+        this.$vuetify.goTo(type)*/
       }
     },
     initPagerParam() {
@@ -248,11 +262,24 @@ export default {
       })
     },
     getAnswerList(page) {
-      if (this.page === 1) {
-        this.cardList = []
-      }
-      this.cardType = 'answer'
-      console.log('获取回答列表')
+      userAudioList(page, this.userId).then(res => {
+        if (res.code === 0) {
+          this.cardType = 'answer'
+          this.$vuetify.goTo(0)
+
+          const pageList = res.data
+          this.cardList.splice(0, this.cardList.length)
+          for (const item of pageList.list) {
+            this.cardList.push(item)
+          }
+          this.currentPage = pageList.currentPage
+          this.length = pageList.totalPages
+        } else {
+          alert(res.data)
+        }
+      }).catch(error => {
+        console.error(error.message)
+      })
     },
     pageChange(page) {
       this.page = page

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff