Browse Source

更新 Image 相关页面和接口

reghao 2 years ago
parent
commit
3257fc083e

+ 49 - 13
src/api/image.js

@@ -1,24 +1,60 @@
-import { get, post } from '@/utils/request'
+import { get, post, delete0 } from '@/utils/request'
 
 const imageApi = {
-  imagePostApi: '/api/content/post/image',
-  userAlbumApi: '/api/content/image/album',
-  userAlbumApi1: '/api/content/image/album',
-  albumSubmitApi: '/api/content/image/album/submit',
+  imageAlbumApi: '/api/content/post/image/album',
+  addAlbumImageApi: '/api/content/post/image/album/add',
+  deleteAlbumImageApi: '/api/content/post/image/album/delete',
+  updateAlbumScopeApi: '/api/content/post/image/album/update/scope',
+  updateAlbumCoverApi: '/api/content/post/image/album/update/cover',
+  albumImageApi: '/api/content/post/image/album',
+
+  albumApi: '/api/content/image/album',
+  collectImageApi: '/api/content/image/collect',
+  imageApi: '/api/content/image',
+}
+
+export function submitAlbum(jsonData) {
+  return post(imageApi.imageAlbumApi, jsonData)
+}
+
+export function addAlbumImage(jsonData) {
+  return post(imageApi.addAlbumImageApi, jsonData)
+}
+
+export function updateAlbumScope(jsonData) {
+  return post(imageApi.updateAlbumScopeApi, jsonData)
+}
+
+export function updateAlbumCover(jsonData) {
+  return post(imageApi.updateAlbumCoverApi, jsonData)
+}
+
+export function deleteAlbumImage(imageFileId) {
+  return delete0(imageApi.deleteAlbumImageApi + '/' + imageFileId)
+}
+
+export function deleteAlbum(albumId) {
+  return delete0(imageApi.imageAlbumApi, albumId)
+}
+
+export function getUserAlbums() {
+  return get(imageApi.imageAlbumApi)
 }
 
