Parcourir la source

feat():live

geek il y a 4 ans
Parent
commit
eb940839b0

+ 40 - 0
src/api/live.js

@@ -0,0 +1,40 @@
+import request from '@/utils/request'
+
+export function fetchList(query) {
+  return request({
+    url: '/Live/index',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchLive(id) {
+  return request({
+    url: '/Live/read',
+    method: 'get',
+    params: { id }
+  })
+}
+
+export function createLive(data) {
+  return request({
+    url: '/Live/save',
+    method: 'post',
+    data
+  })
+}
+
+export function updateLive(data) {
+  return request({
+    url: '/Live/update?id=' + data.id,
+    method: 'post',
+    data
+  })
+}
+
+export function deleteLive(id) {
+  return request({
+    url: '/Live/delete?id=' + id,
+    method: 'get'
+  })
+}

+ 2 - 2
src/api/qiniu.js

@@ -7,9 +7,9 @@ export function getToken() {
   })
 }
 
-export function uploadImg(data) {
+export function uploadImg(data, uploadWx = false) {
   return request({
-    url: '/upload/upload',
+    url: `/upload/upload?uploadWx=${uploadWx}`,
     method: 'post',
     data
   })

+ 10 - 1
src/components/Upload/SingleImage3.vue

@@ -42,6 +42,10 @@ export default {
     value: {
       type: String,
       default: ''
+    },
+    wxUpload: {
+      type: String,
+      default: ''
     }
   },
   data() {
@@ -78,11 +82,16 @@ export default {
       return isIMAGE && isLt1M
     },
     uploadImage(param) {
+      console.log(this.wxUpload)
+      console.log(this.wxUpload.length)
       const formData = new FormData()
       formData.append('image', param.file)
-      uploadImg(formData).then(response => {
+      uploadImg(formData, this.wxUpload.length > 1).then(response => {
         console.log('上传图片成功')
         this.imgUrl = response.data.url
+        if (this.wxUpload.length > 1) {
+          this.$emit('wxMedia', this.wxUpload + '%llz%' + response.data.mediaId)
+        }
         param.onSuccess()
         // 上传成功的图片会显示绿色的对勾
         // 但是我们上传成功了图片, fileList 里面的值却没有改变,还好有on-change指令可以使用

+ 31 - 0
src/router/index.js

@@ -273,6 +273,37 @@ export const constantRoutes = [
     ]
   },
   {
+    path: '/live',
+    component: Layout,
+    redirect: '/live/list',
+    name: 'live',
+    meta: {
+      title: '直播列表',
+      icon: 'el-icon-reading'
+    },
+    children: [
+      {
+        path: 'create',
+        component: () => import('@/views/live/create'),
+        name: 'CreateLive',
+        meta: { title: '创建直播间', icon: 'el-icon-edit' }
+      },
+      {
+        path: 'edit/:id(\\d+)',
+        component: () => import('@/views/live/edit'),
+        name: 'EditLive',
+        meta: { title: '修改直播间', noCache: true, activeMenu: '/live/list' },
+        hidden: true
+      },
+      {
+        path: 'list',
+        component: () => import('@/views/live/list'),
+        name: 'ArticleLive',
+        meta: { title: '直播列表', icon: 'el-icon-s-order' }
+      }
+    ]
+  },
+  {
     path: '/video',
     component: Layout,
     redirect: '/video/list',

+ 340 - 0
src/views/live/components/ArticleDetail.vue

@@ -0,0 +1,340 @@
+<template>
+  <div class="createPost-container">
+    <el-form ref="postForm" :label-position="labelPosition" :model="postForm" :rules="rules" class="form-container" label-width="120px">
+      <div class="createPost-main-container">
+        <el-form-item prop="name" label="直播间名称">
+          <el-input v-model="postForm.name" style="width: 300px;" placeholder="直播间名称" />
+        </el-form-item>
+        <el-form-item prop="cover_img_url" label="封面图">
+          <Upload v-model="postForm.cover_img_url" :wx-upload="postForm.cover_img" @wxMedia="wxMedia" />
+        </el-form-item>
+        <el-form-item prop="time_area" label="时间范围">
+          <el-tooltip placement="top" style="font-size: 18px;margin-left: -50px;">
+            <div slot="content">开播时间段仅供参考,不是实际直播间可以开播的时间。
+              <br>直播间在开始时间前也可以开播,并且到结束时间后不会强制结束。
+              <br>若到结束时间仍未开播,则直播间无法再开播。
+            </div>
+            <i class="el-icon-question" />
+          </el-tooltip>
+          <template>
+            <el-date-picker
+              v-model="postForm.time_area"
+              type="datetimerange"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+              style="margin-left: 31px"
+            />
+          </template>
+        </el-form-item>
+        <el-form-item prop="anchor_name" label="主播名称">
+          <el-input v-model="postForm.anchor_name" placeholder="" style="width: 300px;" />
+        </el-form-item>
+        <el-form-item prop="anchor_wechat" label="主播微信">
+          <el-input v-model="postForm.anchor_wechat" placeholder="" style="width: 600px;" />
+          <el-link type="primary" style="margin-left: 20px" target="_blank" href="https://res.wx.qq.com/op_res/9rSix1dhHfK4rR049JL0PHJ7TpOvkuZ3mE0z7Ou_Etvjf-w1J_jVX0rZqeStLfwh">去认证</el-link>
+        </el-form-item>
+        <el-form-item prop="sub_anchor_wechat" label="主播副微信号">
+          <el-input v-model="postForm.sub_anchor_wechat" placeholder="" style="width: 300px;" />
+          <el-link type="primary" style="margin-left: 20px" target="_blank" href="https://res.wx.qq.com/op_res/9rSix1dhHfK4rR049JL0PHJ7TpOvkuZ3mE0z7Ou_Etvjf-w1J_jVX0rZqeStLfwh">去认证</el-link>
+        </el-form-item>
+        <el-form-item prop="creater_wechat" label="创建者微信号">
+          <el-input v-model="postForm.creater_wechat" placeholder="" style="width: 300px;" />
+        </el-form-item>
+        <el-form-item prop="share_img_url" label="分享图">
+          <Upload v-model="postForm.share_img_url" :wx-upload="postForm.share_img" @wxMedia="wxMedia" />
+        </el-form-item>
+        <el-form-item prop="feeds_img_url" label="购物封面图">
+          <Upload v-model="postForm.feeds_img_url" :wx-upload="postForm.feeds_img" @wxMedia="wxMedia" />
+        </el-form-item>
+        <el-form-item prop="is_feeds_public" label="官方收录">
+          <template>
+            <el-radio-group v-model="postForm.is_feeds_public">
+              <el-radio :label="1">开启</el-radio>
+              <el-radio :label="0">关闭</el-radio>
+            </el-radio-group>
+          </template>
+        </el-form-item>
+        <el-form-item prop="type" label="直播间类型">
+          <template>
+            <el-radio-group v-model="postForm.type">
+              <el-radio :label="1">推流</el-radio>
+              <el-radio :label="0">手机直播</el-radio>
+            </el-radio-group>
+          </template>
+        </el-form-item>
+        <el-form-item prop="screen_type" label="横屏、竖屏">
+          <template>
+            <el-radio-group v-model="postForm.screen_type">
+              <el-radio :label="1">横屏</el-radio>
+              <el-radio :label="0">竖屏</el-radio>
+            </el-radio-group>
+          </template>
+        </el-form-item>
+        <el-form-item prop="close_like" label="点赞">
+          <template>
+            <el-radio-group v-model="postForm.close_like">
+              <el-radio :label="0">开启</el-radio>
+              <el-radio :label="1">关闭</el-radio>
+            </el-radio-group>
+          </template>
+        </el-form-item>
+        <el-form-item prop="close_goods" label="货架">
+          <template>
+            <el-radio-group v-model="postForm.close_goods">
+              <el-radio :label="0">开启</el-radio>
+              <el-radio :label="1">关闭</el-radio>
+            </el-radio-group>
+          </template>
+        </el-form-item>
+        <el-form-item prop="close_comment" label="评论">
+          <template>
+            <el-radio-group v-model="postForm.close_comment">
+              <el-radio :label="0">开启</el-radio>
+              <el-radio :label="1">关闭</el-radio>
+            </el-radio-group>
+          </template>
+        </el-form-item>
+        <el-form-item prop="close_replay" label="回放">
+          <template>
+            <el-radio-group v-model="postForm.close_replay">
+              <el-radio :label="0">开启</el-radio>
+              <el-radio :label="1">关闭</el-radio>
+            </el-radio-group>
+          </template>
+        </el-form-item>
+        <el-form-item prop="close_share" label="分享">
+          <template>
+            <el-radio-group v-model="postForm.close_share">
+              <el-radio :label="0">开启</el-radio>
+              <el-radio :label="1">关闭</el-radio>
+            </el-radio-group>
+          </template>
+        </el-form-item>
+        <el-form-item prop="close_kf" label="客服">
+          <template>
+            <el-radio-group v-model="postForm.close_kf">
+              <el-radio :label="0">开启</el-radio>
+              <el-radio :label="1">关闭</el-radio>
+            </el-radio-group>
+          </template>
+        </el-form-item>
+        <el-row>
+          <el-button v-if="!isEdit" v-loading="loading" type="success" @click="submitForm">
+            提交
+          </el-button>
+          <el-button v-if="isEdit" v-loading="loading" type="success" @click="updateArticle">
+            返回
+          </el-button>
+        </el-row>
+      </div>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import Upload from '@/components/Upload/SingleImage3'
+// import Sticky from '@/components/Sticky' // 粘性header组件
+// import { validURL } from '@/utils/validate'
+import { fetchLive, createLive } from '@/api/live'
+// import Warning from './Warning'
+// import { CommentDropdown, PlatformDropdown, SourceUrlDropdown } from './Dropdown'
+
+const defaultForm = {
+  // status: 'draft',
+  is_feeds_public: 0, // 文章题目
+  screen_type: 0, // 文章内容
+  close_like: 0, // 文章内容
+  close_goods: 1, // 文章内容
+  close_comment: 0, // 文章内容
+  close_replay: 0, // 文章内容
+  close_share: 0, // 文章内容
+  close_kf: 1, // 文章内容
+  type: 1, // 文章外链
+  name: '', // 前台展示时间
+  cover_img: 'cover_img', // 文章图片
+  sub_anchor_wechat: '',
+  creater_wechat: '',
+  cover_img_url: '',
+  share_img_url: '',
+  share_img: 'share_img',
+  feeds_img: 'feeds_img',
+  feeds_img_url: '',
+  time_area: ''
+}
+
+export default {
+  name: 'ArticleDetail',
+  components: { Upload },
+  props: {
+    isEdit: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    const validateRequire = (rule, value, callback) => {
+      if (value === '') {
+        // this.$message({
+        //   message: rule.field + '不为空',
+        //   type: 'error'
+        // })直播标题必须为3-17个字(一个字等于两个英文字符或特殊字符)
+        callback(new Error(rule.field + '不为空'))
+      } else {
+        if (rule.field === 'anchor_name' && value && value.length > 15) {
+          callback(new Error('最大15个字!'))
+        }
+        if (rule.field === 'name' && value && value.length < 4) {
+          callback(new Error('直播标题必须为3-17个字(一个字等于两个英文字符或特殊字符)'))
+        }
+
+        if (rule.field === 'time_area') {
+          if (value === '' || value === null) {
+            callback(new Error('开播时间不能为空'))
+            return
+          }
+          const startTime = value[0]
+          const endTime = value[1]
+          const startTimeDate = new Date(startTime)
+          const endTimeDate = new Date(endTime)
+          const nowDate = new Date()
+          console.log((startTimeDate.getTime() - nowDate.getTime()) / 1000)
+          if ((startTimeDate.getTime() - nowDate.getTime()) < 600 * 1000) {
+            callback(new Error('开播时间至少在10分钟后'))
+            return
+          }
+          if (endTimeDate.getTime() - startTimeDate.getTime() > 3 * 24 * 3600 * 1000) {
+            callback(new Error('时间跨度不能超过三天'))
+            return
+          }
+        }
+        callback()
+      }
+    }
+    return {
+      postForm: Object.assign({}, defaultForm),
+      loading: false,
+      userListOptions: [],
+      rules: {
+        name: [{ message: '直播标题必须为3-17个字(一个字等于两个英文字符或特殊字符)', required: true, validator: validateRequire, trigger: 'blur' }],
+        cover_img_url: [{ message: '封面图不为空', required: true, validator: validateRequire, trigger: 'blur' }],
+        time_area: [{ required: true, validator: validateRequire }],
+        anchor_name: [{ message: '主播名称不为空且最多15个字', required: true, validator: validateRequire, trigger: 'blur' }],
+        anchor_wechat: [{ message: '主播微信不为空且必须是认证的', required: true, validator: validateRequire, trigger: 'blur' }],
+        share_img_url: [{ message: '分享图片不为空', required: true, validator: validateRequire }],
+        type: [{ message: '直播类型不为空', required: true, validator: validateRequire }],
+        screen_type: [{ message: '横屏、竖屏不为空', required: true, validator: validateRequire }],
+        close_like: [{ message: '点赞不为空', required: true, validator: validateRequire }],
+        close_goods: [{ message: '货架不为空', required: true, validator: validateRequire }],
+        close_comment: [{ message: '评论不为空', required: true, validator: validateRequire }]
+      },
+      tempRoute: {},
+      labelPosition: 'left'
+    }
+  },
+  computed: {
+  },
+  created() {
+    if (this.isEdit) {
+      const id = this.$route.params && this.$route.params.id
+      this.fetchData(id)
+    }
+    // Why need to make a copy of this.$route here?
+    // Because if you enter this page and quickly switch tag, may be in the execution of the setTagsViewTitle function, this.$route is no longer pointing to the current page
+    // https://github.com/PanJiaChen/vue-element-admin/issues/1221
+    this.tempRoute = Object.assign({}, this.$route)
+  },
+  methods: {
+    fetchData(id) {
+      fetchLive(id).then(response => {
+        this.postForm = response.data.info
+        // set tags view title
+        // this.setTagsViewTitle()
+        // set page title
+        // this.setPageTitle()
+      }).catch(err => {
+        console.log(err)
+      })
+    },
+    async submitForm() {
+      this.$refs.postForm.validate(async valid => {
+        if (valid) {
+          this.loading = true
+          await createLive(this.postForm)
+          this.$notify({
+            title: '成功',
+            message: '创建直播间成功',
+            type: 'success',
+            duration: 2000
+          })
+          this.loading = false
+          this.listLoading = false
+          this.$router.push(`/live/list`)
+        } else {
+          console.log('error submit!!')
+          return false
+        }
+      })
+    },
+    updateArticle() {
+      console.log(this.postForm)
+      this.$router.push(`/join/list`)
+      // updateJoin(this.postForm).then(response => {
+      //   this.$notify({
+      //     title: '修改',
+      //     message: '修改成功',
+      //     type: 'success',
+      //     duration: 2000
+      //   })
+      //   this.postForm.status = 'published'
+      //   this.loading = false
+      //   this.listLoading = false
+      //   this.$router.push(`/banner/list`)
+      // })
+    },
+    wxMedia(value) {
+      const arr = value.split('%llz%')
+      this.postForm[arr[0]] = arr[1]
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import "~@/styles/mixin.scss";
+
+.createPost-container {
+  position: relative;
+
+  .createPost-main-container {
+    padding: 40px 45px 20px 50px;
+
+    .postInfo-container {
+      position: relative;
+      @include clearfix;
+      margin-bottom: 10px;
+
+      .postInfo-container-item {
+        float: left;
+      }
+    }
+  }
+
+  .word-counter {
+    width: 40px;
+    position: absolute;
+    right: 10px;
+    top: 0px;
+  }
+}
+
+.article-textarea ::v-deep {
+  textarea {
+    padding-right: 40px;
+    resize: none;
+    border: none;
+    border-radius: 0px;
+    border-bottom: 1px solid #bfcbd9;
+  }
+}
+</style>

+ 41 - 0
src/views/live/components/Dropdown/Comment.vue

@@ -0,0 +1,41 @@
+<template>
+  <el-dropdown :show-timeout="100" trigger="click">
+    <el-button plain>
+      {{ !comment_disabled?'Comment: opened':'Comment: closed' }}
+      <i class="el-icon-caret-bottom el-icon--right" />
+    </el-button>
+    <el-dropdown-menu slot="dropdown" class="no-padding">
+      <el-dropdown-item>
+        <el-radio-group v-model="comment_disabled" style="padding: 10px;">
+          <el-radio :label="true">
+            Close comment
+          </el-radio>
+          <el-radio :label="false">
+            Open comment
+          </el-radio>
+        </el-radio-group>
+      </el-dropdown-item>
+    </el-dropdown-menu>
+  </el-dropdown>
+</template>
+
+<script>
+export default {
+  props: {
+    value: {
+      type: Boolean,
+      default: false
+    }
+  },
+  computed: {
+    comment_disabled: {
+      get() {
+        return this.value
+      },
+      set(val) {
+        this.$emit('input', val)
+      }
+    }
+  }
+}
+</script>

+ 46 - 0
src/views/live/components/Dropdown/Platform.vue

@@ -0,0 +1,46 @@
+<template>
+  <el-dropdown :hide-on-click="false" :show-timeout="100" trigger="click">
+    <el-button plain>
+      Platfroms({{ platforms.length }})
+      <i class="el-icon-caret-bottom el-icon--right" />
+    </el-button>
+    <el-dropdown-menu slot="dropdown" class="no-border">
+      <el-checkbox-group v-model="platforms" style="padding: 5px 15px;">
+        <el-checkbox v-for="item in platformsOptions" :key="item.key" :label="item.key">
+          {{ item.name }}
+        </el-checkbox>
+      </el-checkbox-group>
+    </el-dropdown-menu>
+  </el-dropdown>
+</template>
+
+<script>
+export default {
+  props: {
+    value: {
+      required: true,
+      default: () => [],
+      type: Array
+    }
+  },
+  data() {
+    return {
+      platformsOptions: [
+        { key: 'a-platform', name: 'a-platform' },
+        { key: 'b-platform', name: 'b-platform' },
+        { key: 'c-platform', name: 'c-platform' }
+      ]
+    }
+  },
+  computed: {
+    platforms: {
+      get() {
+        return this.value
+      },
+      set(val) {
+        this.$emit('input', val)
+      }
+    }
+  }
+}
+</script>

+ 38 - 0
src/views/live/components/Dropdown/SourceUrl.vue

@@ -0,0 +1,38 @@
+<template>
+  <el-dropdown :show-timeout="100" trigger="click">
+    <el-button plain>
+      Link
+      <i class="el-icon-caret-bottom el-icon--right" />
+    </el-button>
+    <el-dropdown-menu slot="dropdown" class="no-padding no-border" style="width:400px">
+      <el-form-item label-width="0px" style="margin-bottom: 0px" prop="source_uri">
+        <el-input v-model="source_uri" placeholder="Please enter the content">
+          <template slot="prepend">
+            URL
+          </template>
+        </el-input>
+      </el-form-item>
+    </el-dropdown-menu>
+  </el-dropdown>
+</template>
+
+<script>
+export default {
+  props: {
+    value: {
+      type: String,
+      default: ''
+    }
+  },
+  computed: {
+    source_uri: {
+      get() {
+        return this.value
+      },
+      set(val) {
+        this.$emit('input', val)
+      }
+    }
+  }
+}
+</script>

+ 3 - 0
src/views/live/components/Dropdown/index.js

@@ -0,0 +1,3 @@
+export { default as CommentDropdown } from './Comment'
+export { default as PlatformDropdown } from './Platform'
+export { default as SourceUrlDropdown } from './SourceUrl'

+ 9 - 0
src/views/live/components/Warning.vue

@@ -0,0 +1,9 @@
+<template>
+  <aside>
+    <!--<a
+      href="https://panjiachen.github.io/vue-element-admin-site/guide/essentials/tags-view.html"
+      target="_blank"
+    >Document</a>-->
+  </aside>
+</template>
+

+ 13 - 0
src/views/live/create.vue

@@ -0,0 +1,13 @@
+<template>
+  <article-detail :is-edit="false" />
+</template>
+
+<script>
+import ArticleDetail from './components/ArticleDetail'
+
+export default {
+  name: 'CreateArticle',
+  components: { ArticleDetail }
+}
+</script>
+

+ 13 - 0
src/views/live/edit.vue

@@ -0,0 +1,13 @@
+<template>
+  <article-detail :is-edit="true" />
+</template>
+
+<script>
+import ArticleDetail from './components/ArticleDetail'
+
+export default {
+  name: 'EditForm',
+  components: { ArticleDetail }
+}
+</script>
+

+ 206 - 0
src/views/live/list.vue

@@ -0,0 +1,206 @@
+<template>
+  <div class="app-container">
+    <div class="filter-container">
+      <el-input v-model="listQuery.mobile" placeholder="手机号" style="width: 200px;" class="filter-item" @keyup.enter.native="handleFilter" />
+      <el-button v-waves class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
+        搜索
+      </el-button>
+    </div>
+    <el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%">
+      <el-table-column align="center" label="ID" width="80">
+        <template slot-scope="scope">
+          <span>{{ scope.row.id }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column width="180px" align="center" label="创建日期">
+        <template slot-scope="scope">
+          <span>{{ scope.row.create_time }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column class-name="status-col" align="center" label="直播间id">
+        <template slot-scope="scope">
+          <span>{{ scope.row.room_id }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column class-name="status-col" label="直播间名称" align="center" >
+        <template slot-scope="scope">
+          <span>{{ scope.row.name }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column class-name="status-col" label="开始时间" width="180px" align="center">
+        <template slot-scope="scope">
+          <span>{{ scope.row.start_time }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column class-name="status-col" align="center" label="结束时间" width="180px">
+        <template slot-scope="scope">
+          <span>{{ scope.row.end_time }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column class-name="status-col" label="主播昵称" align="center">
+        <template slot-scope="scope">
+          <span>{{ scope.row.anchor_name }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column class-name="status-col" label="直播类型" align="center">
+        <template slot-scope="scope">
+          <span>{{ scope.row.type | typeFilter }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column class-name="status-col" label="状态" align="center">
+        <template slot-scope="{row}">
+          <el-tag type="success">
+            {{ row | statusFilter }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" label="Actions" width="300" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-row>
+            <router-link :to="'/live/edit/'+scope.row.id">
+              <el-button type="primary" size="mini" icon="el-icon-edit" style="margin-right: 10px;">
+                查看
+              </el-button>
+            </router-link>
+<!--            <el-button type="primary" size="mini" icon="el-icon-s-check" :disabled="(scope.row.status === 1 || scope.row.status === 3)" @click="handleUpdate(scope)">-->
+<!--              {{ scope.row.status === 1 || scope.row.status === 3 ? '已处理' : '处理' }}-->
+<!--            </el-button>-->
+            <!--<el-button type="danger" size="mini" icon="el-icon-delete" style="margin-left: 10px;" @click="handleDelete(scope)">
+              删除
+            </el-button>-->
+          </el-row>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.pageSize" @pagination="getList" />
+  </div>
+</template>
+
+<script>
+import { fetchList, deleteLive } from '@/api/live'
+import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
+import waves from '@/directive/waves'
+
+export default {
+  name: 'ArticleList',
+  components: { Pagination },
+  directives: { waves },
+  filters: {
+    statusFilter(row) {
+      const startTimeData = new Date(row.start_time)
+      const endTimeData = new Date(row.end_time)
+      const now = new Date()
+      if (now.getTime() > startTimeData.getTime() && now.getTime() < endTimeData.getTime()) {
+        return '直播中'
+      }
+      if (now.getTime() > endTimeData.getTime()) {
+        return '已结束'
+      }
+      if (now.getTime() < startTimeData.getTime()) {
+        return '未开始'
+      }
+    },
+    typeFilter(type) {
+      const statusMap = {
+        1: '推流',
+        0: '手机直播'
+      }
+      return statusMap[type]
+    }
+  },
+  data() {
+    return {
+      list: null,
+      total: 0,
+      listLoading: true,
+      listQuery: {
+        page: 1,
+        pageSize: 10
+      },
+      temp: {
+        id: undefined,
+        mark: '',
+        status: ''
+      },
+      dialogFormVisible: false
+    }
+  },
+  created() {
+    this.getList()
+  },
+  methods: {
+    getList() {
+      this.listLoading = true
+      fetchList(this.listQuery).then(response => {
+        this.list = response.data.list
+        this.total = response.data.count
+        this.listLoading = false
+      })
+    },
+    handleFilter() {
+      this.listLoading = true
+      fetchList(this.listQuery).then(response => {
+        this.list = response.data.list
+        this.total = response.data.count
+        this.listLoading = false
+      })
+    },
+    handleDelete({ $index, row }) {
+      console.log(row.id)
+      this.$confirm('您确定要隐藏吗', '警告', {
+        confirmButtonText: '是的',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(async() => {
+          await deleteJoin(row.id)
+          this.list.splice($index, 1)
+          this.$message({
+            type: 'success',
+            message: '隐藏成功'
+          })
+        })
+    },
+    async handleUpdate({ $index, row }) {
+      this.temp = Object.assign({}, row) // copy obj
+      this.dialogFormVisible = true
+      this.$nextTick(() => {
+        this.$refs['dataForm'].clearValidate()
+      })
+    },
+    async updateData() {
+      const tempData = Object.assign({}, this.temp)
+      await dealJoin(tempData)
+      const rs = await fetchJoin(tempData.id)
+      const index = this.list.findIndex(v => v.id === this.temp.id)
+      this.list.splice(index, 1, rs.data.info)
+      this.dialogFormVisible = false
+      this.$notify({
+        title: '成功',
+        message: '更新成功',
+        type: 'success',
+        duration: 2000
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+.edit-input {
+  padding-right: 100px;
+}
+.cancel-btn {
+  position: absolute;
+  right: 15px;
+  top: 10px;
+}
+.filter-container{
+  margin-bottom: 20px;
+}
+.filter-item {
+  margin-right: 10px;
+}
+
+</style>