reghao 3 年之前
父節點
當前提交
d939069bde

+ 11 - 2
src/api/user/user.js

@@ -4,6 +4,7 @@ const userApi = {
   myInfoApi: '/api/user/info/my',
   userInfoApi: '/api/user/info',
   vipPlanApi: '/api/user/vip/plan',
+  vipOrderApi: '/api/user/vip/order',
   vipPayApi: '/api/user/vip/pay'
 }
 
@@ -19,6 +20,14 @@ export function getVipPlan() {
   return $axios.get(userApi.vipPlanApi)
 }
 
-export function payVip(planId) {
-  return $axios.post(userApi.vipPayApi + '/' + planId)
+export function getVipOrder() {
+  return $axios.get(userApi.vipOrderApi)
+}
+
+export function createVipOrder(planId) {
+  return $axios.post(userApi.vipOrderApi + '/' + planId)
+}
+
+export function payVip(orderId) {
+  return $axios.post(userApi.vipPayApi + '/' + orderId)
 }

+ 11 - 11
src/components/TempForm.vue

@@ -68,33 +68,33 @@ export default {
   props: {
     placeholder: {
       type: String,
-      default: '输入评论...',
+      default: '输入评论...'
     },
     id: {
       type: [String, Number],
-      default: 'comment-root',
+      default: 'comment-root'
     },
     className: {
       type: String,
-      default: '',
+      default: ''
     },
     comment: {
       type: Object,
-      default: () => {},
-    },
+      default: () => {}
+    }
   },
   data() {
     return {
       focus: false, // * 聚焦状态
       value: '', // * 输入框值
-      imgStr: '', // * 粘贴的图片DOM字符串
+      imgStr: '' // * 粘贴的图片DOM字符串
     }
   },
   computed: {
     // 是否为顶部评论表单
     isRoot() {
       return this.id === 'comment-root'
-    },
+    }
   },
   mounted() {
     const richInput = this.$refs['rich-input']
@@ -134,7 +134,7 @@ export default {
         createAt: new Date().getTime(),
         callback: () => {
           this.isRoot ? this.reset() : this.close()
-        },
+        }
       }
 
       this.$emit('form-submit', data)
@@ -244,7 +244,7 @@ export default {
           '>': '>',
           '&': '&',
           '"': '"',
-          "'": ''',
+          "'": '''
         }[c]
       })
     },
@@ -258,8 +258,8 @@ export default {
     // 关闭
     close() {
       this.$emit('form-delete', this.id)
-    },
-  },
+    }
+  }
 }
 </script>
 

+ 4 - 7
src/components/mobile-login-form.vue → src/components/login-form-mobile.vue

@@ -68,10 +68,6 @@ export default {
         captchaCode: null,
         r: null,
         plat: 'web'
-      },
-      getVerifyCode1: {
-        notifyType: null,
-        receiver: null
       }
     }
   },
