reghao il y a 2 ans
Parent
commit
33d9f975ee

+ 5 - 0
package-lock.json

@@ -14905,6 +14905,11 @@
         }
       }
     },
+    "vue-filepond": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmmirror.com/vue-filepond/-/vue-filepond-6.0.3.tgz",
+      "integrity": "sha512-m0wArAdpgzOOs19bWA6zzYlHAb2aK+igPoKPZGrzpgKiiELPKW7XZ2OBDXzk7rhpFLkedujVrMqwjPyZfmQTTQ=="
+    },
     "vue-hot-reload-api": {
       "version": "2.3.4",
       "resolved": "https://registry.npm.taobao.org/vue-hot-reload-api/download/vue-hot-reload-api-2.3.4.tgz",

+ 1 - 0
package.json

@@ -39,6 +39,7 @@
     "js-cookie": "2.2.0",
     "nprogress": "^0.2.0",
     "prismjs": "^1.25.0",
+    "vue-filepond": "^6.0.3",
     "svg-sprite-loader": "^5.0.0"
   },
   "devDependencies": {

+ 2 - 2
src/assets/js/mixin.js

@@ -202,11 +202,11 @@ export const userMixin = {
       window.open("//account.reghao.cn", "_blank");
     },
     goToPost() {
-      if (this.$route.path === '/user/post/list') {
+      if (this.$route.path === '/post/list') {
         this.$router.go(0)
         return
       }
-      this.$router.push('/user/post/list')
+      this.$router.push('/post/list')
     },
     goToCollection() {
       if (this.$route.path === '/u/collection') {

+ 1 - 1
src/components/layout/NavBar.vue

@@ -50,7 +50,7 @@
         </a>
       </el-col>
       <el-col :md="2" class="right logo">
-        <a href="/user/post/publish" class="tit logo">
+        <a href="/post/publish" class="tit logo">
           <span class="el-icon-upload logo" />
         </a>
       </el-col>

+ 103 - 0
src/components/upload/FilepodImage.vue

@@ -0,0 +1,103 @@
+<template>
+  <div>
+    <file-pond
+      ref="pond"
+      name="file"
+      label-idle="选择图片或拖动图片到此处"
+      label-file-processing="图片正在上传,请稍后"
+      label-file-processing-aborted="图片上传被取消"
+      label-tap-to-retry="尝试重试"
+      label-file-processing-complete="图片上传成功!"
+      label-max-file-size="上传的图片大小不能超过 10MB"
+      label-max-file-size-exceeded="上传的图片大小不能超过 10MB"
+      allow-file-size-validation="true"
+      max-file-size="10MB"
+      accepted-file-types="image/png, image/jpeg, image/jpg, image/gif"
+      :allow-multiple="true"
+      :max-files="12"
+      :server="server"
+      :instant-upload="true"
+      @init="handleFilePondInit"
+      @processfile="success"
+      @removefile="removeFile"
+    />
+  </div>
+</template>
+
+<script>
+import VueFilePond from 'vue-filepond'
+import 'filepond/dist/filepond.min.css'
+import FilePondPluginImagePreview from 'filepond-plugin-image-preview'
+import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css'
+import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type'
+import FilePondPluginFileValidateSize from 'filepond-plugin-file-validate-size'
+
+// Create component
+const FilePond = VueFilePond(
+  FilePondPluginFileValidateType,
+  FilePondPluginImagePreview,
+  FilePondPluginFileValidateSize
+)
+var resp = ''
+
+export default {
+  name: 'FilePondImage',
+  components: {
+    FilePond
+  },
+  resp,
+  data() {
+    return {
+      imgMap: {},
+      server: {
+        url: '//oss.reghao.cn/',
+        revert: null,
+        process: {
+          headers: {
+            'Authorization': this.$store.getters.token
+          },
+          ondata(formData) {
+            return formData
+          },
+          onload(response) {
+            resp = JSON.parse(response)
+          }
+        }
+      }
+    }
+  },
+  created() {
+  },
+  methods: {
+    handleFilePondInit() {
+      // FilePond instance methods are available on `this.$refs.pond`
+    },
+    success(error, metadata) {
+      if (error === null) {
+        const file = metadata.file
+        const filename = file.name
+        this.imgMap[filename] = resp.data.uploadId
+      }
+      this.$emit('resp', resp)
+    },
+    removeFile(error, metadata) {
+      if (error === null) {
+        const file = metadata.file
+        const uploadId = this.imgMap[file.name]
+        fetch('//file.reghao.cn/api/file/rm/' + uploadId, {
+          headers: {
+            'Authorization': this.$store.getters.token
+          },
+          method: 'DELETE'
+        }).then(response => response.json())
+          .then(json => {
+            console.log(json)
+          })
+          .catch(e => {
+            return null
+          })
+      }
+    }
+  }
+}
+</script>

+ 19 - 16
src/components/upload/PublishArticle.vue

@@ -1,21 +1,24 @@
 <template>
   <div>
-    <el-form ref="form" :model="form" label-width="60px">
-      <el-form-item label="标题">
-        <el-input v-model="form.title" style="width: 70%; padding-right: 2px" />
-      </el-form-item>
-      <el-form-item label="分类" style="width: 70%; padding-right: 2px">
-        <el-input v-model="form.category" />
-      </el-form-item>
-      <el-form-item label="内容">
-        <rich-text @content=processContent style="width: 80%; padding-right: 2px" />
-<!-- <mavon-editor v-model="content" style="width: 90%; padding-right: 2px" />-->
-      </el-form-item>
-      <el-form-item>
-        <el-button type="primary" @click="onSubmit">立即投稿</el-button>
-        <el-button>取消</el-button>
-      </el-form-item>
-    </el-form>
+    <el-row style="position: center">
+      <h2>发布文章</h2>
+      <el-form ref="form" :model="form" label-width="60px">
+        <el-form-item label="标题">
+          <el-input v-model="form.title" style="width: 70%; padding-right: 2px" />
+        </el-form-item>
+        <el-form-item label="分类" style="width: 70%; padding-right: 2px">
+          <el-input v-model="form.category" />
+        </el-form-item>
+        <el-form-item label="内容">
+          <rich-text @content=processContent style="width: 80%; padding-right: 2px" />
+          <!-- <mavon-editor v-model="content" style="width: 90%; padding-right: 2px" />-->
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="onSubmit">立即投稿</el-button>
+          <el-button>取消</el-button>
+        </el-form-item>
+      </el-form>
+    </el-row>
   </div>
 </template>
 

+ 1 - 1
src/components/upload/PublishAudio.vue

@@ -3,7 +3,7 @@
     <el-row>
       <el-card>
         <el-row>
-          <h2>上传音频</h2>
+          <h2>发布音频</h2>
           <uploader
             class="uploader-example"
             :options="options"

+ 104 - 26
src/components/upload/PublishImage.vue

@@ -3,56 +3,134 @@
     <el-row>
       <el-card>
         <el-row style="position: center">
-          <h2>上传封面</h2>
-          <el-upload
-            class="avatar-uploader"
-            action="//api.reghao.cn/api/file/upload/image"
-            :show-file-list="false"
-            :before-upload="beforeAvatarUpload"
-            :on-success="handleAvatarSuccess"
-          >
-            <img v-if="imageUrl" :src="imageUrl" class="avatar">
-            <i v-else class="el-icon-plus avatar-uploader-icon" />
-          </el-upload>
+          <h2>发布图片</h2>
+          <file-pond
+            ref="pond"
+            name="file"
+            label-idle="选择图片或拖动图片到此处"
+            label-file-processing="图片正在上传,请稍后"
+            label-file-processing-aborted="图片上传被取消"
+            label-tap-to-retry="尝试重试"
+            label-file-processing-complete="图片上传成功!"
+            label-max-file-size="上传的图片大小不能超过 10MB"
+            label-max-file-size-exceeded="上传的图片大小不能超过 10MB"
+            allow-file-size-validation="true"
+            max-file-size="10MB"
+            accepted-file-types="image/png, image/jpeg, image/jpg, image/gif"
+            :allow-multiple="true"
+            :max-files="12"
+            :server="server"
+            :instant-upload="true"
+            @init="handleFilePondInit"
+            @processfile="handleFilePondSuccess"
+            @removefile="handleFilePondRemove"
+          />
         </el-row>
+        <el-form ref="form" :model="form" label-width="80px">
+          <el-form-item label="标题">
+            <el-input v-model="form.title" style="width: 70%; padding-right: 2px" placeholder="标题不能超过 50 个字符" />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" @click="onSubmit">立即投稿</el-button>
+            <el-button>取消</el-button>
+          </el-form-item>
+        </el-form>
       </el-card>
     </el-row>
   </div>
 </template>
 
 <script>
+import VueFilePond from 'vue-filepond'
+import 'filepond/dist/filepond.min.css'
+import FilePondPluginImagePreview from 'filepond-plugin-image-preview'
+import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css'
+import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type'
+import FilePondPluginFileValidateSize from 'filepond-plugin-file-validate-size'
+
+const FilePond = VueFilePond(
+  FilePondPluginFileValidateType,
+  FilePondPluginImagePreview,
+  FilePondPluginFileValidateSize
+)
+var imgFileIds = []
+
 export default {
   name: 'PublishImage',
+  components: { FilePond },
   data() {
     return {
       rules: [
         value => !value || value.size < 2000000 || 'Avatar size should be less than 2 MB!'
       ],
       imageList: [],
-      imageUrl: ''
+      imageUrl: '',
+      server: {
+        url: '//oss.reghao.cn/',
+        revert: null,
+        process: {
+          headers: {
+            'Authorization': this.$store.getters.token
+          },
+          ondata(formData) {
+            formData.append('channelId', 5)
+            return formData
+          },
+          onload(response) {
+            const resp = JSON.parse(response)
+            if (resp.code === 0) {
+              console.log(resp)
+              //imgFileIds.push(resp.data.imageUploadId)
+            } else {
+              if (resp.msg != null) {
+                this.message = '上传文件出现异常,请重新上传!' + resp.msg
+              } else {
+                this.message = '上传文件出现异常,请重新上传!'
+              }
+              this.showMessage = true
+            }
+          }
+        }
+      },
+      form: {
+        title: null,
+      }
     }
   },
   created() {
   },
   methods: {
-    beforeAvatarUpload(file) {
-      const isJPG = file.type === 'image/jpeg'
-      const isLt2M = file.size / 1024 / 1024 < 2
-      if (!isJPG) {
-        this.$message.error('上传头像图片只能是 JPG 格式!')
-      }
-      if (!isLt2M) {
-        this.$message.error('上传头像图片大小不能超过 2MB!')
+    handleFilePondInit() {
+      // FilePond instance methods are available on `this.$refs.pond`
+    },
+    handleFilePondSuccess(error, metadata) {
+      if (error === null) {
+        return
       }
-      return isJPG && isLt2M
+      console.log('图片已上传')
+      console.log(metadata)
     },
-    handleAvatarSuccess(res, file) {
-      this.imageList.push(file)
-      console.log(this.imageList)
-      this.imageUrl = URL.createObjectURL(file.raw)
+    handleFilePondRemove(error, metadata) {
+      console.log('删除已上传的图片')
+      /*if (error === null) {
+        const file = metadata.file
+        const uploadId = this.imgMap[file.name]
+        fetch('//oss.reghao.cn/' + uploadId, {
+          headers: {
+            'Authorization': this.$store.getters.token
+          },
+          method: 'DELETE'
+        }).then(response => response.json())
+          .then(json => {
+            console.log('删除 this.statusPost.imageFileIds 中相应的图片')
+          })
+          .catch(e => {
+            return null
+          })
+      }*/
     },
     onSubmit() {
-      console.log('submit!')
+      console.log(this.form)
     }
   }
 }

+ 2 - 2
src/components/upload/PublishVideo.vue

@@ -2,7 +2,7 @@
   <el-col>
     <el-card>
       <el-row>
-        <h2>上传视频</h2>
+        <h2>发布视频</h2>
         <uploader
           class="uploader-example"
           :options="options"
@@ -412,7 +412,7 @@ export default {
                 duration: 3000
               }
             )
-            this.$router.push('/user/post/list')
+            this.$router.push('/post/list')
           } else {
             this.$notify(
               {

+ 1 - 1
src/components/upload/UploadFile.vue

@@ -224,7 +224,7 @@ export default {
                 duration: 3000
               }
             )
-            this.$router.push('/user/post/list')
+            this.$router.push('/post/list')
           } else {
             this.$notify(
               {

+ 54 - 6
src/router/index.js

@@ -24,8 +24,16 @@ const AvatarIndex = () => import('views/user/Avatar')
 const VipIndex = () => import('views/user/Vip')
 const CollectionIndex = () => import('views/user/Collection')
 const HistoryIndex = () => import('views/user/History')
-const PostList = () => import('views/post/PostList')
 const PostPublish = () => import('views/post/PostPublish')
+const PostPublishVideo = () => import('views/post/PostPublish')
+const PostPublishAudio = () => import('views/post/PostPublish')
+const PostPublishImage = () => import('views/post/PostPublish')
+const PostPublishArticle = () => import('views/post/PostPublish')
+const PostList = () => import('views/post/PostList')
+const UserPostVideo = () => import('views/post/PostList')
+const UserPostAudio = () => import('views/post/PostList')
+const UserPostImage = () => import('views/post/PostList')
+const UserPostArticle = () => import('views/post/PostList')
 const PostAnalysis = () => import('views/post/PostAnalysis')
 const MessageIndex = () => import('views/message/Message')
 const DiscoverIndex = () => import('views/home/Discover')
@@ -189,17 +197,57 @@ const routes = [
     component: HistoryIndex
   },
   {
-    path: '/user/post/list',
+    path: '/post/publish',
+    name: 'PostPublish',
+    component: PostPublish
+  },
+  {
+    path: '/post/publish/video',
+    name: 'PostPublishVideo',
+    component: PostPublishVideo
+  },
+  {
+    path: '/post/publish/audio',
+    name: 'PostPublishAudio',
+    component: PostPublishAudio
+  },
+  {
+    path: '/post/publish/image',
+    name: 'PostPublishImage',
+    component: PostPublishImage
+  },
+  {
+    path: '/post/publish/article',
+    name: 'PostPublishArticle',
+    component: PostPublishArticle
+  },
+  {
+    path: '/post/list',
     name: 'PostList',
     component: PostList
   },
   {
-    path: '/user/post/publish',
-    name: 'PostPublish',
-    component: PostPublish
+    path: '/post/video',
+    name: 'UserPostVideo',
+    component: UserPostVideo
+  },
+  {
+    path: '/post/audio',
+    name: 'UserPostAudio',
+    component: UserPostAudio
+  },
+  {
+    path: '/post/image',
+    name: 'UserPostImage',
+    component: UserPostImage
+  },
+  {
+    path: '/post/article',
+    name: 'UserPostArticle',
+    component: UserPostArticle
   },
   {
-    path: '/user/post/analysis',
+    path: '/post/analysis',
     name: 'PostAnalysis',
     component: PostAnalysis
   },

+ 1 - 1
src/views/message/Message.vue

@@ -127,7 +127,7 @@ export default {
                 duration: 3000
               }
             )
-            this.$router.push('/user/post/list')
+            this.$router.push('/post/list')
           } else {
             this.$notify(
               {

+ 8 - 3
src/views/post/PostAnalysis.vue

@@ -26,14 +26,19 @@ export default {
   data() {
     return {
       navList: [
-        { path: '/user/post/publish', name: '发布', icon: 'el-icon-upload' },
-        { path: '/user/post/list', name: '稿件', icon: 'el-icon-files' },
-        { path: '/user/post/analysis', name: '数据', icon: 'el-icon-data-analysis' }
+        { path: '/post/publish', name: '发布', icon: 'el-icon-upload' },
+        { path: '/post/list', name: '稿件', icon: 'el-icon-files' },
+        { path: '/post/analysis', name: '数据', icon: 'el-icon-data-analysis' }
       ]
     }
   },
   created() {
   },
+  watch: {
+    $route(){
+      this.$router.go()
+    }
+  },
   methods: {
   }
 }

+ 112 - 10
src/views/post/PostList.vue

@@ -14,32 +14,134 @@
         </el-menu>
       </el-col>
       <el-col :md="20">
-        <span>稿件列表</span>
+        <el-tabs v-model="activeName" @tab-click='tabClick'>
+          <el-tab-pane label="视频" name="video">
+            <span>
+              <h4>视频稿件</h4>
+            </span>
+          </el-tab-pane>
+          <el-tab-pane label="音频" name="audio">
+            <span>
+              <h4>音频稿件</h4>
+            </span>
+          </el-tab-pane>
+          <el-tab-pane label="图片" name="image">
+            <span>
+              <h4>图片稿件</h4>
+            </span>
+          </el-tab-pane>
+          <el-tab-pane label="文章" name="article">
+            <span>
+              <h4>文章稿件</h4>
+            </span>
+          </el-tab-pane>
+        </el-tabs>
       </el-col>
     </el-row>
   </div>
 </template>
 
 <script>
-import { userVideoList } from '@/api/video'
+import PublishVideo from '@/components/upload/PublishVideo'
 
 export default {
-  name: 'PostList',
+  name: 'Publish',
+  components: { PublishVideo},
   data() {
     return {
       navList: [
-        { path: '/user/post/publish', name: '发布', icon: 'el-icon-upload' },
-        { path: '/user/post/list', name: '稿件', icon: 'el-icon-files' },
-        { path: '/user/post/analysis', name: '数据', icon: 'el-icon-data-analysis' }
-      ]
+        { path: '/post/publish', name: '发布', icon: 'el-icon-upload' },
+        { path: '/post/list', name: '稿件', icon: 'el-icon-files' },
+        { path: '/post/analysis', name: '数据', icon: 'el-icon-data-analysis' }
+      ],
+      activeName: 'video'
     }
   },
   created() {
-    userVideoList(1, 10000).then(res => {
-      console.log(res)
-    })
+    const path = this.$route.path
+    if (path.endsWith("video")) {
+      this.activeName = 'video'
+      document.title = '视频稿件'
+    } else if (path.endsWith("image")) {
+      this.activeName = 'image'
+      document.title = '图片稿件'
+    } else if (path.endsWith("audio")) {
+      this.activeName = 'audio'
+      document.title = '音频稿件'
+    } else if (path.endsWith("article")) {
+      this.activeName = 'article'
+      document.title = '文章稿件'
+    }
+  },
+  watch: {
+    $route(){
+      this.$router.go()
+    }
   },
   methods: {
+    tabClick(tab) {
+      this.activeName = tab.name
+      if (this.activeName === 'video') {
+        this.goToTab(this.activeName)
+      } else if (this.activeName === 'image') {
+        this.goToTab(this.activeName)
+      } else if (this.activeName === 'audio') {
+        this.goToTab(this.activeName)
+      } else if (this.activeName === 'article') {
+        this.goToTab(this.activeName)
+      }
+    },
+    goToTab(activeName) {
+      const path = '/post/' + activeName
+      if (this.$route.path === path) {
+        this.$router.go(0)
+        return
+      }
+      this.$router.push(path)
+    },
   }
 }
 </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;
+}
+
+.avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+.avatar-uploader .el-upload:hover {
+  border-color: #409EFF;
+}
+.avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 320px;
+  height: 240px;
+  line-height: 178px;
+  text-align: center;
+}
+.avatar {
+  width: 320px;
+  height: 240px;
+  display: block;
+}
+</style>

+ 54 - 15
src/views/post/PostPublish.vue

@@ -14,21 +14,21 @@
         </el-menu>
       </el-col>
       <el-col :md="20">
-        <el-tabs v-model="activeName">
-          <el-tab-pane label="视频" name="first">
-            <publish-video v-if="activeName === 'first'" />
+        <el-tabs v-model="activeName" @tab-click='tabClick'>
+          <el-tab-pane label="视频" name="video">
+            <publish-video v-if="activeName === 'video'" />
           </el-tab-pane>
-          <el-tab-pane label="音频" name="second">
-            <publish-audio v-if="activeName === 'second'" />
+          <el-tab-pane label="音频" name="audio">
+            <publish-audio v-if="activeName === 'audio'" />
           </el-tab-pane>
-          <el-tab-pane label="图片" name="third">
-            <publish-image v-if="activeName === 'third'" />
+          <el-tab-pane label="图片" name="image">
+            <publish-image v-if="activeName === 'image'" />
           </el-tab-pane>
-          <el-tab-pane label="文章" name="fourth">
-            <publish-article v-if="activeName === 'fourth'" />
+          <el-tab-pane label="文章" name="article">
+            <publish-article v-if="activeName === 'article'" />
           </el-tab-pane>
-          <el-tab-pane label="文件" name="fifth">
-            <upload-file v-if="activeName === 'fifth'" />
+          <el-tab-pane label="文件" name="file">
+            <upload-file v-if="activeName === 'file'" />
           </el-tab-pane>
         </el-tabs>
       </el-col>
@@ -49,11 +49,11 @@ export default {
   data() {
     return {
       navList: [
-        { path: '/user/post/publish', name: '发布', icon: 'el-icon-upload' },
-        { path: '/user/post/list', name: '稿件', icon: 'el-icon-files' },
-        { path: '/user/post/analysis', name: '数据', icon: 'el-icon-data-analysis' }
+        { path: '/post/publish', name: '发布', icon: 'el-icon-upload' },
+        { path: '/post/list', name: '稿件', icon: 'el-icon-files' },
+        { path: '/post/analysis', name: '数据', icon: 'el-icon-data-analysis' }
       ],
-      activeName: 'first',
+      activeName: 'video',
       coverUrl: null,
       videoUrlId: null,
       coverFile: null,
@@ -65,8 +65,47 @@ export default {
     }
   },
   created() {
+    const path = this.$route.path
+    if (path.endsWith("video")) {
+      this.activeName = 'video'
+      document.title = '发布视频'
+    } else if (path.endsWith("image")) {
+      this.activeName = 'image'
+      document.title = '发布图片'
+    } else if (path.endsWith("audio")) {
+      this.activeName = 'audio'
+      document.title = '发布音频'
+    } else if (path.endsWith("article")) {
+      this.activeName = 'article'
+      document.title = '发布文章'
+    }
+  },
+  watch: {
+    $route(){
+      this.$router.go()
+    }
   },
   methods: {
+    tabClick(tab) {
+      this.activeName = tab.name
+      if (this.activeName === 'video') {
+        this.goToTab(this.activeName)
+      } else if (this.activeName === 'image') {
+        this.goToTab(this.activeName)
+      } else if (this.activeName === 'audio') {
+        this.goToTab(this.activeName)
+      } else if (this.activeName === 'article') {
+        this.goToTab(this.activeName)
+      }
+    },
+    goToTab(activeName) {
+      const path = '/post/publish/' + activeName
+      if (this.$route.path === path) {
+        this.$router.go(0)
+        return
+      }
+      this.$router.push(path)
+    },
   }
 }
 </script>

+ 0 - 1
src/views/user/Home.vue

@@ -306,7 +306,6 @@ export default {
       this.$router.push(path)
     },
     getData() {
-      this.activeName = tab.name
       if (this.activeName === 'status') {
         this.currentPage = 1
         this.lastId = 0