-export function getImagePosts() {
-  return get(imageApi.imagePostApi)
+// 获取相册
+export function getAlbumImage(albumId) {
+  return get(imageApi.albumImageApi + '/' + albumId)
 }
 
-export function getUserAlbums(userId) {
-  return get(imageApi.userAlbumApi + '?userId=' + userId)
+// 获取相册
+export function getAlbum(albumId) {
+  return get(imageApi.albumApi + '/' + albumId)
 }
 
-export function getUserAlbum(albumId) {
-  return get(imageApi.userAlbumApi1 + '/' + albumId)
+export function collectImage(jsonData) {
+  return post(imageApi.collectImageApi, jsonData)
 }
 
-export function submitAlbum(album) {
-  return post(imageApi.albumSubmitApi, album)
+export function getImages(page) {
+  return get(imageApi.imageApi + '?page=' + page)
 }

+ 1 - 1
src/components/card/AudioCard.vue

@@ -5,9 +5,9 @@
         <router-link target="_blank" :to="`/audio/${audio.audioId}`">
           <div class="imgs">
             <el-image
+              :src="audio.coverUrl"
               lazy
               fit="cover"
-              :src="audio.coverUrl"
               class="coverImg"
             />
             <span style="position: absolute; bottom: 0; left: 0; color:blue">

+ 0 - 181
src/components/card/ImageCard.vue

@@ -1,181 +0,0 @@
-<template>
-  <el-col style="padding-right: 7px; padding-left: 7px">
-    <div style="cursor: pointer" :title="video.title">
-      <el-card :body-style="{ padding: '0px' }" class="card">
-        <router-link target="_blank" :to="`/video/${video.videoId}`">
-          <div class="imgs">
-            <el-image
-              lazy
-              fit="cover"
-              :src="video.coverUrl"
-              class="coverImg"
-            />
-            <span style="position: absolute; bottom: 0; left: 0; color:white">
-              <i v-if="video.horizontal" class="el-icon-monitor" />
-              <i v-else class="el-icon-mobile-phone" />
-            </span>
-            <span style="position: absolute; bottom: 0; left: 10%; color:white">
-              <i class="el-icon-video-play">{{ getVisited(video.view) }}</i>
-            </span>
-            <span style="position: absolute; bottom: 0; left: 30%; color:white">
-              <i class="el-icon-s-comment">{{ getVisited(video.comment) }}</i>
-            </span>
-            <span style="position: absolute; bottom: 0; right: 0; color:white"> {{ video.duration }} </span>
-          </div>
-        </router-link>
-        <div style="padding: 14px">
-          <router-link target="_blank" :to="`/video/${video.videoId}`">
-            <span style="left: 0;margin-bottom: 0px;color: black;">{{ video.title | ellipsis }}</span>
-          </router-link>
-        </div>
-        <div v-if="video.user !== undefined && video.user !== null" style="padding: 14px">
-          <span style="left: 0;margin-bottom: 0px;color: black;">
-            <router-link target="_blank" :to="`/user/${video.user.userId}`"><i class="el-icon-user"> {{ video.user.screenName }} </i></router-link> · {{ convertTimestamp(video.pubDate) }}
-          </span>
-        </div>
-      </el-card>
-    </div>
-  </el-col>
-</template>
-
-<script>
-import { handleVisited } from 'assets/js/utils'
-
-export default {
-  name: 'ImageCard',
-  filters: {
-    ellipsis(value) {
-      if (!value) return ''
-      const max = 10
-      if (value.length > max) {
-        return value.slice(0, max) + '...'
-      }
-      return value
-    }
-  },
-  props: {
-    video: {
-      type: Object,
-      default: null
-    },
-    // 时间前的描述
-    dateTit: {
-      type: String,
-      default: ''
-    }
-  },
-  methods: {
-    getVisited(visited) {
-      return handleVisited(visited)
-    },
-    convertTimestamp(value) {
-      const date = new Date(value*1000)
-      var month = date.getMonth()
-      if (month < 10) {
-        if (month === 0) {
-          month = '01'
-        } else {
-          month = '0' + month
-        }
-      }
-
-      var day = date.getDay()
-      if (day < 10) {
-        day = '0' + day
-      }
-      return month + '-' + day
-    }
-  }
-}
-</script>
-
-<style scoped>
-.time {
-  font-size: 15px;
-  color: #999;
-}
-
-.bottom {
-  margin-top: 13px;
-  line-height: 12px;
-}
-
-.tit {
-  font-weight: 700;
-  font-size: 18px;
-
-  height: 50px;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  display: -webkit-box;
-  -webkit-line-clamp: 2; /*行数*/
-  -webkit-box-orient: vertical;
-}
-
-.num {
-  position: relative;
-  font-size: 15px;
-  padding-top: 9px;
-}
-
-/*处于手机屏幕时*/
-@media screen and (max-width: 768px) {
-  .tit {
-    font-weight: 600;
-    font-size: 12px;
-    height: 32px;
-  }
-  .time {
-    font-size: 10px;
-    color: #999;
-  }
-  .num {
-    font-size: 9px;
-    padding-top: 3px;
-  }
-  .bottom {
-    margin-top: 2px;
-    line-height: 7px;
-  }
-  .coverImg {
-    height: 120px !important;
-  }
-}
-
-.coverImg {
-  width: 100%;
-  height: 175px;
-  display: block;
-}
-
-.clearfix:before,
-.clearfix:after {
-  display: table;
-  content: "";
-}
-
-.clearfix:after {
-  clear: both;
-}
-
-.card {
-  margin-bottom: 20px;
-  transition: all 0.6s; /*所有属性变化在0.6秒内执行动画*/
-}
-
-/*.card:hover {
-  !*鼠标放上之后元素变成1.06倍大小*!
-  transform: scale(1.06);
-}*/
-.imgs {
-  position: relative;
-}
-.play-icon {
-  position: absolute;
-  /*top: -15px;*/
-  right: 2%;
-  bottom: 5px;
-  z-index: 7;
-  width: 40px;
-}
-</style>

+ 201 - 166
src/components/upload/EditImage.vue

@@ -9,58 +9,39 @@
         </el-card>
       </el-col>
     </el-row>
-    <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
-      <el-col :md="8" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
-        <el-card class="box-card">
-          <div slot="header" class="clearfix">
-            <span>修改相册名</span>
-            <el-button style="float: right; padding: 3px 0" type="text" @click="onUpdateAlbumName">更新</el-button>
-          </div>
-          <div class="text item">
-            <el-form ref="form" :model="form" label-width="80px">
-              <el-form-item label="相册名">
-                <el-input v-model="form.albumName" style="width: 70%; padding-right: 2px" placeholder="相册名不能超过 50 个字符" />
-              </el-form-item>
-            </el-form>
-          </div>
-        </el-card>
-      </el-col>
-      <el-col :md="8" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
-        <el-card class="box-card">
-          <div slot="header" class="clearfix">
-            <span>添加图片</span>
-            <el-button style="float: right; padding: 3px 0" type="text" @click="onAddImages">更新</el-button>
-          </div>
-          <div class="text item">
-            <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="上传的图片大小不能超过 100MB"
-              label-max-file-size-exceeded="上传的图片大小不能超过 100MB"
-              allow-file-size-validation="true"
-              max-file-size="100MB"
-              accepted-file-types="image/png, image/jpeg, image/jpg, image/gif"
-              :allow-multiple="true"
-              :max-files="100"
-              :server="server"
-              :instant-upload="true"
-              @init="handleFilePondInit"
-              @processfile="handleFilePondSuccess"
-              @removefile="handleFilePondRemove"
-            />
-          </div>
-        </el-card>
-      </el-col>
-    </el-row>
     <el-row>
-      <el-col :md="24">
+      <el-col :md="8">
+        <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
+          <el-card class="box-card">
+            <div slot="header" class="clearfix">
+              <span>添加图片</span>
+              <el-button style="float: right; padding: 3px 0" type="text" @click="onAddImages">更新</el-button>
+            </div>
+            <div class="text item">
+              <el-upload
+                action="//oss.reghao.cn/"
+                :headers="imgHeaders"
+                :data="imgData"
+                :file-list="uploadImages"
+                :multiple="true"
+                :limit="limit"
+                :with-credentials="true"
+                list-type="picture-card"
+                :before-upload="handleBeforeUpload"
+                :on-success="handleOnSuccess"
+                :on-error="handleOnError"
+                :on-remove="handleOnRemove"
+                :on-preview="handleOnPreview"
+              >
+                <i class="el-icon-plus"></i>
+              </el-upload>
+            </div>
+          </el-card>
+        </el-row>
+      </el-col>
+      <el-col :md="16">
         <div>
-          <el-col v-for="(image, index) in data.imageUrls"
+          <el-col v-for="(image, index) in data.images"
                   :key="image.thumbnailUrl"
                   :md="6" :sm="12" :xs="12"
                   style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
@@ -80,14 +61,14 @@
                     size="mini"
                     type="danger"
                     class="el-icon-delete"
-                    @click="onDeleteImage"></el-button>
+                    @click="onDeleteImage(image.imageFileId)"></el-button>
                 </el-tooltip>
                 <el-tooltip class="item" effect="dark" content="设为封面" placement="top-end">
                   <el-button
                     size="mini"
                     type="warning"
                     class="el-icon-picture-outline"
-                    @click="onSetCover"></el-button>
+                    @click="onSetCover(image.imageFileId)"></el-button>
                 </el-tooltip>
               </div>
             </el-card>
@@ -99,87 +80,66 @@
 </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 = []
-
-import { getUserAlbums, getUserAlbum, submitAlbum } from "@/api/image";
+import {getAlbumImage, deleteAlbumImage, addAlbumImage, updateAlbumCover} from "@/api/image";
+import {getServerInfo} from "@/api/file";
 
+var imageFileMap = new Map()
 export default {
   name: 'EditImage',
   data() {
     return {
+      /***********************************************************************/
+      imgHeaders: {
+        Authorization: ''
+      },
+      imgData: {
+        channelId: 6
+      },
+      dialogImageUrl: '',
+      dialogVisible: false,
+      uploadImages: [],
+      /***********************************************************************/
       // 屏幕宽度, 为了控制分页条的大小
       screenWidth: document.body.clientWidth,
-      currentPage: 1,
-      viewerOptions:{
-        movable: true,
-        fullscreen: false,
-        keyboard: true
-      },
-      user: null,
       data: null,
-      followButton: {
-        icon: 'el-icon-plus',
-        text: '关注'
-      },
-      collected: false,
-      server: {
-        url: '//oss.reghao.cn/',
-        revert: null,
-        process: {
-          headers: {
-            Authorization: '1234567890'
-          },
-          ondata(formData) {
-            formData.append('channelId', 5)
-            return formData
-          },
-          onload(response) {
-            const resp = JSON.parse(response)
-            if (resp.code === 0) {
-              const uploadId = resp.data.uploadId
-              imgFileIds.push(uploadId)
-            } else {
-              if (resp.msg != null) {
-                this.message = '上传文件出现异常,请重新上传!' + resp.msg
-              } else {
-                this.message = '上传文件出现异常,请重新上传!'
-              }
-              this.showMessage = true
-            }
-          }
-        }
-      },
-      imageList: [],
-      form: {
-        albumName: null,
-        scope: 0
-      }
+      imageCount: 0,
+      limit: 0,
     }
   },
   created() {
     document.title = '编辑相册'
 
     const albumId = this.$route.params.albumId
-    getUserAlbum(albumId).then(res => {
+    getAlbumImage(albumId).then(res => {
       if (res.code === 0) {
         const resData = res.data
         this.data = resData
+        this.imageCount = this.data.images.length
+        this.limit = 40-this.data.images.length
         this.form.albumName = resData.albumName
-        // this.form.scope = resData.scope
       }
     })
+
+    getServerInfo(this.imgData.channelId).then(res => {
+      if (res.code === 0) {
+        const resData = res.data
+        this.imgHeaders.Authorization = "Bearer " + resData.token
+      } else {
+        this.$notify({
+          title: '失败提示',
+          message: res.msg,
+          type: 'warning',
+          duration: 3000
+        })
+      }
+    }).catch(error => {
+      this.$notify({
+        title: '错误提示',
+        message: error.message,
+        type: 'warning',
+        duration: 3000
+      })
+    })
   },
   mounted() {
     // 当窗口宽度改变时获取屏幕宽度
@@ -191,9 +151,57 @@ export default {
     }
   },
   methods: {
+    /***********************************************************************/
+    handleBeforeUpload(file) {
+      const fileType = file.type
+      var isJPG = false
+      if (file.type === 'image/jpeg' || file.type === 'image/webp'
+        || file.type === 'image/gif' || file.type === 'image/png') {
+        isJPG = true
+      }
+
+      const isLt2M = file.size / 1024 / 1024 < 100
+      if (!isJPG) {
+        this.$message.error('图片只能是 jpeg/webp/gif/png 格式!')
+      }
+      if (!isLt2M) {
+        this.$message.error('图片大小不能超过 100MB!')
+      }
+      return isJPG && isLt2M
+    },
+    handleOnSuccess(res, file) {
+      if (res.code === 0) {
+        const resData = res.data
+        imageFileMap.set(file.name, resData.uploadId)
+      } else {
+        this.$notify({
+          title: '提示',
+          message: '图片上传失败,请重试!' + res.msg,
+          type: 'warning',
+          duration: 3000
+        })
+      }
+    },
+    handleOnError(err, file, fileList) {
+      const errMsg = JSON.parse(err.message)
+      this.$notify({
+        title: '图片上传失败',
+        message: errMsg.msg,
+        type: 'error',
+        duration: 3000
+      })
+    },
+    handleOnRemove(file, fileList) {
+      imageFileMap.delete(file.name)
+    },
+    handleOnPreview(file) {
+      this.dialogImageUrl = file.url;
+      this.dialogVisible = true;
+    },
+    /***********************************************************************/
     showImages(index) {
       const imageUrls = []
-      for (const i of this.data.imageUrls) {
+      for (const i of this.data.images) {
         imageUrls.push(i.originalUrl)
       }
 
@@ -207,73 +215,94 @@ export default {
         }
       })
     },
-    /***********************************************************************/
-    handleFilePondInit() {
-      // FilePond instance methods are available on `this.$refs.pond`
-    },
-    handleFilePondSuccess(error, metadata) {
-      if (error === null) {
-        return
-      }
-      console.log('图片已上传')
-      console.log(metadata)
-    },
-    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
-          })
-      }*/
-    },
-    /***********************************************************************/
-    onUpdateAlbumName() {
-      console.log('修改相册名')
-    },
-    onUpdateAlbumScope() {
-      console.log('修改相册可见范围')
-    },
     onDeleteImage(imageFileId) {
-      console.log('删除图片 ' + imageFileId)
+      this.$confirm('确定要删除图片?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        deleteAlbumImage(imageFileId).then(res => {
+          if (res.code === 0) {
+            this.$notify({
+              title: '图片已从相册中删除',
+              type: 'info',
+              duration: 3000
+            })
+            this.$router.go(0)
+          }
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '已取消'
+        })
+      })
     },
     onSetCover(imageFileId) {
-      console.log('设置封面 ' + imageFileId)
+      const jsonData = {}
+      jsonData.albumId = this.data.albumId
+      jsonData.imageFileId = imageFileId
+      updateAlbumCover(jsonData).then(resp => {
+        if (resp.code === 0) {
+          this.$notify({
+            title: '成功',
+            type: 'info',
+            duration: 1000
+          })
+        } else {
+          this.$notify({
+            title: '失败',
+            message: resp.msg,
+            type: 'warning',
+            duration: 3000
+          })
+        }
+      }).catch(error => {
+        this.$notify.error({
+          title: '错误',
+          message: error.message,
+          type: 'error',
+          duration: 3000
+        })
+      })
     },
     onReturnAlbum() {
       this.$router.push('/post/image')
     },
     onAddImages() {
-      console.log('添加图片')
-      /*this.form.imageFileIds = imgFileIds
-      submitAlbum(this.form).then(res => {
-        if (res.code === 0) {
-          this.$router.push('/post/image')
+      const jsonData = {}
+      jsonData.albumId = this.data.albumId
+      jsonData.imageFileIds = Array.from(imageFileMap.values())
+      addAlbumImage(jsonData).then(resp => {
+        if (resp.code === 0) {
+          this.$notify({
+            title: '图片已添加到相册',
+            type: 'info',
+            duration: 1000
+          })
         } else {
+          this.$notify({
+            title: '图片添加失败',
+            message: resp.msg,
+            type: 'warning',
+            duration: 3000
+          })
         }
-      })*/
+      }).catch(error => {
+        this.$notify.error({
+          title: '图片添加错误',
+          message: error.message,
+          type: 'error',
+          duration: 3000
+        })
+      })
+      this.$router.go(0)
     }
   }
 }
 </script>
 
 <style scoped>