@@ -103,9 +99,10 @@ export default {
       })
     },
     getVerifyCode() {
-      this.getVerifyCode1.receiver = this.userLogin.username
-      this.getVerifyCode1.notifyType = 1
-      getVerifyCode(this.getVerifyCode1)
+      const verifyCodeReq = {}
+      verifyCodeReq.receiver = this.userLogin.username
+      verifyCodeReq.notifyType = 2
+      getVerifyCode(verifyCodeReq)
         .then(res => {
           if (res.code === 0) {
             alert(res.msg)

+ 0 - 0
src/components/login-form.vue → src/components/login-form-password.vue


+ 193 - 160
src/components/player/player.vue

@@ -1,5 +1,64 @@
 <template>
-  <div id="dplayer" ref="dplayer" />
+  <div id="dplayer" ref="dplayer">
+    <v-dialog
+      v-model="permissionDialog"
+      max-width="290"
+    >
+      <v-card>
+        <v-card-title class="headline">VIP 观看</v-card-title>
+        <v-card-text>
+          <span>您还不是 VIP, 本视频仅供 VIP 观看</span>
+        </v-card-text>
+
+        <v-card-actions>
+          <v-spacer />
+          <v-btn
+            color="green darken-1"
+            text
+            @click="gotoHomePage"
+          >
+            好的呢
+          </v-btn>
+          <v-btn
+            color="green darken-1"
+            text
+            @click="gotoVipPage"
+          >
+            成为 VIP
+          </v-btn>
+        </v-card-actions>
+      </v-card>
+    </v-dialog>
+    <v-dialog
+      v-model="authCodeDialog"
+      max-width="290"
+    >
+      <v-form
+        ref="form"
+        lazy-validation
+      >
+        <v-text-field
+          v-model="authCode"
+          label="验证码"
+          required
+        />
+        <v-btn
+          color="success"
+          class="mr-4"
+          @click="submitAuthCode"
+        >
+          提交
+        </v-btn>
+        <v-btn
+          color="error"
+          class="mr-4"
+          @click="cancelSubmitAuthCode"
+        >
+          取消
+        </v-btn>
+      </v-form>
+    </v-dialog>
+  </div>
 </template>
 
 <script>
@@ -12,9 +71,9 @@ const DPlayer = require('dplayer')
 export default {
   name: 'Play',
   props: {
-    videoCover: {
-      type: String,
-      default: () => ''
+    videoProp: {
+      type: Object,
+      default: () => null
     }
   },
   data() {
@@ -23,45 +82,91 @@ export default {
       dashjs,
       flv,
       DPlayer,
-      userId: 0,
-      videoId: '',
-      playRecord: null
+      userPermission: {
+        userId: -1,
+        vip: false
+      },
+      userId: -1,
+      playRecord: null,
+      getUrl: false,
+      permissionDialog: false,
+      authCodeDialog: false,
+      authCode: null
     }
   },
-  mounted() {
+  created() {
     const userInfo = this.$store.state.user.userInfo
-    if (userInfo != null) {
-      this.userId = userInfo.userId
+    if (userInfo !== null) {
+      this.userPermission.userId = userInfo.userId
+      this.userPermission.vip = userInfo.vip
     }
 
-    this.videoId = this.$route.params.id
-    videoUrl(this.$route.params.id)
-      .then(res => {
-        if (res.code === 0) {
-          const urlType = res.data.type
-          if (urlType === 'mp4') {
-            const urls = res.data.urls
-            for (const url of urls) {
-              url.type = 'normal'
+    const vidScope = this.videoProp.scope
+    if (vidScope === 1) {
+      this.getUrl = true
+    } else if (vidScope === 2) {
+      if (this.userPermission.vip) {
+        this.getUrl = true
+      } else {
+        this.permissionDialog = true
+      }
+    } else if (vidScope === 3) {
+      this.authCodeDialog = true
+    } else if (vidScope === 4) {
+      alert('私有视频, 只有本人可以观看')
+    }
+  },
+  mounted() {
+    const videoId = this.videoProp.videoId
+    if (this.getUrl) {
+      this.getVideoUrl(videoId)
+      /*      videoUrl(videoId)
+        .then(res => {
+          if (res.code === 0) {
+            const urlType = res.data.type
+            if (urlType === 'mp4') {
+              const urls = res.data.urls
+              for (const url of urls) {
+                url.type = 'normal'
+              }
+              this.initMp4Player(this.userPermission.userId, videoId, this.videoProp.coverUrl, urls)
+            } else if (urlType === 'flv') {
+              // this.initFlvPlayer(videoId, coverUrl, urls)
+            } else {
+              alert('url 类型无法识别')
             }
-            this.initMp4Player(this.userId, this.videoId, this.videoCover, urls)
-          } else if (urlType === 'hls') {
-            // this.initHlsPlayer(this.videoId, coverUrl, urls)
-          } else if (urlType === 'dash') {
-            // this.initDashPlayer(this.videoId, coverUrl, urls)
-          } else if (urlType === 'flv') {
-            // this.initFlvPlayer(this.videoId, coverUrl, urls)
           } else {
-            console.log('无法识别 url 类型')
+            console.error(res.msg)
           }
-        } else {
-          console.error(res.msg)
-        }
-      }).catch(error => {
-        console.error(error.message)
-      })
+        }).catch(error => {
+          console.error(error.message)
+        })*/
+    }
   },
   methods: {
+    getVideoUrl(videoId) {
+      videoUrl(videoId)
+        .then(res => {
+          if (res.code === 0) {
+            const urlType = res.data.type
+            if (urlType === 'mp4') {
+              const urls = res.data.urls
+              for (const url of urls) {
+                url.type = 'normal'
+              }
+              this.initMp4Player(this.userPermission.userId, videoId, this.videoProp.coverUrl, urls)
+            } else if (urlType === 'flv') {
+              // this.initFlvPlayer(videoId, coverUrl, urls)
+            } else {
+              alert('url 类型无法识别')
+            }
+          } else {
+            console.error(res.msg)
+          }
+        }).catch(error => {
+          console.error(error.message)
+        })
+    },
     // TODO 获取弹幕配置,将 videoUrl 作为本函数的回调
     danmakuConfig() {
     },
@@ -83,7 +188,7 @@ export default {
         })
     },
     initMp4Player(userId, videoId, coverUrl, urls) {
-      const player = new DPlayer({
+      new DPlayer({
         container: document.querySelector('#dplayer'),
         lang: 'zh-cn',
         logo: '/logo.png',
@@ -107,11 +212,11 @@ export default {
         }
       })
 
-      if (userId !== 0) {
+      /* if (userId !== 0) {
         console.log('初始化 playRecord')
         this.playRecord = {
-          'userId': this.userId,
-          'videoId': this.videoId,
+          'userId': this.userPermission.userId,
+          'videoId': videoId,
           'currentTime': 0.0
         }
       }
@@ -119,7 +224,7 @@ export default {
       // 跳转到指定秒
       // dp.seek(100)
       player.on('play', function() {
-        console.log('mp4Player 开始播放事件' + this.userId)
+        console.log('mp4Player 开始播放事件' + this.userPermission.userId)
         console.log(this.playRecord)
         if (this.playRecord == null) {
           return
@@ -202,10 +307,30 @@ export default {
             })
         }
         i++
+      })*/
+    },
+    initFlvPlayer(videoId, coverUrl, videoUrl) {
+      new DPlayer({
+        container: document.getElementById('dplayer'),
+        video: {
+          url: videoUrl,
+          type: 'flv'
+        },
+        pluginOptions: {
+          flv: {
+            // refer to https://github.com/bilibili/flv.js/blob/master/docs/api.md#flvjscreateplayer
+            mediaDataSource: {
+              // mediaDataSource config
+            },
+            config: {
+              // config
+            }
+          }
+        }
       })
     },
     initHlsPlayer(videoId, coverUrl, videoUrl) {
-      const player = new DPlayer({
+      new DPlayer({
         container: document.querySelector('#dplayer'),
         lang: 'zh-cn',
         autoplay: false,
@@ -221,142 +346,50 @@ export default {
           maximum: 10000,
           api: '//api.reghao.cn/api/media/danmaku/',
           token: 'bili',
-          user: this.userId,
+          user: this.userPermission.userId,
           videoId: videoId,
           bottom: '15%',
           unlimited: true
         }
       })
-
-      player.on('play', function() {
-        if (this.playRecord == null) {
-          return
-        }
-
-        this.playRecord.currentTime = player.video.currentTime
-        submitPlayRecord(this.playRecord)
-          .then(res => {
-          }).catch(error => {
-            console.error(error.message)
-          })
-      })
-
-      player.on('pause', function() {
-        if (this.playRecord == null) {
-          return
-        }
-
-        this.playRecord.currentTime = player.video.currentTime
-        submitPlayRecord(this.playRecord)
-          .then(res => {
-          }).catch(error => {
-            console.error(error.message)
-          })
-      })
-
-      player.on('ended', function() {
-        // TODO 当前视频播放完成后判断是否继续播放相关推荐中的视频
-        if (this.playRecord == null) {
-          return
-        }
-
-        this.playRecord.currentTime = player.video.currentTime
-        submitPlayRecord(this.playRecord)
-          .then(res => {
-          }).catch(error => {
-            console.error(error.message)
-          })
-      })
-
-      player.on('seeking', function() {
-        if (this.playRecord == null) {
-          return
-        }
-
-        this.playRecord.currentTime = player.video.currentTime
-        submitPlayRecord(this.playRecord)
-          .then(res => {
-          }).catch(error => {
-            console.error(error.message)
-          })
-      })
-
-      player.on('seeked', function() {
-        if (this.playRecord == null) {
-          return
-        }
-
-        this.playRecord.currentTime = player.video.currentTime
-        submitPlayRecord(this.playRecord)
-          .then(res => {
-          }).catch(error => {
-            console.error(error.message)
-          })
-      })
-
-      var i = 0
-      player.on('progress', function() {
-        console.log('i = ' + i)
-        if (i % 5 === 0) {
-          if (this.playRecord == null) {
-            return
-          }
-
-          this.playRecord.currentTime = player.video.currentTime
-          submitPlayRecord(this.playRecord)
-            .then(res => {
-            }).catch(error => {
-              console.error(error.message)
-            })
-        }
-        i++
-      })
     },
     initDashPlayer(videoId, coverUrl, videoUrl) {
-      console.log('初始化 dash 播放器')
-      const player = new DPlayer({
+      new DPlayer({
         container: document.getElementById('dplayer'),
         video: {
           url: videoUrl,
           type: 'dash'
         }
       })
-      console.log('dash 播放器初始化完成')
-
-      player.on('play', function() {
-        if (this.playRecord == null) {
-          return
-        }
+    },
+    gotoHomePage() {
+      this.permissionDialog = false
+      if (this.$route.path === '/') {
+        return
+      }
+      this.$router.push('/')
+    },
+    gotoVipPage() {
+      this.permissionDialog = false
+      if (this.$route.path === '/vip/plan') {
+        return
+      }
+      this.$router.push('/vip/plan')
+    },
+    submitAuthCode() {
+      this.authCodeDialog = false
+      console.log('发送视频认证码')
+      console.log(this.videoProp.videoId)
+      console.log(this.authCode)
 
-        this.playRecord.currentTime = player.video.currentTime
-        submitPlayRecord(this.playRecord)
-          .then(res => {
-          }).catch(error => {
-            console.error(error.message)
-          })
-      })
+      this.getVideoUrl(this.videoProp.videoId)
     },
-    initFlvPlayer(videoId, coverUrl, videoUrl) {
-      console.log('初始化 flv 播放器')
-      const dp = new DPlayer({
-        container: document.getElementById('dplayer'),
-        video: {
-          url: videoUrl,
-          type: 'flv'
-        },
-        pluginOptions: {
-          flv: {
-            // refer to https://github.com/bilibili/flv.js/blob/master/docs/api.md#flvjscreateplayer
-            mediaDataSource: {
-              // mediaDataSource config
-            },
-            config: {
-              // config
-            }
-          }
-        }
-      })
-      console.log(dp.plugins.flv) // flv 实例
+    cancelSubmitAuthCode() {
+      this.authCodeDialog = false
+      if (this.$route.path === '/') {
+        return
+      }
+      this.$router.push('/')
     }
   }
 }

+ 4 - 7
src/components/register-from.vue → src/components/register-form.vue

@@ -96,10 +96,6 @@ export default {
         regVerifyCode: '',
         captchaCode: '',
         r: ''
-      },
-      verifyCode: {
-        type: '',
-        receiver: ''
       }
     }
   },
@@ -194,9 +190,10 @@ export default {
         return
       }
 
-      this.verifyCode.receiver = email
-      this.verifyCode.type = 1
-      getVerifyCode(this.verifyCode)
+      const verifyCodeReq = {}
+      verifyCodeReq.receiver = email
+      verifyCodeReq.notifyType = 1
+      getVerifyCode(verifyCodeReq)
         .then(res => {
           if (res.code === 0) {
             alert(res.msg)

+ 1 - 1
src/components/upload/filepond-image.vue

@@ -84,7 +84,7 @@ export default {
       if (error === null) {
         const file = metadata.file
         const uploadId = this.imgMap[file.name]
-        fetch('http://file.reghao.cn/api/file/rm/' + uploadId, {
+        fetch('//file.reghao.cn/api/file/rm/' + uploadId, {
           headers: {
             'Authorization': this.$store.getters.token
           },

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

@@ -38,7 +38,7 @@ export default {
     return {
       myFiles: [],
       server: {
-        url: 'http://file.reghao.cn' + '/api/file/upload/video',
+        url: '//file.reghao.cn' + '/api/file/upload/video',
         timeout: 600_000,
         revert: null,
         process: {

+ 124 - 97
src/router/index.js

@@ -78,7 +78,7 @@ const routes = [
           },
           {
             path: '/studio/admin/userlist',
-            name: 'Examine',
+            name: 'UserList',
             component: () => import('@/views/admin/user-list.vue'),
             meta: {
               title: '用户列表',
@@ -87,7 +87,7 @@ const routes = [
           },
           {
             path: '/studio/admin/websetting',
-            name: 'Examine',
+            name: 'WebSetting',
             component: () => import('@/views/admin/web-setting.vue'),
             meta: {
               title: '网页设置',
@@ -96,7 +96,7 @@ const routes = [
           },
           {
             path: '/studio/admin/category',
-            name: 'Examine',
+            name: 'Category',
             component: () => import('@/views/admin/category.vue'),
             meta: {
               title: '分区设置',
@@ -122,7 +122,7 @@ const routes = [
         children: [
           {
             path: '/user/home',
-            name: 'UserHome',
+            name: 'MyHome',
             component: () => import('@/views/user/home.vue'),
             meta: {
               title: '个人中心',
@@ -175,93 +175,41 @@ const routes = [
           }
         ]
       },
-      /*
-      {
-        path: '/user',
-        name: 'User',
-        component: () => import('@/views/user/index.vue')
-      },
       {
-          path: '/user/studio',
-          name: 'StudioIndex',
-          component: () => import('@/views/studio/index.vue'),
-          meta: {
-            title: '个人中心',
-            requireAuth: true
-          }
-        },
-        {
-          path: '/user/upload',
-          name: 'Upload',
-          component: () => import('@/views/studio/upload.vue'),
-          meta: {
-            title: '投稿',
-            requireAuth: true
-          }
-        },
-        {
-          path: '/user/post',
-          name: 'Post',
-          component: () => import('@/views/studio/post.vue'),
-          meta: {
-            title: '稿件列表',
-            requireAuth: true
-          }
-        },
-        {
-          path: '/user/comment',
-          name: 'Comment',
-          component: () => import('@/views/studio/comment.vue'),
-          meta: {
-            title: '评论',
-            requireAuth: true
-          }
-        },
-        {
-          path: '/user/admin/invitation',
-          name: 'invitation',
-          component: () => import('@/views/admin/invitation.vue'),
-          meta: {
-            title: '邀请码',
-            requireAuth: true
-          }
-        },
-        {
-          path: '/user/admin/examine',
-          name: 'Examine',
-          component: () => import('@/views/admin/examine.vue'),
-          meta: {
-            title: '审核视频',
-            requireAuth: true
-          }
-        },
-        {
-          path: '/user/admin/userlist',
-          name: 'Examine',
-          component: () => import('@/views/admin/user-list.vue'),
-          meta: {
-            title: '用户列表',
-            requireAuth: true
-          }
-        },
-        {
-          path: '/user/admin/websetting',
-          name: 'Examine',
-          component: () => import('@/views/admin/web-setting.vue'),
-          meta: {
-            title: '网页设置',
-            requireAuth: true
-          }
+        path: '/vip',
+        name: 'VipCenter',
+        component: () => import('@/views/vip/index.vue'),
+        meta: {
+          title: 'VIP 中心',
+          requireAuth: true
         },
-        {
-          path: '/user/admin/category',
-          name: 'Examine',
-          component: () => import('@/views/admin/category.vue'),
-          meta: {
-            title: '分区设置',
-            requireAuth: true
+        children: [
+          {
+            path: '/vip/plan',
+            name: 'VipPlan',
+            component: () => import('@/views/vip/plan.vue'),
+            meta: {
+              title: 'VIP 套餐', requireAuth: true
+            }
+          },
+          {
+            path: '/vip/order',
+            name: 'VipOrder',
+            component: () => import('@/views/vip/order.vue'),
+            meta: {
+              title: 'VIP 订单', requireAuth: true
+            }
+          },
+          {
+            path: '/vip/pay',
+            name: 'VipPay',
+            component: () => import('@/views/vip/pay.vue'),
+            meta: {
+              title: 'VIP 支付', requireAuth: true
+            }
           }
-        }*/
+        ]
+      },
       {
         path: '/message',
         name: 'Message',
@@ -270,7 +218,7 @@ const routes = [
         children: [
           {
             path: '/message',
-            name: 'Message',
+            name: 'MessageHome',
             component: () => import('@/views/message/home.vue'),
             meta: { title: '消息主页' }
           },
@@ -336,14 +284,6 @@ const routes = [
         component: () => import('@/views/video/video.vue'),
         meta: { title: '播放' }
       },
-      {
-        path: '/vip/pay',
-        name: 'VipPay',
-        component: () => import('@/views/vip/pay.vue'),
-        meta: {
-          title: 'VIP'
-        }
-      },
       {
         path: '/live',
         name: 'live',
@@ -368,6 +308,93 @@ const routes = [
       title: '404'
     }
   }
+  /*
+      {
+        path: '/user',
+        name: 'User',
+        component: () => import('@/views/user/index.vue')
+      },
+      {
+          path: '/user/studio',
+          name: 'StudioIndex',
+          component: () => import('@/views/studio/index.vue'),
+          meta: {
+            title: '个人中心',
+            requireAuth: true
+          }
+        },
+        {
+          path: '/user/upload',
+          name: 'Upload',
+          component: () => import('@/views/studio/upload.vue'),
+          meta: {
+            title: '投稿',
+            requireAuth: true
+          }
+        },
+        {
+          path: '/user/post',
+          name: 'Post',
+          component: () => import('@/views/studio/post.vue'),
+          meta: {
+            title: '稿件列表',
+            requireAuth: true
+          }
+        },
+        {
+          path: '/user/comment',
+          name: 'Comment',
+          component: () => import('@/views/studio/comment.vue'),
+          meta: {
+            title: '评论',
+            requireAuth: true
+          }
+        },
+        {
+          path: '/user/admin/invitation',
+          name: 'invitation',
+          component: () => import('@/views/admin/invitation.vue'),
+          meta: {
+            title: '邀请码',
+            requireAuth: true
+          }
+        },
+        {
+          path: '/user/admin/examine',
+          name: 'Examine',
+          component: () => import('@/views/admin/examine.vue'),
+          meta: {
+            title: '审核视频',
+            requireAuth: true
+          }
+        },
+        {
+          path: '/user/admin/userlist',
+          name: 'Examine',
+          component: () => import('@/views/admin/user-list.vue'),
+          meta: {
+            title: '用户列表',
+            requireAuth: true
+          }
+        },
+        {
+          path: '/user/admin/websetting',
+          name: 'Examine',
+          component: () => import('@/views/admin/web-setting.vue'),
+          meta: {
+            title: '网页设置',
+            requireAuth: true
+          }
+        },
+        {
+          path: '/user/admin/category',
+          name: 'Examine',
+          component: () => import('@/views/admin/category.vue'),
+          meta: {
+            title: '分区设置',
+            requireAuth: true
+          }
+        }*/
 ]
 
 const router = new VueRouter({

+ 0 - 1
src/views/home/t66ypage.vue

@@ -13,7 +13,6 @@ export default {
   },
   created() {
     const pageUrl = this.$route.query.pageUrl
-    console.log(pageUrl)
     this.getPage(pageUrl)
   },
   methods: {

+ 10 - 9
src/views/login.vue

@@ -27,9 +27,9 @@
               <h1>{{ this.$store.state.webInfo.name }} &nbsp; &nbsp;  {{ type }}</h1>
             </v-row>
             <v-row style="height: 48px" />
-            <MobileLoginForm v-show="showLogin" @login="userLogin" />
-            <!--            <LoginForm v-show="showLogin === true" @login="userLogin" />-->
-            <RegisterFrom v-show="showLogin === false" @register="userRegister" />
+            <LoginFormMobile v-show="showLogin" @login="userLogin" />
+            <LoginFormPassword v-show="showLogin1 === true" @login="userLogin" />
+            <RegisterForm v-show="showLogin === false" @register="userRegister" />
             <v-row justify="center">
               <v-col cols="5">
                 <v-btn text color="primary">忘记密码</v-btn>
@@ -63,16 +63,16 @@
 </template>
 
 <script>
-import MobileLoginForm from '@/components/mobile-login-form.vue'
-/* import LoginForm from '@/components/login-form.vue'*/
-import RegisterFrom from '@/components/register-from.vue'
+import LoginFormMobile from '@/components/login-form-mobile.vue'
+import LoginFormPassword from '@/components/login-form-password.vue'
+import RegisterForm from '@/components/register-form.vue'
 
 export default {
   name: 'Login',
   components: {
-    MobileLoginForm,
-    /* LoginForm,*/
-    RegisterFrom
+    LoginFormMobile,
+    LoginFormPassword,
+    RegisterForm
   },
   data() {
     return {
@@ -82,6 +82,7 @@ export default {
       type: '登录',
       moveMessage: '没有账号,创建账号',
       showLogin: true,
+      showLogin1: false,
       message: '',
       showMessage: false
     }

+ 1 - 1
src/views/mblog/mblog.vue

@@ -301,7 +301,7 @@ export default {
       if (error === null) {
         const file = metadata.file
         const uploadId = this.imgMap[file.name]
-        fetch('http://file.reghao.cn/api/file/rm/' + uploadId, {
+        fetch('//file.reghao.cn/api/file/rm/' + uploadId, {
           headers: {
             'Authorization': this.$store.getters.token
           },

+ 0 - 8
src/views/user/home.vue

@@ -142,14 +142,6 @@ export default {
     }
   },
   created() {
-    const loginUserInfo = this.$store.state.user.userInfo
-    if (loginUserInfo === null) {
-      console.log('匿名用户')
-    } else {
-      console.log('已登录用户')
-      console.log(loginUserInfo)
-    }
-
     const userIdStr = this.$route.params.userId
     if (userIdStr === undefined) {
       // 从"个人中心"加载

+ 6 - 9
src/views/user/vip.vue

@@ -1,6 +1,6 @@
 <template>
   <v-container fill-height>
-    <v-row v-if="userInfo == null || userInfo.vip === false" justify="center" align="center">
+    <v-row v-if="this.$store.state.user.userInfo == null || this.$store.state.user.userInfo.vip === false" justify="center" align="center">
       <v-col>
         <v-card
           class="mx-auto"
@@ -13,7 +13,7 @@
           </v-row>
           <v-row justify="center">
             <v-col cols="10" style="text-align: center">
-              <v-btn x-large outlined color="indigo" @click="()=>this.$router.push('/vip/pay')">开启</v-btn>
+              <v-btn x-large outlined color="indigo" @click="()=>this.$router.push('/vip/plan')">开启</v-btn>
             </v-col>
           </v-row>
 
@@ -31,18 +31,18 @@
             height="200px"
             src="https://cdn.vuetifyjs.com/images/cards/docks.jpg"
           >
-            <v-card-title>你好,尊贵的 VIP: {{ userInfo.username }}</v-card-title>
+            <v-card-title>你好,尊贵的 VIP: {{ this.$store.state.user.userInfo.username }}</v-card-title>
           </v-img>
 
           <v-card-text class="text--primary">
-            <div>VIP 到期时间: <strong>{{ userInfo.expiredAt }}</strong></div>
+            <div>VIP 到期时间: <strong>{{ this.$store.state.user.userInfo.expiredAt }}</strong></div>
           </v-card-text>
 
           <v-card-actions>
             <v-btn
               color="orange"
               text
-              @click="()=>this.$router.push('/vip/pay')"
+              @click="()=>this.$router.push('/vip/plan')"
             >
               续费
             </v-btn>
@@ -61,13 +61,10 @@ export default {
   data() {
     return {
       checkPower,
-      TimeUtil,
-      userInfo: null
+      TimeUtil
     }
   },
   created() {
-    this.userInfo = this.$store.state.user.userInfo
-    console.log(this.userInfo)
   }
 }
 </script>

+ 82 - 13
src/views/video/video.vue

@@ -1,5 +1,5 @@
 <template>
-  <div>
+  <div v-if="videoData !== null">
     <v-container>
       <v-col>
         <v-row>
@@ -19,7 +19,7 @@
     <v-container>
       <v-row>
         <v-col>
-          <VideoPlayer :videoCover="videoData.coverUrl" />
+          <VideoPlayer v-if="vidProp !== null" :video-prop="vidProp" />
         </v-col>
       </v-row>
     </v-container>
@@ -126,12 +126,59 @@
                 </v-card>
               </v-dialog>
             </v-col>
-          </v-row>
-          <!--<v-row>
-            <v-col>
-              <h3 v-text="videoData.title" />
+            <v-col cols="2">
+              <v-btn icon @click="openEditDialog">
+                <v-icon>mdi-thumb-up</v-icon>
+                <span>编辑</span>
+              </v-btn>
+              <v-dialog
+                v-model="showEditDialog"
+                persistent
+                max-width="600px"
+              >
+                <v-form
+                  ref="form"
+                  v-model="editVideo"
+                  lazy-validation
+                >
+                  <v-text-field
+                    v-model="videoId"
+                    label="视频 ID"
+                    required
+                  />
+
+                  <v-text-field
+                    v-model="editVideo.pubDate"
+                    label="发布日期"
+                    required
+                  />
+
+                  <v-btn
+                    color="success"
+                    class="mr-4"
+                    @click="submitEdit"
+                  >
+                    提交
+                  </v-btn>
+
+                  <v-btn
+                    color="error"
+                    class="mr-4"
+                    @click="resetEdit"
+                  >
+                    重置
+                  </v-btn>
+                  <v-btn
+                    color="error"
+                    class="mr-4"
+                    @click="showEditDialog = false"
+                  >
+                    取消
+                  </v-btn>
+                </v-form>
+              </v-dialog>
             </v-col>
-          </v-row>-->
+          </v-row>
           <!--<v-row>
             <v-col style="color: #999;font-size: 12px;padding-top: 0px;">
               &lt;!&ndash;
@@ -144,8 +191,6 @@
                 <span v-text="videoData.childrenCategory.name" />
               </router-link>&ndash;&gt;
               <span v-html="'&nbsp;&nbsp;&nbsp;&nbsp;'" />
-              <span v-text="videoData.viewCount" /> 次观看 <span v-html="'&nbsp;&nbsp;&nbsp;&nbsp;'" />
-              <span v-text="TimeUtil.renderTime(videoData.pubDate)" />
             </v-col>
           </v-row>-->
           <v-divider />
@@ -187,7 +232,8 @@
       </v-row>
       <v-row>
         <v-col :cols="colsWidth">
-          <CommentCard v-if="videoData !== null" :video="videoData" />
+          <!--          <CommentCard v-if="videoData !== null" :video="videoData" />-->
+          <CommentCard v-if="showComment === true" :video="videoData" />
         </v-col>
         <v-col>
           相关推荐:
@@ -233,7 +279,14 @@ export default {
       showRepostDialog: false,
       formData: {},
       collectionDialog: false,
-      isCollected: '收藏'
+      isCollected: '收藏',
+      showEditDialog: false,
+      editVideo: {
+        videoId: null,
+        pubDate: null
+      },
+      showComment: false,
+      vidProp: null
     }
   },
   created() {
@@ -261,8 +314,15 @@ export default {
       videoInfo(videoId)
         .then(res => {
           if (res.code === 0) {
-            this.videoData = res.data
-            document.title = res.data.title
+            const vidData = res.data
+            this.videoData = vidData
+            document.title = vidData.title
+
+            const vidProp = {}
+            vidProp.videoId = vidData.videoId
+            vidProp.coverUrl = vidData.coverUrl
+            vidProp.scope = vidData.scope
+            this.vidProp = vidProp
           } else {
             console.error(res.msg)
           }
@@ -311,9 +371,18 @@ export default {
     openSuggestDialog() {
       this.showDialog = true
     },
+    openEditDialog() {
+      this.showEditDialog = true
+    },
     submitVideoErr() {
       this.showDialog = false
       console.log('提交视频错误')
+    },
+    submitEdit() {
+      console.log('提交编辑信息')
+    },
+    resetEdit() {
+      console.log('重置编辑信息')
     }
   }
 }

+ 56 - 57
src/views/vip/index.vue

@@ -1,74 +1,73 @@
 <template>
-  <v-container fill-height>
-    <v-row v-if="this.$store.state.user.userInfo == null || checkPower.checkVip(this.$store.state.user.userInfo) === false" justify="center" align="center">
-      <v-col>
-        <v-card
-          class="mx-auto"
-          max-width="500"
-        >
-          <v-row justify="center">
-            <v-col cols="10" style="text-align: center">
-              <h3>开启VIP,享受无限观看次数。获取专属VIP标记!</h3>
-            </v-col>
-          </v-row>
-          <v-row justify="center">
-            <v-col cols="10" style="text-align: center">
-              <v-btn x-large outlined color="indigo" @click="()=>this.$router.push('/vip/pay')">开启</v-btn>
-            </v-col>
-          </v-row>
+  <v-container>
+    <v-row>
+      <v-col cols="2">
+        <v-sheet rounded="lg">
+          <v-list color="transparent">
+            <router-link v-for="item in items" :key="item.text" :to="item.link">
+              <v-list-item
+                link
+              >
+                <v-list-item-action>
+                  <v-icon>{{ item.icon }}</v-icon>
+                </v-list-item-action>
+                <v-list-item-content>
+                  <v-list-item-title>
+                    {{ item.text }}
+                  </v-list-item-title>
+                </v-list-item-content>
+              </v-list-item>
+            </router-link>
+
+            <v-divider class="my-2" />
 
-        </v-card>
+            <v-list-item
+              link
+              color="grey lighten-4"
+            >
+              <v-list-item-content>
+                <v-list-item-title>
+                  Refresh
+                </v-list-item-title>
+              </v-list-item-content>
+            </v-list-item>
+          </v-list>
+        </v-sheet>
       </v-col>
-    </v-row>
-    <v-row v-else justify="center" align="center">
       <v-col>
-        <v-card
-          class="mx-auto"
-          max-width="400"
+        <v-sheet
+          min-height="70vh"
+          rounded="lg"
         >
-          <v-img
-            class="white--text align-end"
-            height="200px"
-            src="https://cdn.vuetifyjs.com/images/cards/docks.jpg"
-          >
-            <v-card-title>你好,尊贵的VIP:  {{ this.$store.state.user.userInfo.username }}</v-card-title>
-          </v-img>
-
-          <v-card-text class="text--primary">
-            <div>VIP到期时间: <strong>{{ TimeUtil.renderTime(this.$store.state.user.userInfo.vipStopTime) }}</strong></div>
-            <div>剩余观看次数:<strong> ∞ </strong></div>
-          </v-card-text>
-
-          <v-card-actions>
-            <v-btn
-              color="orange"
-              text
-              @click="()=>this.$router.push('/vip/pay')"
-            >
-              续费
-            </v-btn>
-          </v-card-actions>
-        </v-card>
+          <router-view />
+        </v-sheet>
       </v-col>
     </v-row>
-
   </v-container>
 </template>
 
 <script>
-import checkPower from '@/utils/check-power.vue'
-import TimeUtil from '@/utils/time-util.vue'
+import CheckPower from '@/utils/check-power.vue'
+
 export default {
-  name: 'VIP',
-  data() {
-    return {
-      checkPower,
-      TimeUtil
-    }
+  data: () => ({
+    CheckPower,
+    items: [
+      { icon: 'mdi-wrench', text: '套餐', link: '/vip/plan' },
+      { icon: 'mdi-account-multiple', text: '订单', link: '/vip/order' }
+    ]
+  }),
+  mounted() {
+  },
+  created() {
+  },
+  methods: {
   }
 }
 </script>
 
-<style>
-
+<style scoped>
+a {
+  text-decoration: none;
+}
 </style>

+ 31 - 2
src/views/vip/order.vue

@@ -1,17 +1,46 @@
 <template>
-  <v-container fill-height>
-    <span><h2>订单页面</h2></span>
+  <v-container>
+    <v-data-table
+      :headers="headers"
+      :items="orders"
+      :items-per-page="5"
+      class="elevation-1"
+    />
   </v-container>
 </template>
 
 <script>
+import { getVipOrder } from '@/api/user/user'
+
 export default {
   data() {
     return {
+      headers: [
+        {
+          text: '套餐',
+          align: 'start',
+          sortable: false,
+          value: 'plan'
+        },
+        { text: '单价', value: 'price' },
+        { text: '数量', value: 'num' },
+        { text: '交易状态', value: 'status' },
+        { text: '创建时间', value: 'createdAt' }
+      ],
+      orders: []
     }
   },
   created() {
     this.windowSize = { x: window.innerWidth, y: window.innerHeight }
+    getVipOrder().then(res => {
+      if (res.code === 0) {
+        this.orders = []
+        const resData = res.data
+        for (const item of resData) {
+          this.orders.push(item)
+        }
+      }
+    })
   },
   methods: {
     onResize() {

+ 19 - 85
src/views/vip/pay.vue

@@ -3,10 +3,6 @@
     <span><h2>支付页面</h2></span>
     <v-row no-gutters justify="center" align="center">
       <v-col
-        v-for="item in vipPlans"
-        :key="item.planId"
-        v-resize="onResize"
-        :cols="cols"
         style="margin-top: 48px;"
       >
         <v-card
@@ -14,125 +10,63 @@
           max-width="344"
         >
           <v-card-text>
-            <div> 时长: </div>
-            <p class="display-1 text--primary">
+            <div> 您正在支付订单号为 11223344 的订单 </div>
+            <!--            <p class="display-1 text&#45;&#45;primary">
               {{ item.duration }}
-            </p>
-
-            <div class="text--primary">
-              <strong> ¥: {{ item.price }} </strong>
-            </div>
+            </p>-->
           </v-card-text>
           <v-card-actions>
             <v-btn
               text
               color="deep-purple accent-4"
-              @click="choosePlan(item)"
+              @click="pay"
             >
-              选择
+              支付
             </v-btn>
           </v-card-actions>
         </v-card>
       </v-col>
     </v-row>
-    <v-dialog
-      v-model="dialog"
-      max-width="290"
-    >
-      <v-card>
-        <v-card-title class="headline">支付订单</v-card-title>
-<!--        <v-card-text>
-          <span>您选择的是 </span>
-          <h3>{{ vipPlan.duration }}</h3>
-          <span> 套餐</span>
-        </v-card-text>-->
-
-        <v-card-actions>
-          <v-spacer />
-          <v-btn
-            color="green darken-1"
-            text
-            @click="dialog = false"
-          >
-            取消
-          </v-btn>
-
-          <v-btn
-            color="green darken-1"
-            text
-            @click="pay"
-          >
-            支付
-          </v-btn>
-        </v-card-actions>
-      </v-card>
-    </v-dialog>
   </v-container>
 </template>
 
 <script>
-import { getVipPlan, payVip } from '@/api/user/user'
+import { payVip } from '@/api/user/user'
 
 export default {
   data() {
     return {
-      dialog: false,
-      vipPlans: [],
-      vipPlan: null,
-      planId: null,
-      cols: 5,
-      windowSize: {
-      }
+      orderId: null
     }
   },
   created() {
-    this.windowSize = { x: window.innerWidth, y: window.innerHeight }
-    getVipPlan().then(res => {
-      if (res.code === 0) {
-        const resData = res.data
-        this.vipPlans = []
-        for (const item of resData) {
-          this.vipPlans.push(item)
-        }
-      } else {
-        alert(res.data)
-      }
-    }).catch(error => {
-      console.error(error.message)
-    })
+    this.orderId = parseInt(this.$route.query.orderId)
   },
   methods: {
-    onResize() {
-      this.windowSize = { x: window.innerWidth, y: window.innerHeight }
-      if (this.windowSize.x < 700) {
-        this.cols = 12
-      } else {
-        this.cols = 5
-      }
-    },
-    choosePlan(item) {
-      this.dialog = true
-      this.vipPlan = item
-    },
     pay() {
-      this.dialog = false
-      payVip(this.vipPlan.planId).then(res => {
+      if (this.orderId === null) {
+        alert('订单 ID 不存在')
+        return
+      }
+
+      payVip(this.orderId).then(res => {
         if (res.code === 0) {
-          this.vipPlan = null
           this.$store.commit('user/SET_VIP', res.data)
+
+          if (this.$route.path === '/vip/order') {
+            return
+          }
+          this.$router.push('/vip/order')
         } else {
-          console.log(res.data)
           alert(res.data)
         }
       }).catch(error => {
         console.error(error.message)
       })
-      console.log('支付')
     }
   }
 }
 </script>
 
 <style>
-
 </style>

+ 142 - 0
src/views/vip/plan.vue

@@ -0,0 +1,142 @@
+<template>
+  <v-container fill-height>
+    <span><h2>VIP 套餐</h2></span>
+    <v-row no-gutters justify="center" align="center">
+      <v-col
+        v-for="item in vipPlans"
+        :key="item.planId"
+        v-resize="onResize"
+        :cols="cols"
+        style="margin-top: 48px;"
+      >
+        <v-card
+          class="mx-auto"
+          max-width="344"
+        >
+          <v-card-text>
+            <div> 时长: </div>
+            <p class="display-1 text--primary">
+              {{ item.duration }}
+            </p>
+
+            <div class="text--primary">
+              <strong> ¥: {{ item.price }} </strong>
+            </div>
+          </v-card-text>
+          <v-card-actions>
+            <v-btn
+              text
+              color="deep-purple accent-4"
+              @click="choosePlan(item)"
+            >
+              选择
+            </v-btn>
+          </v-card-actions>
+        </v-card>
+      </v-col>
+    </v-row>
+    <v-dialog
+      v-model="dialog"
+      max-width="290"
+    >
+      <v-card>
+        <v-card-title class="headline">套餐详情</v-card-title>
+        <v-card-text v-if="vipPlan !== null">
+          <span>您选择的是 </span>
+          <h3>{{ vipPlan.duration }}</h3>
+          <span> 套餐, 确定选择此套餐? </span>
+        </v-card-text>
+
+        <v-card-actions>
+          <v-spacer />
+          <v-btn
+            color="green darken-1"
+            text
+            @click="dialog = false"
+          >
+            重新选择
+          </v-btn>
+
+          <v-btn
+            color="green darken-1"
+            text
+            @click="ensurePlan"
+          >
+            就是它了
+          </v-btn>
+        </v-card-actions>
+      </v-card>
+    </v-dialog>
+  </v-container>
+</template>
+
+<script>
+import { getVipPlan, createVipOrder } from '@/api/user/user'
+
+export default {
+  data() {
+    return {
+      dialog: false,
+      vipPlans: [],
+      vipPlan: null,
+      planId: null,
+      cols: 5,
+      windowSize: {
+      }
+    }
+  },
+  created() {
+    this.windowSize = { x: window.innerWidth, y: window.innerHeight }
+    getVipPlan().then(res => {
+      if (res.code === 0) {
+        const resData = res.data
+        this.vipPlans = []
+        for (const item of resData) {
+          this.vipPlans.push(item)
+        }
+      } else {
+        alert(res.data)
+      }
+    }).catch(error => {
+      console.error(error.message)
+    })
+  },
+  methods: {
+    onResize() {
+      this.windowSize = { x: window.innerWidth, y: window.innerHeight }
+      if (this.windowSize.x < 700) {
+        this.cols = 12
+      } else {
+        this.cols = 5
+      }
+    },
+    choosePlan(item) {
+      this.dialog = true
+      this.vipPlan = item
+    },
+    ensurePlan() {
+      createVipOrder(this.vipPlan.planId).then(res => {
+        if (res.code === 0) {
+          if (this.$route.path === '/vip/pay') {
+            return
+          }
+
+          const orderId = res.data
+          this.$router.push({
+            path: '/vip/pay',
+            query: {
+              orderId: orderId
+            }
+          })
+        } else {
+          alert('订单创建失败')
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style>
+
+</style>