|
|
@@ -1,40 +1,296 @@
|
|
|
<template>
|
|
|
- <v-container fill-height>
|
|
|
- <v-tabs>
|
|
|
- <v-tab @click="setShow(0)">图片</v-tab>
|
|
|
- <v-tab @click="setShow(1)">视频</v-tab>
|
|
|
- <v-tab @click="setShow(2)">音乐</v-tab>
|
|
|
- <v-tab @click="setShow(3)">文章</v-tab>
|
|
|
- </v-tabs>
|
|
|
- <VideoPhoto v-if="show === 0" />
|
|
|
- <VideoUpload v-if="show === 1" />
|
|
|
- <VideoMusic v-if="show === 2" />
|
|
|
- <VideoArticle v-if="show === 3" />
|
|
|
- </v-container>
|
|
|
+ <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 cols="10">
|
|
|
+ <!-- <v-file-input prepend-icon="mdi-video" show-size counter accept="video/*,.flv" chips label="请选择视频文件" @change="setFile" /> -->
|
|
|
+ <FilePondUpload @video="videoUploadCallback" />
|
|
|
+ </v-col>
|
|
|
+ </v-row>
|
|
|
+ <v-row justify="center">
|
|
|
+ <v-col cols="10">
|
|
|
+ <h2>基本信息</h2>
|
|
|
+ </v-col>
|
|
|
+ </v-row>
|
|
|
+ <v-row justify="center">
|
|
|
+ <v-col cols="5">
|
|
|
+ <v-card outlined>
|
|
|
+ <v-img :src="videoInfo.coverUrl" aspect-ratio="1.77" contain max-height="150" alt="封面图,推荐16:9" />
|
|
|
+ </v-card>
|
|
|
+ </v-col>
|
|
|
+ <v-col cols="5">
|
|
|
+ <v-file-input
|
|
|
+ :rules="rules"
|
|
|
+ accept="image/png, image/jpeg, image/bmp"
|
|
|
+ placeholder="上传视频封面"
|
|
|
+ prepend-icon="mdi-camera"
|
|
|
+ label="封面"
|
|
|
+ @change="setFile"
|
|
|
+ />
|
|
|
+ <v-btn color="primary" @click="uploadFile">
|
|
|
+ 上传
|
|
|
+ </v-btn>
|
|
|
+ </v-col>
|
|
|
+ </v-row>
|
|
|
+ <v-row justify="center">
|
|
|
+ <v-col cols="5">
|
|
|
+ <v-select
|
|
|
+ :items="category"
|
|
|
+ label="分区"
|
|
|
+ @change="getCategory"
|
|
|
+ />
|
|
|
+ </v-col>
|
|
|
+ <v-col cols="5">
|
|
|
+ <v-select
|
|
|
+ :items="childCategory"
|
|
|
+ label="子分区"
|
|
|
+ @change="getChildCategory"
|
|
|
+ />
|
|
|
+ </v-col>
|
|
|
+ </v-row>
|
|
|
+ <v-row justify="center">
|
|
|
+ <v-col cols="10">
|
|
|
+ <v-text-field
|
|
|
+ v-model="videoInfo.title"
|
|
|
+ placeholder="标题"
|
|
|
+ label="标题(50字以内)"
|
|
|
+ clearable
|
|
|
+ :rules="[() => videoInfo.title != null || '标题不能为空']"
|
|
|
+ />
|
|
|
+ </v-col>
|
|
|
+ </v-row>
|
|
|
+ <v-row justify="center">
|
|
|
+ <v-col cols="10">
|
|
|
+ <v-textarea
|
|
|
+ v-model="videoInfo.description"
|
|
|
+ label="简介(200字以内)"
|
|
|
+ clearable
|
|
|
+ placeholder="填写更全面的视频信息,让更多的人找到你!"
|
|
|
+ />
|
|
|
+ </v-col>
|
|
|
+ </v-row>
|
|
|
+ <v-row justify="center">
|
|
|
+ <v-col cols="10">
|
|
|
+ <v-combobox
|
|
|
+ v-model="videoInfo.tags"
|
|
|
+ label="添加标签让更多人找到你(最多6个)"
|
|
|
+ multiple
|
|
|
+ chips
|
|
|
+ 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 VideoUpload from '@/components/upload/upload-video.vue'
|
|
|
-import VideoPhoto from '@/components/upload/upload-image.vue'
|
|
|
-import VideoArticle from '@/components/upload/upload-article.vue'
|
|
|
-import VideoMusic from '@/components/upload/upload-music.vue'
|
|
|
-
|
|
|
+import FilePondUpload from '@/components/upload/filepond-upload.vue'
|
|
|
+import { videoCategory, submitVideoPost } from '@/api/media/video'
|
|
|
export default {
|
|
|
- name: 'Upload',
|
|
|
components: {
|
|
|
- VideoUpload,
|
|
|
- VideoPhoto,
|
|
|
- VideoArticle,
|
|
|
- VideoMusic
|
|
|
+ FilePondUpload
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
- show: 0
|
|
|
+ rules: [
|
|
|
+ value => !value || value.size < 2000000 || 'Avatar size should be less than 2 MB!'
|
|
|
+ ],
|
|
|
+ // 提交给后端的数据
|
|
|
+ videoInfo: {
|
|
|
+ videoId: '',
|
|
|
+ title: '',
|
|
|
+ description: '',
|
|
|
+ coverUrl: '',
|
|
|
+ duration: 0,
|
|
|
+ categoryId: -1,
|
|
|
+ tags: [],
|
|
|
+ fileId: ''
|
|
|
+ },
|
|
|
+ categoryMap: {
|
|
|
+ Set: function(key, value) { this[key] = value },
|
|
|
+ Get: function(key) { return this[key] },
|
|
|
+ Contains: function(key) { return this.Get(key) !== null },
|
|
|
+ Remove: function(key) { delete this[key] }
|
|
|
+ },
|
|
|
+ category: [],
|
|
|
+ childCategory: [],
|
|
|
+ nowCategory: {},
|
|
|
+ files: [],
|
|
|
+ showMessage: false,
|
|
|
+ message: ''
|
|
|
}
|
|
|
},
|
|
|
+ created() {
|
|
|
+ this.getVideoCategory()
|
|
|
+ },
|
|
|
methods: {
|
|
|
- setShow(value) {
|
|
|
- this.show = value
|
|
|
+ publish() {
|
|
|
+ if (!this.videoInfo.fileId) {
|
|
|
+ this.message = '你还没有上传视频'
|
|
|
+ this.showMessage = true
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (this.videoInfo.title === '' || this.coverUrl === '' || this.videoInfo.tags.length === 0 || this.videoInfo.categoryId === -1) {
|
|
|
+ this.message = '标题,封面,标签,分区不能为空'
|
|
|
+ this.showMessage = true
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.videoInfo.tags.length > 6) {
|
|
|
+ this.message = '标签超过6个'
|
|
|
+ this.showMessage = true
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ submitVideoPost(this.videoInfo)
|
|
|
+ .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)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ setFile(value) {
|
|
|
+ this.files = []
|
|
|
+ this.files.push(value)
|
|
|
+ },
|
|
|
+ // filepond 组件上传文件完成时调用
|
|
|
+ videoUploadCallback(value) {
|
|
|
+ if (value.code === 0) {
|
|
|
+ this.videoInfo.videoId = value.data.videoId
|
|
|
+ this.setTitle(value.data.filename)
|
|
|
+ this.videoInfo.duration = value.data.duration
|
|
|
+ this.videoInfo.coverUrl = value.data.coverUrl
|
|
|
+ this.videoInfo.fileId = value.data.fileId
|
|
|
+
|
|
|
+ this.message = '视频上传成功'
|
|
|
+ this.showMessage = true
|
|
|
+ } else {
|
|
|
+ // TODO 返回错误原因,网络错误或是服务端错误
|
|
|
+ if (value.msg != null) {
|
|
|
+ this.message = '上传文件出现异常,请重新上传!' + value.msg
|
|
|
+ } else {
|
|
|
+ this.message = '上传文件出现异常,请重新上传!'
|
|
|
+ }
|
|
|
+ this.showMessage = true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ setTitle(title) {
|
|
|
+ if (title.length > 50) {
|
|
|
+ this.videoInfo.title = title.substring(0, 50)
|
|
|
+ } else {
|
|
|
+ this.videoInfo.title = title
|
|
|
+ }
|
|
|
+ },
|
|
|
+ uploadFile() {
|
|
|
+ if (this.files.length === 0) {
|
|
|
+ this.message = '请先选择视频封面,然后上传!'
|
|
|
+ this.showMessage = true
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const formData = new FormData()
|
|
|
+ for (let i = 0; i < this.files.length; i++) {
|
|
|
+ formData.append('file[]', this.files[i])
|
|
|
+ }
|
|
|
+ fetch(`http://file.reghao.cn/api/file/upload/image`, {
|
|
|
+ headers: {
|
|
|
+ 'X-XSRF-TOKEN': this.$cookies.get('XSRF-TOKEN')
|
|
|
+ },
|
|
|
+ method: 'POST',
|
|
|
+ credentials: 'include',
|
|
|
+ body: formData
|
|
|
+ }).then(response => response.json())
|
|
|
+ .then(json => {
|
|
|
+ if (json.code === 0) {
|
|
|
+ this.videoInfo.coverUrl = json.data[0].url
|
|
|
+ } else {
|
|
|
+ this.message = '上传失败,请重试!' + json.message
|
|
|
+ this.showMessage = true
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(e => {
|
|
|
+ return null
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getVideoCategory() {
|
|
|
+ videoCategory()
|
|
|
+ .then(res => {
|
|
|
+ if (res.code === 0) {
|
|
|
+ for (let i = 0; i < res.data.length; i++) {
|
|
|
+ const name = res.data[i].name
|
|
|
+ this.category.push(name)
|
|
|
+ this.categoryMap.Set(name, res.data[i])
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ console.error(res.msg)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(error => {
|
|
|
+ console.error(error.message)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getCategory(name) {
|
|
|
+ // 重置子分区,清除前一次选择分区时留下的缓存
|
|
|
+ this.childCategory = []
|
|
|
+ this.currentCategory = this.categoryMap.Get(name)
|
|
|
+ this.videoInfo.categoryId = this.currentCategory.id
|
|
|
+
|
|
|
+ const c = this.currentCategory.children
|
|
|
+ if (c) {
|
|
|
+ for (let i = 0; i < c.length; i++) {
|
|
|
+ this.childCategory.push(c[i].name)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getChildCategory(name) {
|
|
|
+ const c = this.currentCategory.children
|
|
|
+ for (let i = 0; i < c.length; i++) {
|
|
|
+ if (c[i].name === name) {
|
|
|
+ this.videoInfo.categoryId = c[i].id
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|