-.movie-list {
-  padding-top: 15px;
-  padding-left: 6%;
-  padding-right: 6%;
-}
-
 /*处于手机屏幕时*/
 @media screen and (max-width: 768px){
   .movie-list {
@@ -287,9 +316,15 @@ export default {
   }
 }
 
+.movie-list {
+  padding-top: 15px;
+  padding-left: 6%;
+  padding-right: 6%;
+}
+
 .coverImg {
   width: 100%;
-  height: 320px;
+  height: 240px;
   display: block;
 }
 

+ 155 - 149
src/components/upload/PublishImage.vue

@@ -1,189 +1,195 @@
 <template>
   <el-row class="movie-list">
-    <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
-      <el-col :md="12" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
-        <el-card class="box-card">
-          <div slot="header" class="clearfix">
-            <span>上传图片文件</span>
-          </div>
-          <div class="text item">
-            <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="上传的图片大小不能超过 100MB"
-              label-max-file-size-exceeded="上传的图片大小不能超过 100MB"
-              allow-file-size-validation="true"
-              max-file-size="100MB"
-              accepted-file-types="image/png, image/jpeg, image/jpg, image/gif"
-              :allow-multiple="true"
-              :max-files="100"
-              :server="server"
-              :instant-upload="true"
-              @init="handleFilePondInit"
-              @processfile="handleFilePondSuccess"
-              @removefile="handleFilePondRemove"
-            />
-          </div>
-        </el-card>
-      </el-col>
-    </el-row>
-    <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
-      <el-col :md="12" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
-        <el-card class="box-card">
-          <div slot="header" class="clearfix">
-            <span>稿件信息</span>
-            <el-button style="float: right; padding: 3px 0" type="text" @click="onSubmit">发布</el-button>
-          </div>
-          <div class="text item">
-            <el-form ref="form" :model="form" label-width="80px">
-              <el-form-item label="相册名">
-                <el-input v-model="form.albumName" style="width: 70%; padding-right: 2px" placeholder="相册名不能超过 50 个字符" />
-              </el-form-item>
-              <el-form-item label="可见范围">
-                <el-select v-model="form.scope" placeholder="选择稿件的可见范围">
-                  <el-option label="所有人可见" value="1" />
-                  <el-option label="验证码可见" value="2" />
-                  <el-option label="VIP 可见" value="3" />
-                  <el-option label="仅自己可见" value="4" />
-                </el-select>
-              </el-form-item>
-              <el-form-item label="定时发布">
-                <el-date-picker
-                  v-model="form.scheduledPubDate"
-                  type="datetime"
-                  placeholder="选择定时发布的时间">
-                </el-date-picker>
-              </el-form-item>
-            </el-form>
-          </div>
-        </el-card>
-      </el-col>
-    </el-row>
+    <el-col :md="16" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
+      <el-card class="box-card">
+        <div slot="header" class="clearfix">
+          <span>上传图片文件</span>
+        </div>
+        <div class="text item">
+          <el-upload
+            action="//oss.reghao.cn/"
+            :headers="imgHeaders"
+            :data="imgData"
+            :file-list="uploadImages"
+            :multiple="true"
+            :limit="40"
+            :with-credentials="true"
+            list-type="picture-card"
+            :before-upload="handleBeforeUpload"
+            :on-success="handleOnSuccess"
+            :on-error="handleOnError"
+            :on-remove="handleOnRemove"
+            :on-preview="handleOnPreview"
+          >
+            <i class="el-icon-plus"></i>
+          </el-upload>
+          <el-dialog :visible.sync="dialogVisible">
+            <img width="100%" :src="dialogImageUrl" alt="">
+          </el-dialog>
+        </div>
+      </el-card>
+    </el-col>
+    <el-col :md="8" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
+      <el-card class="box-card">
+        <div slot="header" class="clearfix">
+          <span>稿件信息</span>
+          <el-button style="float: right; padding: 3px 0" type="text" @click="onSubmit('submitForm')">发布</el-button>
+        </div>
+        <div class="text item">
+          <el-form ref="submitForm" :model="submitForm" :rules="submitFormRules" label-width="80px">
+            <el-form-item label="相册名">
+              <el-input v-model="submitForm.albumName" style="width: 70%; padding-right: 2px" placeholder="相册名不能超过 50 个字符" />
+            </el-form-item>
+            <el-form-item label="可见范围">
+              <el-select v-model="submitForm.scope" placeholder="选择稿件的可见范围">
+                <el-option label="所有人可见" value="1" />
+                <el-option label="验证码可见" value="2" />
+                <el-option label="VIP 可见" value="3" />
+                <el-option label="仅自己可见" value="4" />
+              </el-select>
+            </el-form-item>
+            <el-form-item label="定时发布">
+              <el-date-picker
+                v-model="submitForm.scheduledPubDate"
+                type="datetime"
+                placeholder="选择定时发布的时间">
+              </el-date-picker>
+            </el-form-item>
+          </el-form>
+        </div>
+      </el-card>
+    </el-col>
   </el-row>
 </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'
-
 import { getServerInfo } from '@/api/file'
 import { submitAlbum } from '@/api/image'
 
-const FilePond = VueFilePond(
-  FilePondPluginFileValidateType,
-  FilePondPluginImagePreview,
-  FilePondPluginFileValidateSize
-)
-var imgFileIds = []
-
+var imageFileMap = new Map()
 export default {
   name: 'PublishImage',
-  components: { FilePond },
+  components: {},
   data() {
     return {
-      server: {
-        url: '//oss.reghao.cn/',
-        revert: null,
-        process: {
-          withCredentials: true,
-          headers: {
-            Authorization: '0123456789'
-          },
-          ondata(formData) {
-            formData.append('channelId', 6)
-            return formData
-          },
-          onload(response) {
-            const resp = JSON.parse(response)
-            if (resp.code === 0) {
-              const uploadId = resp.data.uploadId
-              imgFileIds.push(uploadId)
-            } else {
-              if (resp.msg != null) {
-                this.message = '上传文件出现异常,请重新上传!' + resp.msg
-              } else {
-                this.message = '上传文件出现异常,请重新上传!'
-              }
-              this.showMessage = true
-            }
-          }
-        }
+      /***********************************************************************/
+      imgHeaders: {
+        Authorization: ''
       },
-      imageList: [],
-      form: {
+      imgData: {
+        channelId: 6
+      },
+      dialogImageUrl: '',
+      dialogVisible: false,
+      uploadImages: [],
+      /***********************************************************************/
+      submitForm: {
+        imageFileIds: [],
         albumName: null,
         scope: "1",
         scheduledPubDate: null
+      },
+      submitFormRules: {
+        imageFileIds: [
+          { type: 'array', required: true, message: '至少上传一张图片', trigger: 'change' }
+        ]
       }
     }
   },
   created() {
-    getServerInfo(6).then(res => {
+    getServerInfo(this.imgData.channelId).then(res => {
       if (res.code === 0) {
         const resData = res.data
-        this.server.url = resData.ossUrl
-        this.server.process.headers.Authorization = "Bearer " + resData.token
+        this.imgHeaders.Authorization = "Bearer " + resData.token
       } else {
+        this.$notify({
+          title: '失败提示',
+          message: res.msg,
+          type: 'warning',
+          duration: 3000
+        })
       }
+    }).catch(error => {
+      this.$notify({
+        title: '错误提示',
+        message: error.message,
+        type: 'warning',
+        duration: 3000
+      })
     })
   },
   methods: {
-    handleFilePondInit() {
-      // FilePond instance methods are available on `this.$refs.pond`
+    /***********************************************************************/
+    handleBeforeUpload(file) {
+      const fileType = file.type
+      var isJPG = false
+      if (file.type === 'image/jpeg' || file.type === 'image/webp'
+        || file.type === 'image/gif' || file.type === 'image/png') {
+        isJPG = true
+      }
+
+      const isLt2M = file.size / 1024 / 1024 < 100
+      if (!isJPG) {
+        this.$message.error('图片只能是 jpeg/webp/gif/png 格式!')
+      }
+      if (!isLt2M) {
+        this.$message.error('图片大小不能超过 100MB!')
+      }
+      return isJPG && isLt2M
     },
-    handleFilePondSuccess(error, metadata) {
-      if (error === null) {
-        return
+    handleOnSuccess(res, file) {
+      if (res.code === 0) {
+        const resData = res.data
+        imageFileMap.set(file.name, resData.uploadId)
+      } else {
+        this.$notify({
+          title: '提示',
+          message: '图片上传失败,请重试!' + res.msg,
+          type: 'warning',
+          duration: 3000
+        })
       }
-      console.log(metadata)
     },
-    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
-          })
-      }*/
+    handleOnError(err, file, fileList) {
+      const errMsg = JSON.parse(err.message)
+      this.$notify({
+        title: '图片上传失败',
+        message: errMsg.msg,
+        type: 'error',
+        duration: 3000
+      })
     },
-    onSubmit() {
-      this.form.imageFileIds = imgFileIds
-      submitAlbum(this.form).then(res => {
-        if (res.code === 0) {
-          this.$router.push('/post/image')
-        } else {
+    handleOnRemove(file, fileList) {
+      imageFileMap.delete(file.name)
+    },
+    handleOnPreview(file) {
+      this.dialogImageUrl = file.url;
+      this.dialogVisible = true;
+    },
+    /***********************************************************************/
+    onSubmit(formName) {
+      this.$refs[formName].validate(valid => {
+        if (!valid) return false
+
+        this.submitForm.imageFileIds = Array.from(imageFileMap.values())
+        submitAlbum(this.submitForm).then(res => {
+          if (res.code === 0) {
+            this.$router.push('/post/image')
+          } else {
+            this.$notify({
+              title: '提示',
+              message: res.msg,
+              type: 'warning',
+              duration: 3000
+            })
+          }
+        }).catch(error => {
           this.$notify({
             title: '提示',
-            message: res.msg,
+            message: error.message,
             type: 'warning',
             duration: 3000
           })
-        }
-      }).catch(error => {
-        this.$notify({
-          title: '提示',
-          message: error.message,
-          type: 'warning',
-          duration: 3000
         })
       })
     }

+ 0 - 5
src/router/index.js

@@ -140,11 +140,6 @@ const routes = [
     name: 'ImageIndex',
     component: ImageIndex
   },
-  {
-    path: '/image/:id',
-    name: 'ImagePage',
-    component: ImagePage
-  },
   {
     path: '/image/album/:albumId',
     name: 'ImagePage',

+ 1 - 563
src/views/admin/AdminPost.vue

@@ -1,376 +1,18 @@
 <template>
   <el-row>
-    <el-col :md="2">
-      <el-menu
-        :default-active="this.$route.path"
-        router
-        class="el-menu-vertical-demo"
-      >
-        <el-menu-item v-for="(item,i) in navList" :key="i" :index="item.path">
-          <i :class="item.icon" />
-          <span slot="title">{{ item.name }}</span>
-        </el-menu-item>
-      </el-menu>
-    </el-col>
-    <el-col :md="22">
-      <el-row>
-        <el-tabs v-model="activeName" @tab-click='tabClick'>
-          <el-tab-pane label="视频" name="video">
-            <el-row :md="6" :sm="12" :xs="12">
-              <el-table
-                :data="dataList"
-                style="width: 100%"
-              >
-                <el-table-column
-                  type="index">
-                </el-table-column>
-                <el-table-column
-                  prop="pubDate"
-                  label="发布时间"
-                  fixed="left">
-                </el-table-column>
-                <el-table-column
-                  prop="coverUrl"
-                  label="封面"
-                  width="80">
-                  <template slot-scope="scope">
-                    <el-image :src="scope.row.coverUrl" min-width="40" height="30" />
-                  </template>
-                </el-table-column>
-                <el-table-column
-                  prop="videoId"
-                  label="视频 ID">
-                  <template slot-scope="scope">
-                    <router-link target="_blank" :to="`/video/${scope.row.videoId}`">
-                      <span>{{scope.row.videoId}}</span>
-                    </router-link>
-                  </template>
-                </el-table-column>
-                <el-table-column
-                  prop="title"
-                  label="标题">
-                </el-table-column>
-                <el-table-column
-                  prop="description"
-                  label="描述">
-                </el-table-column>
-                <el-table-column
-                  prop="scope"
-                  label="可见范围">
-                  <template slot-scope="scope">
-                    <el-button
-                      v-if="scope.row.scope === 1"
-                      size="mini"
-                    >所有人可见</el-button>
-                    <el-button
-                      v-else-if="scope.row.scope === 2"
-                      size="mini"
-                      type="success"
-                    >验证码可见</el-button>
-                    <el-button
-                      v-else-if="scope.row.scope === 3"
-                      size="mini"
-                      type="warning"
-                    ></el-button>
-                    <el-button
-                      v-else
-                      size="mini"
-                      type="danger"
-                    >本人可见</el-button>
-                  </template>
-                </el-table-column>
-                <el-table-column
-                  prop="scope"
-                  label="审核状态">
-                  <template slot-scope="scope">
-                    <el-tag v-if="scope.row.status === 1" :type="'warning'" disable-transitions>
-                      审核中
-                    </el-tag>
-                    <el-tag v-else-if="scope.row.status === 2" :type="'success'" disable-transitions>
-                      审核通过
-                    </el-tag>
-                    <el-tag v-else-if="scope.row.status === 3" :type="'danger'" disable-transitions>
-                      审核未通过
-                    </el-tag>
-                    <el-tag v-else-if="scope.row.status === 4" :type="'danger'" disable-transitions>
-                      审核未通过
-                    </el-tag>
-                    <el-tag v-else-if="scope.row.status === 5" :type="'danger'" disable-transitions>
-                      待缓存
-                    </el-tag>
-                    <el-tag v-else-if="scope.row.status === 6" :type="'danger'" disable-transitions>
-                      缓存中
-                    </el-tag>
-                    <el-tag v-else-if="scope.row.status === 7" :type="'danger'" disable-transitions>
-                      缓存失败
-                    </el-tag>
-                    <el-tag v-else :type="'danger'" disable-transitions>
-                       未知状态
-                    </el-tag>
-                  </template>
-                </el-table-column>
-                <el-table-column label="操作" width="210" fixed="right">
-                  <template slot-scope="scope">
-                    <el-button
-                      size="mini"
-                      @click="handlePreview(scope.$index, scope.row)">预览</el-button>
-                    <el-button
-                      size="mini"
-                      @click="handleCensor(scope.$index, scope.row)">审核</el-button>
-                    <el-button
-                      size="mini"
-                      @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
-                    <el-button
-                      size="mini"
-                      type="danger"
-                      @click="handleDelete(scope.$index, scope.row)">删除</el-button>
-                  </template>
-                </el-table-column>
-              </el-table>
-            </el-row>
-          </el-tab-pane>
-          <el-tab-pane label="相册" name="image">
-            <el-row :md="6" :sm="12" :xs="12">
-              <el-table
-                :data="dataList"
-                style="width: 100%"
-              >
-                <el-table-column
-                  type="index">
-                </el-table-column>
-                <el-table-column
-                  prop="coverUrl"
-                  label="相册封面"
-                  width="150">
-                  <template slot-scope="scope">
-                    <el-image :src="scope.row.coverUrl" min-width="40" height="30" />
-                  </template>
-                </el-table-column>
-                <el-table-column
-                  prop="pubDate"
-                  label="发布时间">
-                </el-table-column>
-                <el-table-column
-                  prop="albumName"
-                  label="相册名字"
-                  width="180">
-                </el-table-column>
-                <el-table-column
-                  prop="total"
-                  label="图片数量">
-                </el-table-column>
-                <el-table-column
-                  prop="scope"
-                  label="可见范围">
-                  <template slot-scope="scope">
-                    <el-tag v-if="scope.row.scope === 1" disable-transitions>
-                      全部可见
-                    </el-tag>
-                    <el-tag v-else-if="scope.row.scope === 2" :type="'success'" disable-transitions>
-                      验证码可见
-                    </el-tag>
-                    <el-tag v-else-if="scope.row.scope === 3" :type="'warning'" disable-transitions>
-                      VIP 可见
-                    </el-tag>
-                    <el-tag v-else :type="'danger'" disable-transitions>
-                      本人可见
-                    </el-tag>
-                  </template>
-                </el-table-column>
-                <el-table-column label="操作">
-                  <template slot-scope="scope">
-                    <el-button
-                      size="mini"
-                      @click="handleEditImage(scope.$index, scope.row)">编辑</el-button>
-                    <el-button
-                      size="mini"
-                      type="danger"
-                      @click="handleDeleteImage(scope.$index, scope.row)">删除</el-button>
-                  </template>
-                </el-table-column>
-              </el-table>
-            </el-row>
-          </el-tab-pane>
-          <el-tab-pane label="音频" name="audio">
-            <el-row :md="6" :sm="12" :xs="12">
-              <el-table
-                :data="dataList"
-                style="width: 100%"
-              >
-                <el-table-column
-                  type="index">
-                </el-table-column>
-                <el-table-column
-                  prop="coverUrl"
-                  label="音频封面"
-                  width="150">
-                  <template slot-scope="scope">
-                    <el-image :src="scope.row.coverUrl" min-width="40" height="30" />
-                  </template>
-                </el-table-column>
-                <el-table-column
-                  prop="pubDate"
-                  label="发布时间">
-                </el-table-column>
-                <el-table-column
-                  prop="title"
-                  label="音频名字">
-                </el-table-column>
-                <!--                <el-table-column
-                                  prop="description"
-                                  label="音频简介">
-                                </el-table-column>-->
-                <el-table-column
-                  prop="scope"
-                  label="可见范围">
-                  <template slot-scope="scope">
-                    <el-tag v-if="scope.row.scope === 1" disable-transitions>
-                      全部可见
-                    </el-tag>
-                    <el-tag v-else-if="scope.row.scope === 2" :type="'success'" disable-transitions>
-                      验证码可见
-                    </el-tag>
-                    <el-tag v-else-if="scope.row.scope === 3" :type="'warning'" disable-transitions>
-                      VIP 可见
-                    </el-tag>
-                    <el-tag v-else :type="'danger'" disable-transitions>
-                      本人可见
-                    </el-tag>
-                  </template>
-                </el-table-column>
-                <el-table-column label="操作">
-                  <template slot-scope="scope">
-                    <el-button
-                      size="mini"
-                      @click="handleEditAudio(scope.$index, scope.row)">编辑</el-button>
-                    <el-button
-                      size="mini"
-                      type="danger"
-                      @click="handleDeleteAudio(scope.$index, scope.row)">删除</el-button>
-                  </template>
-                </el-table-column>
-              </el-table>
-            </el-row>
-          </el-tab-pane>
-          <el-tab-pane label="文章" name="article">
-            <span>
-              <h4>文章稿件</h4>
-            </span>
-          </el-tab-pane>
-        </el-tabs>
-      </el-row>
-      <el-row>
-        <el-col :span="22" class="pagination">
-          <el-pagination
-            background
-            :small="screenWidth <= 768"
-            layout="prev, pager, next"
-            :page-size="pageSize"
-            :current-page="currentPage"
-            :total="totalSize"
-            @current-change="handleCurrentChange"
-            @prev-click="handleCurrentChange"
-            @next-click="handleCurrentChange"
-          />
-        </el-col>
-      </el-row>
-    </el-col>
-
-    <!-- 修改视频可见范围对话框 -->
-    <el-dialog
-      append-to-body
-      :visible.sync="showEditScopeDialog"
-      width="30%"
-      center
-    >
-      <el-card class="box-card">
-        <div slot="header" class="clearfix">
-          <span>修改视频可见范围</span>
-          <el-button style="float: right; padding: 3px 0" type="text" @click="onUpdateVideoScope">更新</el-button>
-        </div>
-        <div class="text item">
-          <el-form ref="form" :model="form" label-width="80px">
-            <el-form-item label="可见范围">
-              <el-select v-model="form.scope" placeholder="选择可见范围">
-                <el-option label="所有人可见" value="1" />
-                <el-option label="验证码可见" value="2" />
-                <el-option label="VIP 可见" value="3" />
-                <el-option label="仅自己可见" value="4" />
-              </el-select>
-            </el-form-item>
-          </el-form>
-        </div>
-      </el-card>
-    </el-dialog>
-    <!-- 视频预览对话框 -->
-    <el-dialog
-      title="预览视频"
-      append-to-body
-      :visible.sync="showPreviewDialog"
-      :before-close="handleDialogClose"
-      width="70%"
-      center
-    >
-      <template>
-        <video-preview-player :video-prop.sync="this.videoProp"/>
-      </template>
-    </el-dialog>
   </el-row>
 </template>
 
 <script>
-import VideoPreviewPlayer from 'components/VideoPreviewPlayer'
-
-import {userVideoPost, updateVideoScope, videoInfo, deleteVideo} from "@/api/video";
-import {getUserAlbums} from "@/api/image";
-import { getUserAudio } from "@/api/audio";
-
 export default {
   name: 'AdminPost',
-  components: { VideoPreviewPlayer },
+  components: {},
   data() {
     return {
-      // 屏幕宽度, 为了控制分页条的大小
-      screenWidth: document.body.clientWidth,
-      currentPage: 1,
-      pageSize: 12,
-      totalSize: 0,
-      dataList: [],
-      /*************************************************************************/
-      navList: [
-        { path: '/admin/user', name: '用户', icon: 'el-icon-user' },
-        { path: '/admin/post', name: '稿件', icon: 'el-icon-files' },
-      ],
-      activeName: 'video',
-      userId: 10001,
-      showPreviewDialog: false,
-      videoProp: null,
-      showEditScopeDialog: false,
-      form: {
-        videoId: null,
-        scope: null
-      }
     }
   },
   created() {
     document.title = "稿件管理"
-
-    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 = '文章稿件'
-    }
-
-    this.getData()
   },
   watch: {
     $route(){
@@ -378,213 +20,9 @@ export default {
     }
   },
   methods: {
-    handleCurrentChange(pageNumber) {
-      this.currentPage = pageNumber
-      this.getData()
-      // 回到顶部
-      scrollTo(0, 0)
-    },
-    handleScope(index, row) {
-      this.form.videoId = row.videoId
-      this.form.scope = row.scope
-      this.showEditScopeDialog = true
-    },
-    handleDialogClose(done) {
-      this.showPreviewDialog = false
-      this.videoProp = {
-        videoId: null,
-        play: false
-      }
-      done()
-    },
-    handlePreview(index, row) {
-      videoInfo(row.videoId).then(res => {
-        if (res.code === 0) {
-          this.showPreviewDialog = true
-          this.videoProp = {
-            videoId: res.data.videoId,
-            play: true
-          }
-        }
-      })
-    },
-    handleEdit(index, row) {
-      console.log(row.videoId);
-      const path = '/admin/edit/video/' + row.videoId
-      this.$router.push(path)
-    },
-    handleCensor(index, row) {
-      console.log('审核视频')
-    },
-    handleDelete(index, row) {
-      deleteVideo(row.videoId).then(res => {
-         if (res.code === 0) {
-           this.$notify({
-             title: '提示',
-             message: '视频稿件已删除',
-             type: 'warning',
-             duration: 3000
-           })
-           this.$router.go(0)
-         }
-      })
-    },
-    handleEditImage(index, row) {
-      console.log(row.videoId);
-      const path = '/post/edit/album/' + row.albumId
-      this.$router.push(path)
-    },
-    handleDeleteImage(index, row) {
-      console.log(row.videoId);
-    },
-    handleEditAudio(index, row) {
-      console.log(row.videoId);
-      const path = '/post/edit/audio/' + row.audioId
-      this.$router.push(path)
-    },
-    handleDeleteAudio(index, row) {
-      console.log(row.videoId);
-    },
-    tabClick(tab) {
-      this.activeName = tab.name
-      this.goToTab(this.activeName)
-    },
-    goToTab(activeName) {
-      const path = '/admin/post/' + activeName
-      if (this.$route.path === path) {
-        this.$router.go(0)
-        return
-      }
-      this.$router.push(path)
-    },
-    getData() {
-      this.dataList = []
-      if (this.activeName === 'video') {
-        userVideoPost(this.currentPage).then(res => {
-          if (res.code === 0) {
-            const resData = res.data
-            this.dataList = resData.list
-            this.totalSize = resData.totalSize
-
-            if (this.totalSize !== 0) {
-              this.showEmpty = false
-            } else {
-              this.showEmpty = true
-            }
-          } else {
-            this.$notify({
-              title: '提示',
-              message: res.msg,
-              type: 'warning',
-              duration: 3000
-            })
-          }
-        }).catch(error => {
-          this.$notify({
-            title: '提示',
-            message: error.message,
-            type: 'error',
-            duration: 3000
-          })
-        })
-      } else if (this.activeName === 'image') {
-        getUserAlbums(this.userId).then(res => {
-          if (res.code === 0) {
-            const resData = res.data
-            if (resData.length !== 0) {
-              this.showEmpty = false
-              for (const item of resData) {
-                this.dataList.push(item)
-              }
-            } else {
-              this.showEmpty = true
-            }
-          }
-        })
-      } else if (this.activeName === 'audio') {
-        this.currentPage = 1
-        this.lastId = 0
-        getUserAudio(this.userId).then(res => {
-          if (res.code === 0) {
-            const resData = res.data.list
-            if (resData.length !== 0) {
-              this.showEmpty = false
-              for (const item of resData) {
-                this.dataList.push(item)
-              }
-            } else {
-              this.showEmpty = true
-            }
-          }
-        })
-      } else if (this.activeName === 'article') {
-        this.currentPage = 1
-        this.lastId = 0
-      }
-    },
-    onUpdateVideoScope() {
-      this.showEditScopeDialog = false
-      updateVideoScope(this.form).then(res => {
-        if (res.code === 0) {
-          this.$notify({
-            title: '提示',
-            message: '视频可见范围已更新',
-            type: 'warning',
-            duration: 3000
-          })
-        }
-      }).catch(error => {
-        this.$notify({
-          title: '提示',
-          message: error.message,
-          type: 'warning',
-          duration: 3000
-        })
-      })
-    }
   }
 }
 </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>

+ 1 - 268
src/views/admin/AdminUser.vue

@@ -1,199 +1,18 @@
 <template>
   <el-row>
-    <el-col :md="2">
-      <el-menu
-        :default-active="this.$route.path"
-        router
-        class="el-menu-vertical-demo"
-      >
-        <el-menu-item v-for="(item,i) in navList" :key="i" :index="item.path">
-          <i :class="item.icon" />
-          <span slot="title">{{ item.name }}</span>
-        </el-menu-item>
-      </el-menu>
-    </el-col>
-    <el-col :md="22">
-      <el-row>
-        <el-row :md="6" :sm="12" :xs="12">
-          <el-table
-            :data="dataList"
-            style="width: 100%"
-          >
-            <el-table-column
-              type="index">
-            </el-table-column>
-            <el-table-column
-              prop="pubDate"
-              label="注册时间">
-            </el-table-column>
-            <el-table-column
-              prop="avatarUrl"
-              label="头像"
-              width="80">
-              <template slot-scope="scope">
-                <el-image :src="scope.row.avatarUrl" min-width="40" height="30" />
-              </template>
-            </el-table-column>
-            <el-table-column
-              prop="userId"
-              label="用户 ID">
-              <template slot-scope="scope">
-                <router-link target="_blank" :to="`/user/${scope.row.userId}`">
-                  <span>{{scope.row.userId}}</span>
-                </router-link>
-              </template>
-            </el-table-column>
-            <el-table-column
-              prop="screenName"
-              label="显示名">
-            </el-table-column>
-            <el-table-column
-              prop="gender"
-              label="性别">
-            </el-table-column>
-            <el-table-column
-              prop="signature"
-              label="签名">
-            </el-table-column>
-            <el-table-column
-              prop="following"
-              label="关注数">
-            </el-table-column>
-            <el-table-column
-              prop="follower"
-              label="粉丝数">
-            </el-table-column>
-            <el-table-column
-              prop="accountType"
-              label="帐号类型">
-              <template slot-scope="scope">
-                <el-tag v-if="scope.row.status === 1" :type="'warning'" disable-transitions>
-                  tnb 帐号
-                </el-tag>
-                <el-tag v-else-if="scope.row.status === 2" :type="'success'" disable-transitions>
-                  bilibili 帐号
-                </el-tag>
-                <el-tag v-else :type="'danger'" disable-transitions>
-                  其他
-                </el-tag>
-              </template>
-            </el-table-column>
-            <el-table-column
-              prop="accountType"
-              label="帐号状态">
-              <template slot-scope="scope">
-                <el-tooltip class="item" effect="dark" content="点击修改视频可见范围" placement="top-end">
-                  <el-button
-                    v-if="scope.row.scope === 1"
-                    size="mini"
-                    @click="handleScope(scope.$index, scope.row)">正常</el-button>
-                  <el-button
-                    v-else-if="scope.row.scope === 2"
-                    size="mini"
-                    type="success"
-                    @click="handleScope(scope.$index, scope.row)">封禁</el-button>
-                  <el-button
-                    v-else
-                    size="mini"
-                    type="danger"
-                    @click="handleScope(scope.$index, scope.row)">其他</el-button>
-                </el-tooltip>
-              </template>
-            </el-table-column>
-            <el-table-column label="操作" width="210">
-              <template slot-scope="scope">
-                <el-button
-                  size="mini"
-                  @click="handlePreview(scope.$index, scope.row)">预览</el-button>
-                <el-button
-                  size="mini"
-                  @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
-                <el-button
-                  size="mini"
-                  type="danger"
-                  @click="handleDelete(scope.$index, scope.row)">删除</el-button>
-              </template>
-            </el-table-column>
-          </el-table>
-        </el-row>
-      </el-row>
-      <el-row>
-        <el-col :span="22" class="pagination">
-          <el-pagination
-            background
-            :small="screenWidth <= 768"
-            hide-on-single-page
-            layout="prev, pager, next"
-            :page-size="pageSize"
-            :current-page="currentPage"
-            :total="totalSize"
-            @current-change="handleCurrentChange"
-            @prev-click="handleCurrentChange"
-            @next-click="handleCurrentChange"
-          />
-        </el-col>
-      </el-row>
-    </el-col>
-
-    <!-- 修改视频可见范围对话框 -->
-    <el-dialog
-      append-to-body
-      :visible.sync="showEditScopeDialog"
-      width="30%"
-      center
-    >
-      <el-card class="box-card">
-        <div slot="header" class="clearfix">
-          <span>修改帐号状态</span>
-          <el-button style="float: right; padding: 3px 0" type="text" @click="onUpdateVideoScope">更新</el-button>
-        </div>
-        <div class="text item">
-          <el-form ref="form" :model="form" label-width="80px">
-            <el-form-item label="可见范围">
-              <el-select v-model="form.scope" placeholder="选择可见范围">
-                <el-option label="所有人可见" value="1" />
-                <el-option label="验证码可见" value="2" />
-                <el-option label="VIP 可见" value="3" />
-                <el-option label="仅自己可见" value="4" />
-              </el-select>
-            </el-form-item>
-          </el-form>
-        </div>
-      </el-card>
-    </el-dialog>
   </el-row>
 </template>
 
 <script>
-import { getUserList } from "@/api/user";
-
 export default {
-  name: 'AdminPost',
+  name: 'AdminUser',
   components: {},
   data() {
     return {
-      // 屏幕宽度, 为了控制分页条的大小
-      screenWidth: document.body.clientWidth,
-      currentPage: 1,
-      pageSize: 12,
-      totalSize: 0,
-      dataList: [],
-      /*************************************************************************/
-      navList: [
-        { path: '/admin/user', name: '用户', icon: 'el-icon-user' },
-        { path: '/admin/post', name: '稿件', icon: 'el-icon-files' },
-      ],
-      showPreviewDialog: false,
-      showEditScopeDialog: false,
-      form: {
-        videoId: null,
-        scope: null
-      }
     }
   },
   created() {
     document.title = "用户管理"
-    this.getUserListWrapper(this.currentPage)
   },
   watch: {
     $route(){
@@ -201,95 +20,9 @@ export default {
     }
   },
   methods: {
-    handleCurrentChange(pageNumber) {
-      this.currentPage = pageNumber
-      this.getUserListWrapper(this.currentPage)
-      // 回到顶部
-      scrollTo(0, 0)
-    },
-    handleScope(index, row) {
-      this.form.videoId = row.videoId
-      this.form.scope = row.scope
-      this.showEditScopeDialog = true
-    },
-    handlePreview(index, row) {
-      console.log('预览操作')
-    },
-    handleEdit(index, row) {
-      console.log('编辑操作')
-    },
-    handleDelete(index, row) {
-      console.log('删除操作')
-    },
-    getUserListWrapper(page) {
-      getUserList(page).then(res => {
-        if (res.code === 0) {
-          this.dataList = res.data.list
-          this.totalSize = res.data.totalSize
-        } else {
-          this.$notify({
-            title: '提示',
-            message: '获取用户列表失败',
-            type: 'warning',
-            duration: 3000
-          })
-        }
-      }).catch(error => {
-        this.$notify({
-          title: '提示',
-          message: error.message,
-          type: 'warning',
-          duration: 3000
-        })
-      })
-    },
-    onUpdateVideoScope() {
-      this.showEditScopeDialog = false
-      console.log('更新帐号状态')
-    }
   }
 }
 </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>

+ 125 - 26
src/views/home/Image.vue

@@ -4,9 +4,35 @@
     <el-row id="movie-list">
       <!--电影列表-->
       <el-col :md="24">
-        <el-col v-for="(video, index) in videoList" :key="index" :md="6" :sm="12" :xs="12">
-          <image-card :video="video" />
-        </el-col>
+        <div>
+          <el-col v-for="(image, index) in dataList"
+                  :key="image.thumbnailUrl"
+                  :md="6" :sm="12" :xs="12"
+                  style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
+            <el-card :body-style="{ padding: '0px' }" class="card">
+              <div class="imgs">
+                <el-image
+                  lazy
+                  fit="cover"
+                  class="coverImg"
+                  :src="image.thumbnailUrl"
+                  @click="showImages(index)">
+                </el-image>
+              </div>
+              <div style="padding: 14px;">
+                <span style="position: relative; bottom: 0; left: 0%; color:green">
+                  <i v-if="image.collected" class='el-icon-star-on' @click="collectItem(image)"/>
+                  <i v-else class='el-icon-star-off' @click="collectItem(image)"/>
+                </span>
+                <router-link target="_blank" :to="`/image/album/${image.albumId}`">
+                  <span style="position: relative; bottom: 0; left: 0; color:blue">
+                    {{ image.albumName | ellipsis }}
+                  </span>
+                </router-link>
+              </div>
+            </el-card>
+          </el-col>
+        </div>
         <!--
           分页按钮:
           page-size:每页显示条数
@@ -27,7 +53,7 @@
         </el-col>
       </el-col>
     </el-row>
-    <el-row v-if="showEmpty" class="not-result">
+    <el-row v-if="dataList.length === 0" class="not-result">
       <el-col :span="12" :offset="6">
         <img src="@/assets/img/icon/not-result.png">
         <div>没有图片数据</div>
@@ -37,12 +63,21 @@
 </template>
 
 <script>
-import ImageCard from 'components/card/ImageCard'
-import { videoRecommend } from '@/api/video'
+import {collectImage, getImages} from '@/api/image'
 
 export default {
   name: 'Image',
-  components: { ImageCard },
+  components: {},
+  filters: {
+    ellipsis(value) {
+      if (!value) return ''
+      const max = 10
+      if (value.length > max) {
+        return value.slice(0, max) + '...'
+      }
+      return value
+    }
+  },
   data() {
     return {
       // 屏幕宽度, 为了控制分页条的大小
@@ -51,23 +86,32 @@ export default {
       pageSize: 12,
       totalPages: 0,
       totalSize: 0,
-      videoList: [],
-      showEmpty: true
+      showEmpty: true,
+      dataList: [],
     }
   },
   created() {
     document.title = '图片'
 
-    this.currentPage = 1
-    videoRecommend(this.currentPage).then(res => {
-      if (res.code === 0) {
-        const resData = res.data
-        this.videoList = resData.list
+    getImages(this.currentPage).then(resp => {
+      if (resp.code === 0) {
+        this.dataList = resp.data
+      } else {
+        this.$notify({
+          title: '获取数据失败',
+          message: res.msg,
+          type: 'warning',
+          duration: 3000
+        })
       }
+    }).catch(error => {
+      this.$notify({
+        title: '获取数据错误',
+        message: error.message,
+        type: 'error',
+        duration: 3000
+      })
     })
-    // console.log(this.$store.state.videos);
-    // 当页面挂载时,页码变为1
-    this.$store.commit('updatePage', 1)
   },
   mounted() {
     // 当窗口宽度改变时获取屏幕宽度
@@ -85,18 +129,82 @@ export default {
       this.$store.dispatch('getPageBean')
       // 回到顶部
       scrollTo(0, 0)
+    },
+    showImages(index) {
+      const imageUrls = []
+      for (const i of this.dataList) {
+        imageUrls.push(i.originalUrl)
+      }
+
+      this.$viewerApi({
+        images: imageUrls,
+        options: {
+          initialViewIndex: index,
+          movable: true,
+          fullscreen: false,
+          keyboard: true
+        }
+      })
+    },
+    collectItem(image) {
+      const jsonData = {}
+      jsonData.contentId = image.imageFileId
+      if (image.collected) {
+        jsonData.collect = false
+        collectImage(jsonData).then(res => {
+          if (res.code === 0) {
+            this.$notify({
+              title: '取消收藏图片',
+              type: 'info',
+              duration: 3000
+            })
+            image.collected = false
+          }
+        })
+      } else {
+        jsonData.collect = true
+        collectImage(jsonData).then(res => {
+          if (res.code === 0) {
+            this.$notify({
+              title: '图片已收藏',
+              type: 'info',
+              duration: 3000
+            })
+            image.collected = true
+          }
+        })
+      }
     }
   }
 }
 </script>
 
 <style scoped>
+/*处于手机屏幕时*/
+@media screen and (max-width: 768px){
+  #movie-list {
+    padding-top: 8px;
+    padding-left: 0.5%;
+    padding-right: 0.5%;
+  }
+
+  .coverImg {
+    height: 120px !important;
+  }
+}
+
 #movie-list {
   padding-top: 15px;
   padding-left: 6%;
   padding-right: 6%;
 }
 
+.coverImg {
+  width: 100%;
+  height: 320px;
+  display: block;
+}
+
 .not-result {
   padding-top: 100px;
   padding-bottom: 100px;
@@ -107,13 +215,4 @@ export default {
   text-align: center;
   padding: 10px;
 }
-
-/*处于手机屏幕时*/
-@media screen and (max-width: 768px){
-  #movie-list {
-    padding-top: 8px;
-    padding-left: 0.5%;
-    padding-right: 0.5%;
-  }
-}
 </style>

+ 57 - 45
src/views/home/ImagePage.vue

@@ -44,9 +44,7 @@
     <el-row>
       <el-col :md="24" class="movie-list">
         <div>
-          <el-col v-for="(image, index) in data.imageUrls" :key="image.thumbnailUrl"
-                  :md="6" :sm="12" :xs="12"
-                  style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
+          <el-col v-for="(image, index) in data.images" :key="image.thumbnailUrl" :md="6" :sm="12" :xs="12" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
             <el-card :body-style="{ padding: '0px' }" class="card">
               <div class="imgs">
                 <el-image
@@ -59,7 +57,8 @@
               </div>
               <div style="padding: 14px;">
                 <span>
-                  <i :class=collectedIcon @click="collectItem"/>
+                  <i v-if="image.collected" class='el-icon-star-on' @click="collectItem(image)"/>
+                  <i v-else class='el-icon-star-off' @click="collectItem(image)"/>
                 </span>
               </div>
             </el-card>
@@ -71,39 +70,34 @@
 </template>
 
 <script>
-import { getUserAlbums, getUserAlbum } from "@/api/image";
-import {followUser, getUserInfo, unfollowUser} from "@/api/user";
+import { followUser, getUserInfo, unfollowUser } from "@/api/user";
+import { getAlbum, collectImage } from "@/api/image";
 
 export default {
   name: 'ImagePage',
+  components: {},
   data() {
     return {
       // 屏幕宽度, 为了控制分页条的大小
       screenWidth: document.body.clientWidth,
       currentPage: 1,
-      viewerOptions:{
-        movable: true,
-        fullscreen: false,
-        keyboard: true
-      },
       user: null,
-      data: null,
       followButton: {
         icon: 'el-icon-plus',
         text: '关注'
       },
-      collected: false,
-      collectedIcon: 'el-icon-star-off'
+      data: null,
+      dataList: [],
     }
   },
   created() {
     const albumId = this.$route.params.albumId
-    getUserAlbum(albumId).then(res => {
+    getAlbum(albumId).then(res => {
       if (res.code === 0) {
         const resData = res.data
-        this.data = resData
         document.title = '相册 - ' + resData.albumName
 
+        this.data = resData
         this.userId = resData.userId
         getUserInfo(this.userId).then(res => {
           if (res.code === 0) {
@@ -123,9 +117,29 @@ export default {
     }
   },
   methods: {
+    followUser(userId) {
+      if (this.followButton.text === '关注') {
+        followUser(userId).then(res => {
+          if (res.code === 0) {
+            this.followButton.text = '已关注'
+            this.followButton.icon = 'el-icon-check'
+          }
+        })
+      } else {
+        unfollowUser(userId).then(res => {
+          if (res.code === 0) {
+            this.followButton.text = '关注'
+            this.followButton.icon = 'el-icon-plus'
+          }
+        })
+      }
+    },
+    sendMessage(userId) {
+      console.log('发送消息')
+    },
     showImages(index) {
       const imageUrls = []
-      for (const i of this.data.imageUrls) {
+      for (const i of this.data.images) {
         imageUrls.push(i.originalUrl)
       }
 
@@ -139,48 +153,40 @@ export default {
         }
       })
     },
-    followUser(userId) {
-      if (this.followButton.text === '关注') {
-        followUser(userId).then(res => {
+    collectItem(image) {
+      const jsonData = {}
+      jsonData.contentId = image.imageFileId
+      if (image.collected) {
+        jsonData.collect = false
+        collectImage(jsonData).then(res => {
           if (res.code === 0) {
-            this.followButton.text = '已关注'
-            this.followButton.icon = 'el-icon-check'
+            this.$notify({
+              title: '取消收藏图片',
+              type: 'info',
+              duration: 3000
+            })
+            image.collected = false
           }
         })
       } else {
-        unfollowUser(userId).then(res => {
+        jsonData.collect = true
+        collectImage(jsonData).then(res => {
           if (res.code === 0) {
-            this.followButton.text = '关注'
-            this.followButton.icon = 'el-icon-plus'
+            this.$notify({
+              title: '图片已收藏',
+              type: 'info',
+              duration: 3000
+            })
+            image.collected = true
           }
         })
       }
-    },
-    sendMessage(userId) {
-      console.log('发送消息')
-    },
-    collectItem() {
-      if (this.collected) {
-        console.log('取消收藏图片')
-        this.collected = false
-        this.collectedIcon = 'el-icon-star-off'
-      } else {
-        console.log('收藏图片')
-        this.collected = true
-        this.collectedIcon = 'el-icon-star-on'
-      }
     }
   }
 }
 </script>
 
 <style scoped>
-.movie-list {
-  padding-top: 15px;
-  padding-left: 6%;
-  padding-right: 6%;
-}
-
 /*处于手机屏幕时*/
 @media screen and (max-width: 768px){
   .movie-list {
@@ -194,6 +200,12 @@ export default {
   }
 }
 
+.movie-list {
+  padding-top: 15px;
+  padding-left: 6%;
+  padding-right: 6%;
+}
+
 .coverImg {
   width: 100%;
   height: 320px;

+ 61 - 13
src/views/post/ImagePost.vue

@@ -13,7 +13,11 @@
           label="相册封面"
           width="90">
           <template slot-scope="scope">
-            <el-image :src="scope.row.coverUrl" min-width="30" height="20" />
+            <el-image
+              lazy
+              fit="cover"
+              class="coverImg"
+              :src="scope.row.coverUrl" />
           </template>
         </el-table-column>
         <el-table-column
@@ -24,6 +28,11 @@
           prop="albumName"
           label="相册名字"
           width="180">
+          <template slot-scope="scope">
+            <router-link target="_blank" :to="`/image/album/${scope.row.albumId}`">
+              <span>{{scope.row.albumName}}</span>
+            </router-link>
+          </template>
         </el-table-column>
         <el-table-column
           prop="total"
@@ -96,7 +105,7 @@
 </template>
 
 <script>
-import {updateVideoScope, videoInfo, deleteVideo} from "@/api/video";
+import { updateAlbumScope, deleteAlbum } from "@/api/image";
 
 export default {
   name: 'ImagePost',
@@ -129,21 +138,31 @@ export default {
       this.$router.push(path)
     },
     handleDelete(index, row) {
-      deleteVideo(row.videoId).then(res => {
-         if (res.code === 0) {
-           this.$notify({
-             title: '提示',
-             message: '相册稿件已删除',
-             type: 'warning',
-             duration: 3000
-           })
-           this.$router.go(0)
-         }
+      this.$confirm('确定要删除 ' + row.albumName + ' 相册?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        deleteAlbum(row.albumId).then(res => {
+          if (res.code === 0) {
+            this.$notify({
+              title: '相册稿件已删除',
+              type: 'warning',
+              duration: 3000
+            })
+            //this.$router.go(0)
+          }
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '已取消'
+        })
       })
     },
     onUpdateScope() {
       this.showEditScopeDialog = false
-      updateVideoScope(this.form).then(res => {
+      updateAlbumScope(this.form).then(res => {
         if (res.code === 0) {
           this.$notify({
             title: '提示',
@@ -166,4 +185,33 @@ export default {
 </script>
 
 <style>
+/*处于手机屏幕时*/
+@media screen and (max-width: 768px) {
+  .tit {
+    font-weight: 600;
+    font-size: 12px;
+    height: 32px;
+  }
+  .time {
+    font-size: 10px;
+    color: #999;
+  }
+  .num {
+    font-size: 9px;
+    padding-top: 3px;
+  }
+  .bottom {
+    margin-top: 2px;
+    line-height: 7px;
+  }
+  .coverImg {
+    height: 120px !important;
+  }
+}
+
+.coverImg {
+  width: 100%;
+  height: 90px;
+  display: block;
+}
 </style>

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

@@ -138,7 +138,7 @@ import ImageAlbumCard from '@/components/card/ImageAlbumCard'
 import AudioCard from '@/components/card/AudioCard'
 import ArticleCard from 'components/card/ArticleCard'
 
-import { getUserInfo, getUserFollowing, getUserFollower, checkRelation, followUser, unfollowUser } from "@/api/user";
+import { getUserInfo, checkRelation, followUser, unfollowUser } from "@/api/user";
 import { getUserContentData, userVideoCard } from "@/api/video";
 import { getUserAlbums } from "@/api/image";
 import { getUserAudio } from "@/api/audio";