浏览代码

添加广告热点相关页面效果

syh 5 年之前
父节点
当前提交
3dab673001

+ 1 - 0
public/index.html

@@ -4,6 +4,7 @@
 <head>
 <head>
   <meta charset="utf-8">
   <meta charset="utf-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="referrer" content="never">
   <meta name="viewport" content="width=device-width,initial-scale=1.0">
   <meta name="viewport" content="width=device-width,initial-scale=1.0">
   <title>汇创投放助手</title>
   <title>汇创投放助手</title>
   <link rel="icon" href="<%= BASE_URL %>logo.png">
   <link rel="icon" href="<%= BASE_URL %>logo.png">

+ 384 - 0
src/views/oceanengine/AdList.vue

@@ -0,0 +1,384 @@
+<template>
+  <a-row :gutter="10" class="list-pubu">
+    <a-col :sm="24" style="margin-bottom: 20px;z-index: 10">
+      <a-card :bordered="false">
+        <div class="table-page-search-wrapper">
+          <a-form layout="inline">
+            <a-row :gutter="24">
+              <!--<a-col :md="8" :sm="8">
+                <a-form-item
+                  label="抓取日期"
+                  :labelCol="{lg: {span: 7}, sm: {span: 7}}"
+                  :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
+                >
+                  <a-range-picker name="buildTime" style="width: 100%" v-model="time" />
+                </a-form-item>
+              </a-col>-->
+              <a-col :md="8" :sm="8">
+                <a-form-item label="发布人">
+                  <a-input placeholder="请输入发布人昵称" v-model="queryParam.userName"></a-input>
+                </a-form-item>
+              </a-col>
+            </a-row>
+            <a-row :gutter="24">
+              <a-col :md="10" :sm="10">
+                <a-form-item label="排序">
+                  <a-radio-group v-model="queryParam.orderByColumn">
+                    <a-radio-button value="create_time">按抓取时间</a-radio-button>
+                    <a-radio-button value="play">按播放数</a-radio-button>
+                    <a-radio-button value="like_cnt">按喜欢数</a-radio-button>
+                    <a-radio-button value="comment">按评论数</a-radio-button>
+                  </a-radio-group>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="6">
+                <a-form-item>
+                  <a-radio-group v-model="queryParam.orderByType">
+                    <a-radio-button value="asc">正序</a-radio-button>
+                    <a-radio-button value="desc">倒序</a-radio-button>
+                  </a-radio-group>
+                </a-form-item>
+              </a-col>
+              <a-col :md="8" :sm="8">
+                <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+                <a-button
+                  type="primary"
+                  @click="searchReset"
+                  icon="reload"
+                  style="margin-left: 8px"
+                >重置</a-button>
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <app-ad-modal ref="modalForm"></app-ad-modal>
+      </a-card>
+    </a-col>
+    <vue-waterfall-easy
+      class="adcover_waterfall_container"
+      ref="waterfall"
+      :imgsArr="imgsArr"
+      @click="handleDetail"
+      @scrollReachBottom="getData"
+      style="height: 800px;"
+    >
+      <div class="img-info" slot-scope="props">
+
+        <div class="some-info">
+          <ul>
+            <li>
+              <video height="300px" width="250px" :src=props.value.url></video>
+            </li>
+            <li>
+              <b>发布人:</b>
+              <span>{{props.value.coreUserName}}</span>
+            </li>
+            <!--<li>
+              <b>视频标题:</b>
+              <span>{{props.value.title}}</span>
+            </li>-->
+            <li>
+              <b>播放:</b>
+              <span>{{props.value.play}}</span>
+            </li>
+            <li>
+              <b>分享:</b>
+              <span>{{props.value.share}}</span>
+            </li>
+            <li>
+              <b>评论:</b>
+              <span>{{props.value.comment}}</span>
+            </li>
+            <li>
+              <b>喜欢:</b>
+              <span>{{props.value.likeCnt}}</span>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div slot="waterfall-over">无更多数据</div>
+    </vue-waterfall-easy>
+    <div class="scroll_top">
+      <a-icon type="to-top" />
+    </div>
+  </a-row>
+</template>
+
+<script>
+import { getAction } from '@/api/manage'
+import { filterObj } from '@/utils/util'
+import vueWaterfallEasy from 'vue-waterfall-easy'
+import AppAdModal from './modules/AppAdModal'
+import JTreeSelect from '@/components/jeecg/JTreeSelect'
+import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+import ARow from 'ant-design-vue/es/grid/Row'
+import ACol from 'ant-design-vue/es/grid/Col'
+import AFormItem from 'ant-design-vue/es/form/FormItem'
+import moment from 'moment'
+import $ from 'jquery'
+
+let timeout
+let currentValue
+
+function fetch(value, callback) {
+  if (timeout) {
+    clearTimeout(timeout)
+    timeout = null
+  }
+  currentValue = value
+
+  function fake() {}
+
+  timeout = setTimeout(fake, 300)
+}
+
+$(function() {
+  $('.scroll_top').click(function() {
+    $('.vue-waterfall-easy-scroll').animate(
+      {
+        scrollTop: 0
+      },
+      500
+    )
+    return false
+  })
+  $('.vue-waterfall-easy-scroll').scroll(function() {
+    var top = $('.vue-waterfall-easy-scroll').scrollTop()
+    if (top >= 100) {
+      $('.scroll_top').fadeIn()
+    } else {
+      $('.scroll_top').fadeOut()
+    }
+  })
+})
+
+export default {
+  name: 'waterfall',
+  // mixins:[JeecgListMixin],
+  data() {
+    return {
+      queryParam: {
+        orderByColumn: 'create_time',
+        orderByType: 'desc',
+        start: '',
+        end: ''
+      },
+      time: [],
+      companyData: [],
+      productData: [],
+      value: undefined,
+      imgsArr: [],
+      pageNo: 1, // request param
+      url: {
+        feedsUrl: '/ctop/hot/douyin/feeds',
+        companySugestUrl: '/ctop/kuaishou/advertiser/companysugest',
+        productSugestUrl: '/ctop/kuaishou/advertiser/productsugest',
+        list: '/ctop/hot/douyin/feeds'
+      },
+      validatorRules: {
+        pid: {},
+        name: {},
+        code: {}
+      },
+      pidField: 'pid',
+      isCoverStar: false // 收藏
+    }
+  },
+  components: {
+    AFormItem,
+    ACol,
+    ARow,
+    vueWaterfallEasy,
+    AppAdModal,
+    JTreeSelect
+  },
+  mixins: [JeecgListMixin],
+  methods: {
+    searchQuery() {
+      this.imgsArr = []
+      this.ipagination.current = 1
+      if (this.time != null && this.time.length > 0) {
+        this.queryParam.start = moment(this.time[0]).format('YYYY-MM-DD')
+        this.queryParam.end = moment(this.time[1]).format('YYYY-MM-DD')
+      }
+
+      this.getData()
+    },
+    searchReset() {
+      this.queryParam = {
+        orderByColumn: 'create_time',
+        orderByType: 'desc'
+      }
+      this.imgsArr = []
+      this.time = []
+      this.ipagination.current = 1
+      this.ipagination.pageSize = 20
+      this.getData()
+    },
+    handleProductSearch(value) {
+      getAction(this.url.productSugestUrl, { product: value }).then(res => {
+        console.log(res)
+        if (currentValue === value) {
+          const result = res.result
+          const data = []
+          result.forEach(r => {
+            data.push({
+              value: r,
+              text: r
+            })
+          })
+          this.productData = data
+        }
+      })
+      fetch(value)
+    },
+    handleProductChange(value) {
+      this.value = value
+      fetch(value, data => (this.productData = data))
+    },
+    handleCompanySearch(value) {
+      getAction(this.url.companySugestUrl, { company: value }).then(res => {
+        if (currentValue === value) {
+          const result = res.result
+          const data = []
+          result.forEach(r => {
+            data.push({
+              value: r,
+              text: r
+            })
+          })
+          this.companyData = data
+        }
+      })
+      fetch(value)
+    },
+    handleCompanyChange(value) {
+      this.value = value
+      fetch(value, data => (this.companyData = data))
+    },
+    handleDetail(event, { index, value }) {
+      this.$refs.modalForm.show(value)
+      this.$refs.modalForm.title = '详情'
+    },
+    flushData() {
+      this.imgsArr = []
+      this.pageNo = 1
+      this.getData()
+    },
+    modalFormOk() {},
+    getQueryParams() {
+      //获取查询条件
+      var param = Object.assign(this.queryParam, this.isorter, this.filters)
+      param.pageNo = this.ipagination.current
+      param.pageSize = 20
+      return filterObj(param)
+    },
+    getData() {
+      var params = this.getQueryParams() //查询条件
+      console.log(params)
+      getAction(this.url.feedsUrl, params).then(res => {
+        console.log(res)
+        this.ipagination.current = this.ipagination.current + 1
+        if (res.success) {
+          if (res.result.records.length == 0) {
+            this.$refs.waterfall.waterfallOver()
+            return
+          }
+          for (var i = 0; i < res.result.records.length; i++) {
+            let arr = {};
+            arr.id = res.result.records[i].id;
+            arr.mid = res.result.records[i].mid;
+            arr.title = res.result.records[i].title;
+            arr.play = res.result.records[i].play;
+            arr.share = res.result.records[i].share;
+            arr.comment = res.result.records[i].comment;
+            arr.url = res.result.records[i].url;
+            arr.videoId = res.result.records[i].video_id;
+            arr.coreUserId = res.result.records[i].core_user_id;
+            arr.coreUserName = res.result.records[i].core_user_name;
+            arr.headImageUri = res.result.records[i].head_image_uri;
+            arr.likeCnt = res.result.records[i].like_cnt;
+            arr.createTime = res.result.records[i].createTime
+            this.imgsArr = this.imgsArr.concat(arr)
+          }
+        }
+      })
+    }
+  },
+  created() {
+    this.getData()
+  }
+}
+</script>
+
+
+<style lang="scss">
+.adcover_waterfall_container {
+  .img-box {
+    .img-inner-box {
+      position: relative;
+      cursor: pointer;
+
+      -webkit-transition: all 0.3s;
+      transition: all 0.3s;
+      .img-wraper {
+        // height: 427px!important;
+        img {
+        }
+      }
+      .img-info {
+        position: relative;
+        // height: 146px!important;
+        .some-info {
+          color: rgba(0, 0, 0, 0.65);
+          padding: 10px;
+          ul {
+            margin: 0;
+            padding: 0;
+            li {
+              list-style: none;
+              padding: 0;
+              margin: 0;
+            }
+          }
+        }
+        .cover_star {
+          position: absolute;
+          right: 0;
+          bottom: 0;
+          padding: 10px;
+          z-index: 1;
+          color: rgba(0, 0, 0, 0.65);
+          .coverStar {
+            color: red;
+          }
+        }
+      }
+    }
+  }
+}
+.scroll_top {
+  position: fixed;
+  z-index: 9;
+  right: 80px;
+  bottom: 40px;
+  display: none;
+  cursor: pointer;
+  color: #1890ff;
+  font-size: 40px;
+}
+</style>
+<style>
+.list-pubu .ball-beat {
+  height: 100px;
+}
+.list-pubu .loading {
+  position: fixed !important;
+  z-index: 10 !important;
+  left: 60% !important;
+  bottom: 0 !important;
+}
+.sider.light {
+  z-index: 11;
+}
+</style>

+ 371 - 0
src/views/oceanengine/EffectCaseList.vue

@@ -0,0 +1,371 @@
+<template>
+  <a-row :gutter="10" class="list-pubu">
+    <a-col :sm="24" style="margin-bottom: 20px;z-index: 10">
+      <a-card :bordered="false">
+        <div class="table-page-search-wrapper">
+          <a-form layout="inline">
+            <a-row :gutter="24">
+              <a-col :md="8" :sm="8">
+                <a-form-item label="发布人">
+                  <a-input placeholder="请输入发布人昵称" v-model="queryParam.userName"></a-input>
+                </a-form-item>
+              </a-col>
+            </a-row>
+            <a-row :gutter="24">
+              <a-col :md="10" :sm="10">
+                <a-form-item label="排序">
+                  <a-radio-group v-model="queryParam.orderByColumn">
+                    <a-radio-button value="create_time">按抓取时间</a-radio-button>
+                    <a-radio-button value="creative_score">按创意评分</a-radio-button>
+                  </a-radio-group>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="6">
+                <a-form-item>
+                  <a-radio-group v-model="queryParam.orderByType">
+                    <a-radio-button value="asc">正序</a-radio-button>
+                    <a-radio-button value="desc">倒序</a-radio-button>
+                  </a-radio-group>
+                </a-form-item>
+              </a-col>
+              <a-col :md="8" :sm="8">
+                <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+                <a-button
+                  type="primary"
+                  @click="searchReset"
+                  icon="reload"
+                  style="margin-left: 8px"
+                >重置</a-button>
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <effect-case-modal ref="modalForm"></effect-case-modal>
+      </a-card>
+    </a-col>
+    <vue-waterfall-easy
+      class="adcover_waterfall_container"
+      ref="waterfall"
+      :imgsArr="imgsArr"
+      @click="handleDetail"
+      @scrollReachBottom="getData"
+      style="height: 800px;"
+    >
+      <div class="img-info" slot-scope="props">
+
+        <div class="some-info">
+          <ul>
+            <li>
+              <video height="300px" width="250px" :src=props.value.video_url></video>
+            </li>
+            <li>
+              <b>发布人:</b>
+              <span>{{props.value.author}}</span>
+            </li>
+            <!--<li>
+              <b>视频标题:</b>
+              <span>{{props.value.title}}</span>
+            </li>-->
+            <li>
+              <b>转化类型:</b>
+              <span>{{props.value.conversion_type}}</span>
+            </li>
+            <li>
+              <b>创意评分:</b>
+              <span>{{props.value.creative_score}}</span>
+            </li>
+            <li>
+              <b>行业标签:</b>
+              <span>{{props.value.industry_tag}}</span>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div slot="waterfall-over">无更多数据</div>
+    </vue-waterfall-easy>
+    <div class="scroll_top">
+      <a-icon type="to-top" />
+    </div>
+  </a-row>
+</template>
+
+<script>
+import { getAction } from '@/api/manage'
+import { filterObj } from '@/utils/util'
+import vueWaterfallEasy from 'vue-waterfall-easy'
+import EffectCaseModal from './modules/EffectCaseModal'
+import JTreeSelect from '@/components/jeecg/JTreeSelect'
+import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+import ARow from 'ant-design-vue/es/grid/Row'
+import ACol from 'ant-design-vue/es/grid/Col'
+import AFormItem from 'ant-design-vue/es/form/FormItem'
+import moment from 'moment'
+import $ from 'jquery'
+
+let timeout
+let currentValue
+
+function fetch(value, callback) {
+  if (timeout) {
+    clearTimeout(timeout)
+    timeout = null
+  }
+  currentValue = value
+
+  function fake() {}
+
+  timeout = setTimeout(fake, 300)
+}
+
+$(function() {
+  $('.scroll_top').click(function() {
+    $('.vue-waterfall-easy-scroll').animate(
+      {
+        scrollTop: 0
+      },
+      500
+    )
+    return false
+  })
+  $('.vue-waterfall-easy-scroll').scroll(function() {
+    var top = $('.vue-waterfall-easy-scroll').scrollTop()
+    if (top >= 100) {
+      $('.scroll_top').fadeIn()
+    } else {
+      $('.scroll_top').fadeOut()
+    }
+  })
+})
+
+export default {
+  name: 'waterfall',
+  // mixins:[JeecgListMixin],
+  data() {
+    return {
+      queryParam: {
+        orderByColumn: 'create_time',
+        orderByType: 'desc',
+        start: '',
+        end: ''
+      },
+      time: [],
+      companyData: [],
+      productData: [],
+      value: undefined,
+      imgsArr: [],
+      pageNo: 1, // request param
+      url: {
+        feedsUrl: '/ctop/hot/effectcase/feeds',
+        companySugestUrl: '/ctop/kuaishou/advertiser/companysugest',
+        productSugestUrl: '/ctop/kuaishou/advertiser/productsugest',
+        list: '/ctop/hot/effectcase/feeds'
+      },
+      validatorRules: {
+        pid: {},
+        name: {},
+        code: {}
+      },
+      pidField: 'pid',
+      isCoverStar: false // 收藏
+    }
+  },
+  components: {
+    AFormItem,
+    ACol,
+    ARow,
+    vueWaterfallEasy,
+    EffectCaseModal,
+    JTreeSelect
+  },
+  mixins: [JeecgListMixin],
+  methods: {
+    searchQuery() {
+      this.imgsArr = []
+      this.ipagination.current = 1
+      if (this.time != null && this.time.length > 0) {
+        this.queryParam.start = moment(this.time[0]).format('YYYY-MM-DD')
+        this.queryParam.end = moment(this.time[1]).format('YYYY-MM-DD')
+      }
+
+      this.getData()
+    },
+    searchReset() {
+      this.queryParam = {
+        orderByColumn: 'create_time',
+        orderByType: 'desc'
+      }
+      this.imgsArr = [];
+      this.time = [];
+      this.ipagination.current = 1;
+      this.ipagination.pageSize = 20;
+      this.getData();
+    },
+    handleProductSearch(value) {
+      getAction(this.url.productSugestUrl, { product: value }).then(res => {
+        console.log(res)
+        if (currentValue === value) {
+          const result = res.result
+          const data = []
+          result.forEach(r => {
+            data.push({
+              value: r,
+              text: r
+            })
+          })
+          this.productData = data
+        }
+      })
+      fetch(value)
+    },
+    handleProductChange(value) {
+      this.value = value
+      fetch(value, data => (this.productData = data))
+    },
+    handleCompanySearch(value) {
+      getAction(this.url.companySugestUrl, { company: value }).then(res => {
+        if (currentValue === value) {
+          const result = res.result
+          const data = []
+          result.forEach(r => {
+            data.push({
+              value: r,
+              text: r
+            })
+          })
+          this.companyData = data
+        }
+      })
+      fetch(value)
+    },
+    handleCompanyChange(value) {
+      this.value = value
+      fetch(value, data => (this.companyData = data))
+    },
+    handleDetail(event, { index, value }) {
+      this.$refs.modalForm.show(value);
+      this.$refs.modalForm.title = '详情'
+    },
+    flushData() {
+      this.imgsArr = []
+      this.pageNo = 1
+      this.getData()
+    },
+    modalFormOk() {},
+    getQueryParams() {
+      //获取查询条件
+      var param = Object.assign(this.queryParam, this.isorter, this.filters);
+      param.pageNo = this.ipagination.current;
+      param.pageSize = 20;
+      return filterObj(param)
+    },
+    getData() {
+      var params = this.getQueryParams(); //查询条件
+      console.log(params);
+      getAction(this.url.feedsUrl, params).then(res => {
+        console.log(res)
+        this.ipagination.current = this.ipagination.current + 1
+        if (res.success) {
+          if (res.result.records.length == 0) {
+            this.$refs.waterfall.waterfallOver()
+            return
+          }
+          for (var i = 0; i < res.result.records.length; i++) {
+            let arr = {};
+            arr.id = res.result.records[i].id;
+            arr.vid = res.result.records[i].vid;
+            arr.author = res.result.records[i].author;
+            arr.createTime = res.result.records[i].createTime;
+            arr.updateTime = res.result.records[i].updateTime;
+            arr.creativeLabel = res.result.records[i].creativeLabel;
+            arr.create_date = res.result.records[i].create_date;
+            arr.creative_id = res.result.records[i].creative_id;
+            arr.video_url = res.result.records[i].video_url;
+            arr.conversion_type = res.result.records[i].conversion_type;
+            arr.creative_title = res.result.records[i].creative_title;
+            arr.creative_info = res.result.records[i].creative_info;
+            arr.creative_score = res.result.records[i].creative_score;
+            arr.industry_tag = res.result.records[i].industry_tag;
+            arr.effect = res.result.records[i].effect;
+            this.imgsArr = this.imgsArr.concat(arr)
+          }
+        }
+      })
+    }
+  },
+  created() {
+    this.getData()
+  }
+}
+</script>
+
+
+<style lang="scss">
+.adcover_waterfall_container {
+  .img-box {
+    .img-inner-box {
+      position: relative;
+      cursor: pointer;
+
+      -webkit-transition: all 0.3s;
+      transition: all 0.3s;
+      .img-wraper {
+        // height: 427px!important;
+        img {
+        }
+      }
+      .img-info {
+        position: relative;
+        // height: 146px!important;
+        .some-info {
+          color: rgba(0, 0, 0, 0.65);
+          padding: 10px;
+          ul {
+            margin: 0;
+            padding: 0;
+            li {
+              list-style: none;
+              padding: 0;
+              margin: 0;
+            }
+          }
+        }
+        .cover_star {
+          position: absolute;
+          right: 0;
+          bottom: 0;
+          padding: 10px;
+          z-index: 1;
+          color: rgba(0, 0, 0, 0.65);
+          .coverStar {
+            color: red;
+          }
+        }
+      }
+    }
+  }
+}
+.scroll_top {
+  position: fixed;
+  z-index: 9;
+  right: 80px;
+  bottom: 40px;
+  display: none;
+  cursor: pointer;
+  color: #1890ff;
+  font-size: 40px;
+}
+</style>
+<style>
+.list-pubu .ball-beat {
+  height: 100px;
+}
+.list-pubu .loading {
+  position: fixed !important;
+  z-index: 10 !important;
+  left: 60% !important;
+  bottom: 0 !important;
+}
+.sider.light {
+  z-index: 11;
+}
+</style>

+ 367 - 0
src/views/oceanengine/HotMaterialList.vue

@@ -0,0 +1,367 @@
+<template>
+  <a-row :gutter="10" class="list-pubu">
+    <a-col :sm="24" style="margin-bottom: 20px;z-index: 10">
+      <a-card :bordered="false">
+        <div class="table-page-search-wrapper">
+          <a-form layout="inline">
+            <!--<a-row :gutter="24">
+              &lt;!&ndash;<a-col :md="8" :sm="8">
+                <a-form-item
+                  label="抓取日期"
+                  :labelCol="{lg: {span: 7}, sm: {span: 7}}"
+                  :wrapperCol="{lg: {span: 10}, sm: {span: 17} }"
+                >
+                  <a-range-picker name="buildTime" style="width: 100%" v-model="time" />
+                </a-form-item>
+              </a-col>&ndash;&gt;
+              <a-col :md="8" :sm="8">
+                <a-form-item label="发布人">
+                  <a-input placeholder="请输入发布人昵称" v-model="queryParam.userName"></a-input>
+                </a-form-item>
+              </a-col>
+            </a-row>-->
+            <a-row :gutter="24">
+              <a-col :md="10" :sm="10">
+                <a-form-item label="排序">
+                  <a-radio-group v-model="queryParam.orderByColumn">
+                    <a-radio-button value="create_time">按抓取时间</a-radio-button>
+                    <!--<a-radio-button value="play">按播放数</a-radio-button>
+                    <a-radio-button value="like_cnt">按喜欢数</a-radio-button>
+                    <a-radio-button value="comment">按评论数</a-radio-button>-->
+                  </a-radio-group>
+                </a-form-item>
+              </a-col>
+              <a-col :md="6" :sm="6">
+                <a-form-item>
+                  <a-radio-group v-model="queryParam.orderByType">
+                    <a-radio-button value="asc">正序</a-radio-button>
+                    <a-radio-button value="desc">倒序</a-radio-button>
+                  </a-radio-group>
+                </a-form-item>
+              </a-col>
+              <a-col :md="8" :sm="8">
+                <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+                <a-button
+                  type="primary"
+                  @click="searchReset"
+                  icon="reload"
+                  style="margin-left: 8px"
+                >重置</a-button>
+              </a-col>
+            </a-row>
+          </a-form>
+        </div>
+        <hot-material-modal ref="modalForm"></hot-material-modal>
+      </a-card>
+    </a-col>
+    <vue-waterfall-easy
+      class="adcover_waterfall_container"
+      ref="waterfall"
+      :imgsArr="imgsArr"
+      @click="handleDetail"
+      @scrollReachBottom="getData"
+      style="height: 800px;"
+    >
+      <div class="img-info" slot-scope="props">
+
+        <div class="some-info">
+          <ul>
+            <li>
+              <video height="300px" width="250px" :src=props.value.videoUrl></video>
+            </li>
+            <li>
+              <b>标题:</b>
+              <span>{{props.value.title}}</span>
+            </li>
+            <li>
+              <b>媒体类型:</b>
+              <span>{{props.value.appName}}</span>
+            </li>
+            <li>
+              <b>抓取时间:</b>
+              <span>{{props.value.createTime}}</span>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div slot="waterfall-over">无更多数据</div>
+    </vue-waterfall-easy>
+    <div class="scroll_top">
+      <a-icon type="to-top" />
+    </div>
+  </a-row>
+</template>
+
+<script>
+import { getAction } from '@/api/manage'
+import { filterObj } from '@/utils/util'
+import vueWaterfallEasy from 'vue-waterfall-easy'
+import HotMaterialModal from './modules/HotMaterialModal'
+import JTreeSelect from '@/components/jeecg/JTreeSelect'
+import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+import ARow from 'ant-design-vue/es/grid/Row'
+import ACol from 'ant-design-vue/es/grid/Col'
+import AFormItem from 'ant-design-vue/es/form/FormItem'
+import moment from 'moment'
+import $ from 'jquery'
+
+let timeout
+let currentValue
+
+function fetch(value, callback) {
+  if (timeout) {
+    clearTimeout(timeout)
+    timeout = null
+  }
+  currentValue = value
+
+  function fake() {}
+
+  timeout = setTimeout(fake, 300)
+}
+
+$(function() {
+  $('.scroll_top').click(function() {
+    $('.vue-waterfall-easy-scroll').animate(
+      {
+        scrollTop: 0
+      },
+      500
+    )
+    return false
+  })
+  $('.vue-waterfall-easy-scroll').scroll(function() {
+    var top = $('.vue-waterfall-easy-scroll').scrollTop()
+    if (top >= 100) {
+      $('.scroll_top').fadeIn()
+    } else {
+      $('.scroll_top').fadeOut()
+    }
+  })
+})
+
+export default {
+  name: 'waterfall',
+  // mixins:[JeecgListMixin],
+  data() {
+    return {
+      queryParam: {
+        orderByColumn: 'create_time',
+        orderByType: 'desc',
+        start: '',
+        end: ''
+      },
+      time: [],
+      companyData: [],
+      productData: [],
+      value: undefined,
+      imgsArr: [],
+      pageNo: 1, // request param
+      url: {
+        feedsUrl: '/ctop/hot/material/feeds',
+        companySugestUrl: '/ctop/kuaishou/advertiser/companysugest',
+        productSugestUrl: '/ctop/kuaishou/advertiser/productsugest',
+        list: '/ctop/hot/material/feeds'
+      },
+      validatorRules: {
+        pid: {},
+        name: {},
+        code: {}
+      },
+      pidField: 'pid',
+      isCoverStar: false // 收藏
+    }
+  },
+  components: {
+    AFormItem,
+    ACol,
+    ARow,
+    vueWaterfallEasy,
+    HotMaterialModal,
+    JTreeSelect
+  },
+  mixins: [JeecgListMixin],
+  methods: {
+    searchQuery() {
+      this.imgsArr = []
+      this.ipagination.current = 1
+      if (this.time != null && this.time.length > 0) {
+        this.queryParam.start = moment(this.time[0]).format('YYYY-MM-DD')
+        this.queryParam.end = moment(this.time[1]).format('YYYY-MM-DD')
+      }
+
+      this.getData()
+    },
+    searchReset() {
+      this.queryParam = {
+        orderByColumn: 'create_time',
+        orderByType: 'desc'
+      }
+      this.imgsArr = []
+      this.time = []
+      this.ipagination.current = 1
+      this.ipagination.pageSize = 20
+      this.getData()
+    },
+    handleProductSearch(value) {
+      getAction(this.url.productSugestUrl, { product: value }).then(res => {
+        console.log(res)
+        if (currentValue === value) {
+          const result = res.result
+          const data = []
+          result.forEach(r => {
+            data.push({
+              value: r,
+              text: r
+            })
+          })
+          this.productData = data
+        }
+      })
+      fetch(value)
+    },
+    handleProductChange(value) {
+      this.value = value
+      fetch(value, data => (this.productData = data))
+    },
+    handleCompanySearch(value) {
+      getAction(this.url.companySugestUrl, { company: value }).then(res => {
+        if (currentValue === value) {
+          const result = res.result
+          const data = []
+          result.forEach(r => {
+            data.push({
+              value: r,
+              text: r
+            })
+          })
+          this.companyData = data
+        }
+      })
+      fetch(value)
+    },
+    handleCompanyChange(value) {
+      this.value = value
+      fetch(value, data => (this.companyData = data))
+    },
+    handleDetail(event, { index, value }) {
+      this.$refs.modalForm.show(value)
+      this.$refs.modalForm.title = '详情'
+    },
+    flushData() {
+      this.imgsArr = []
+      this.pageNo = 1
+      this.getData()
+    },
+    modalFormOk() {},
+    getQueryParams() {
+      //获取查询条件
+      var param = Object.assign(this.queryParam, this.isorter, this.filters)
+      param.pageNo = this.ipagination.current
+      param.pageSize = 20
+      return filterObj(param)
+    },
+    getData() {
+      var params = this.getQueryParams() //查询条件
+      console.log(params)
+      getAction(this.url.feedsUrl, params).then(res => {
+        console.log(res)
+        this.ipagination.current = this.ipagination.current + 1
+        if (res.success) {
+          if (res.result.records.length == 0) {
+            this.$refs.waterfall.waterfallOver()
+            return
+          }
+          for (var i = 0; i < res.result.records.length; i++) {
+            let arr = {};
+            arr.id = res.result.records[i].id;
+            arr.vid = res.result.records[i].vid;
+            arr.videoUrl = res.result.records[i].videoUrl;
+            arr.title = res.result.records[i].title;
+            arr.appCode = res.result.records[i].appCode;
+            arr.appName = res.result.records[i].appName;
+            arr.createTime = res.result.records[i].createTime;
+            arr.updateTime = res.result.records[i].updateTime;
+            this.imgsArr = this.imgsArr.concat(arr)
+          }
+        }
+      })
+    }
+  },
+  created() {
+    this.getData()
+  }
+}
+</script>
+
+
+<style lang="scss">
+.adcover_waterfall_container {
+  .img-box {
+    .img-inner-box {
+      position: relative;
+      cursor: pointer;
+
+      -webkit-transition: all 0.3s;
+      transition: all 0.3s;
+      .img-wraper {
+        // height: 427px!important;
+        img {
+        }
+      }
+      .img-info {
+        position: relative;
+        // height: 146px!important;
+        .some-info {
+          color: rgba(0, 0, 0, 0.65);
+          padding: 10px;
+          ul {
+            margin: 0;
+            padding: 0;
+            li {
+              list-style: none;
+              padding: 0;
+              margin: 0;
+            }
+          }
+        }
+        .cover_star {
+          position: absolute;
+          right: 0;
+          bottom: 0;
+          padding: 10px;
+          z-index: 1;
+          color: rgba(0, 0, 0, 0.65);
+          .coverStar {
+            color: red;
+          }
+        }
+      }
+    }
+  }
+}
+.scroll_top {
+  position: fixed;
+  z-index: 9;
+  right: 80px;
+  bottom: 40px;
+  display: none;
+  cursor: pointer;
+  color: #1890ff;
+  font-size: 40px;
+}
+</style>
+<style>
+.list-pubu .ball-beat {
+  height: 100px;
+}
+.list-pubu .loading {
+  position: fixed !important;
+  z-index: 10 !important;
+  left: 60% !important;
+  bottom: 0 !important;
+}
+.sider.light {
+  z-index: 11;
+}
+</style>

二进制
src/views/oceanengine/images/arrow_left.png


二进制
src/views/oceanengine/images/arrow_right.png


+ 350 - 0
src/views/oceanengine/modules/AppAdModal.vue

@@ -0,0 +1,350 @@
+<template>
+  <a-modal
+    :title="title"
+    :width="1300"
+    :visible="visible"
+    @cancel="handleCancel"
+    cancelText="关闭"
+    class="ad_cover_container"
+  >
+    <div>
+      <a-row>
+        <a-col :span="8" class="addetail_left">
+          <a-tabs :defaultActiveKey="defaultActiveKey">
+            <a-tab-pane tab="视频" key="1">
+              <div class="item">
+                <div class="player">
+                  <video-player
+                    class="vjs-custom-skin"
+                    ref="videoPlayer"
+                    :options="playerOptions"
+                    :playsinline="true"
+                    @play="onPlayerPlay($event)"
+                    @pause="onPlayerPause($event)"
+                    @ended="onPlayerEnded($event)"
+                    @loadeddata="onPlayerLoadeddata($event)"
+                    @waiting="onPlayerWaiting($event)"
+                    @playing="onPlayerPlaying($event)"
+                    @timeupdate="onPlayerTimeupdate($event)"
+                    @canplay="onPlayerCanplay($event)"
+                    @canplaythrough="onPlayerCanplaythrough($event)"
+                    @ready="playerReadied"
+                    @statechanged="playerStateChanged($event)"
+                  ></video-player>
+                </div>
+              </div>
+            </a-tab-pane>
+          </a-tabs>
+        </a-col>
+        <a-col :span="16" class="addetail_right">
+          <div v-if="videoModel != null">
+            <detail-list :col="1">
+              <detail-list-item term="标题">{{videoModel.title}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+              <detail-list-item term="快手视频ID">
+                <a :href="[videoModel.url]" target="_blank">{{videoModel.videoId}}</a>
+              </detail-list-item>
+            </detail-list>
+              <!--<detail-list-item term="发布时间">{{videoModel.time}}</detail-list-item>-->
+            <detail-list :col="1">
+              <detail-list-item term="抓取时间">{{videoModel.createTime}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+              <detail-list-item term="播放数">{{videoModel.play}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+            <detail-list-item term="喜欢数">{{videoModel.likeCnt}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+              <detail-list-item term="评论数">{{videoModel.comment}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+              <detail-list-item term="分享数">{{videoModel.share}}</detail-list-item>
+            </detail-list>
+          </div>
+        </a-col>
+      </a-row>
+    </div>
+  </a-modal>
+</template>
+<script>
+// custom skin css
+// import '../src/custom-theme.css'
+import 'video.js/dist/video-js.css'
+import { videoPlayer } from 'vue-video-player'
+import DetailList from '@/components/tools/DetailList'
+import PageLayout from '@/components/page/PageLayout'
+import STable from '@/components/table/'
+import { getAction, deleteAction, putAction, postAction } from '@/api/manage'
+
+const DetailListItem = DetailList.Item;
+export default {
+  components: {
+    videoPlayer,
+    PageLayout,
+    DetailList,
+    DetailListItem,
+    STable
+  },
+  data() {
+    return {
+      goodsColumns: [
+        {
+          title: '封面ID',
+          dataIndex: 'coverId',
+          key: 'coverId'
+        },
+        {
+          title: '封面预览',
+          //   dataIndex: 'coverUrl',
+          //   key: 'coverUrl',
+          dataIndex: 'ADcoverImagePreview',
+          scopedSlots: { customRender: 'ADcoverImagePreview' }
+        },
+        {
+          title: '创意ID',
+          dataIndex: 'creativeId',
+          key: 'creativeId'
+        },
+        {
+          title: '展示数',
+          dataIndex: 'viewCount',
+          key: 'viewCount'
+        },
+        {
+          title: '喜欢数',
+          dataIndex: 'likeCount',
+          key: 'likeCount'
+        },
+        {
+          title: '评论数',
+          dataIndex: 'commentCount',
+          key: 'commentCount'
+        },
+        {
+          title: '质量分',
+          dataIndex: 'score',
+          key: 'score'
+        },
+        {
+          title: 'App名称',
+          dataIndex: 'appName',
+          key: 'appName'
+        },
+        {
+          title: '发布时间',
+          dataIndex: 'time',
+          key: 'time'
+        }
+      ],
+      userId: 0,
+      photoId: 0,
+      title: '操作',
+      visible: false,
+      model: [],
+      userModel: {},
+      videoModel: {},
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      },
+      // videojs options
+      playerOptions: {
+        height: '640',
+        width: '360',
+        autoplay: false,
+        muted: true,
+        language: 'en',
+        playbackRates: [0.7, 1.0, 1.5, 2.0],
+        sources: [
+          {
+            type: 'video/mp4',
+            // mp4
+            src: ''
+            // webm
+            // src: "https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm"
+          }
+        ],
+        poster: ''
+      },
+      loadGoodsData: () => {
+        var params = {
+          photoId: this.photoId,
+          userId: this.userId
+        }
+        return getAction('/ctop/adcover/adlist', params).then(res => {
+          this.model = res.result
+          console.log(res.result)
+          return res.result
+        })
+      },
+      defaultActiveKey: '1',
+
+      //   封面预览弹窗
+      coverPreviewVisible: false,
+      coverPreviewMaskStyle: {
+        background: 'rgba(0,0,0,.08)'
+      },
+      coverPreviewUrl: ''
+    }
+  },
+  mounted() {
+    // console.log('this is current player instance object', this.player)
+    setTimeout(() => {
+      console.log('dynamic change options', this.player)
+      // change src
+      // this.playerOptions.sources[0].src = 'https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm';
+      // change item
+      // this.$set(this.playerOptions.sources, 0, {
+      //   type: "video/mp4",
+      //   src: 'https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm',
+      // })
+      // change array
+      // this.playerOptions.sources = [{
+      //   type: "video/mp4",
+      //   src: 'https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm',
+      // }]
+      this.player.muted(false)
+    }, 5000)
+  },
+  computed: {
+    // player() {
+    //   return this.$refs.videoPlayer.player
+    // }
+  },
+  methods: {
+    // listen event
+    onPlayerPlay(player) {
+      // console.log('player play!', player)
+    },
+    onPlayerPause(player) {
+      // console.log('player pause!', player)
+    },
+    onPlayerEnded(player) {
+      // console.log('player ended!', player)
+    },
+    onPlayerLoadeddata(player) {
+      // console.log('player Loadeddata!', player)
+    },
+    onPlayerWaiting(player) {
+      // console.log('player Waiting!', player)
+    },
+    onPlayerPlaying(player) {
+      // console.log('player Playing!', player)
+    },
+    onPlayerTimeupdate(player) {
+      // console.log('player Timeupdate!', player.currentTime())
+    },
+    onPlayerCanplay(player) {
+      // console.log('player Canplay!', player)
+    },
+    onPlayerCanplaythrough(player) {
+      // console.log('player Canplaythrough!', player)
+    },
+    // or listen state event
+    playerStateChanged(playerCurrentState) {
+      // console.log('player current update state', playerCurrentState)
+    },
+    // player is ready
+    playerReadied(player) {
+      // seek to 10s
+      console.log('example player 1 readied', player)
+      // player.currentTime(10)
+      // console.log('example 01: the player is readied', player)
+    },
+    show(value) {
+      this.model = [];
+      this.userModel = {};
+      this.videoModel = {};
+      this.playerOptions.sources[0].src = '';
+      this.loadDetail(value);
+      this.visible = true;
+      this.defaultActiveKey = '1'
+    },
+    loadDetail(value) {
+      this.videoModel = value
+      this.playerOptions.sources[0].src = value.url;
+    },
+    close() {
+      this.$emit('close')
+      this.visible = false
+      this.defaultActiveKey = '1'
+    },
+    handleCancel() {
+      this.close()
+      this.defaultActiveKey = '1'
+    },
+
+    // 封面预览弹窗
+    coverPreviewShowModal(record) {
+      this.coverPreviewVisible = true
+      this.coverPreviewUrl = record.coverUrl
+      this.coverPreviewMaskStyle.background = 'rgba(0,0,0,.08)'
+    },
+    coverPreviewHandleOk() {
+      this.coverPreviewVisible = false
+      this.coverPreviewMaskStyle.background = 'rgba(0,0,0,0)'
+    },
+    coverPreviewHandleCancel() {
+      this.coverPreviewVisible = false
+      this.coverPreviewUrl = ''
+      this.coverPreviewMaskStyle.background = 'rgba(0,0,0,0)'
+    }
+  }
+}
+</script>
+<style lang="scss">
+.ant-carousel >>> .slick-slide {
+  text-align: center;
+  //   height: 160px;
+  //   line-height: 160px;
+  background: #364d79;
+  overflow: hidden;
+}
+
+.ad_cover_container .ant-card-body {
+  padding: 0;
+}
+
+.ant-carousel >>> .slick-slide h3 {
+  color: #fff;
+}
+.ant-carousel >>> .custom-slick-arrow {
+  width: 25px;
+  height: 25px;
+  font-size: 25px;
+  color: #fff;
+  background-color: rgba(31, 45, 61, 0.11);
+  opacity: 0.3;
+}
+.ant-carousel >>> .custom-slick-arrow:before {
+  display: none;
+}
+.ant-carousel >>> .custom-slick-arrow:hover {
+  opacity: 0.5;
+}
+.addetail_left {
+  padding-right: 56px;
+  .custom-slick-arrow {
+    width: 40px;
+    height: 40px;
+  }
+  .slick_arrow_left {
+    background: url(../images/arrow_left.png);
+  }
+  .slick_arrow_right {
+    background: url(../images/arrow_right.png);
+  }
+    .slick_arrow_left:hover {
+    background: url(../images/arrow_left.png)!important;
+  }
+  .slick_arrow_right:hover {
+    background: url(../images/arrow_right.png)!important;
+  }
+}
+</style>

+ 362 - 0
src/views/oceanengine/modules/EffectCaseModal.vue

@@ -0,0 +1,362 @@
+<template>
+  <a-modal
+    :title="title"
+    :width="1300"
+    :visible="visible"
+    @cancel="handleCancel"
+    cancelText="关闭"
+    class="ad_cover_container"
+  >
+    <div>
+      <a-row>
+        <a-col :span="8" class="addetail_left">
+          <a-tabs :defaultActiveKey="defaultActiveKey">
+            <a-tab-pane tab="视频" key="1">
+              <div class="item">
+                <div class="player">
+                  <video-player
+                    class="vjs-custom-skin"
+                    ref="videoPlayer"
+                    :options="playerOptions"
+                    :playsinline="true"
+                    @play="onPlayerPlay($event)"
+                    @pause="onPlayerPause($event)"
+                    @ended="onPlayerEnded($event)"
+                    @loadeddata="onPlayerLoadeddata($event)"
+                    @waiting="onPlayerWaiting($event)"
+                    @playing="onPlayerPlaying($event)"
+                    @timeupdate="onPlayerTimeupdate($event)"
+                    @canplay="onPlayerCanplay($event)"
+                    @canplaythrough="onPlayerCanplaythrough($event)"
+                    @ready="playerReadied"
+                    @statechanged="playerStateChanged($event)"
+                  ></video-player>
+                </div>
+              </div>
+            </a-tab-pane>
+          </a-tabs>
+        </a-col>
+        <a-col :span="16" class="addetail_right">
+          <div v-if="videoModel != null">
+            <detail-list :col="1">
+              <detail-list-item term="创意标题">{{videoModel.creative_title}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+              <detail-list-item term="创意内容">{{videoModel.creative_info}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+              <detail-list-item term="创意标签">{{videoModel.creativeLabel}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+              <detail-list-item term="创意分数">{{videoModel.creative_score}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+              <detail-list-item term="视频ID">
+                <a :href="[videoModel.video_url]" target="_blank">{{videoModel.vid}}</a>
+              </detail-list-item>
+            </detail-list>
+              <!--<detail-list-item term="发布时间">{{videoModel.time}}</detail-list-item>-->
+            <detail-list :col="1">
+              <detail-list-item term="发布人">{{videoModel.author}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+              <detail-list-item term="发布时间">{{videoModel.create_date}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+              <detail-list-item term="效果">{{videoModel.effect}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+            <detail-list-item term="转化类型">{{videoModel.conversion_type}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+              <detail-list-item term="行业标签">{{videoModel.industry_tag}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+              <detail-list-item term="抓取时间">{{videoModel.createTime}}</detail-list-item>
+            </detail-list>
+          </div>
+        </a-col>
+      </a-row>
+    </div>
+  </a-modal>
+</template>
+<script>
+// custom skin css
+// import '../src/custom-theme.css'
+import 'video.js/dist/video-js.css'
+import { videoPlayer } from 'vue-video-player'
+import DetailList from '@/components/tools/DetailList'
+import PageLayout from '@/components/page/PageLayout'
+import STable from '@/components/table/'
+import { getAction, deleteAction, putAction, postAction } from '@/api/manage'
+
+const DetailListItem = DetailList.Item;
+export default {
+  components: {
+    videoPlayer,
+    PageLayout,
+    DetailList,
+    DetailListItem,
+    STable
+  },
+  data() {
+    return {
+      goodsColumns: [
+        {
+          title: '封面ID',
+          dataIndex: 'coverId',
+          key: 'coverId'
+        },
+        {
+          title: '封面预览',
+          //   dataIndex: 'coverUrl',
+          //   key: 'coverUrl',
+          dataIndex: 'ADcoverImagePreview',
+          scopedSlots: { customRender: 'ADcoverImagePreview' }
+        },
+        {
+          title: '创意ID',
+          dataIndex: 'creativeId',
+          key: 'creativeId'
+        },
+        {
+          title: '展示数',
+          dataIndex: 'viewCount',
+          key: 'viewCount'
+        },
+        {
+          title: '喜欢数',
+          dataIndex: 'likeCount',
+          key: 'likeCount'
+        },
+        {
+          title: '评论数',
+          dataIndex: 'commentCount',
+          key: 'commentCount'
+        },
+        {
+          title: '质量分',
+          dataIndex: 'score',
+          key: 'score'
+        },
+        {
+          title: 'App名称',
+          dataIndex: 'appName',
+          key: 'appName'
+        },
+        {
+          title: '发布时间',
+          dataIndex: 'time',
+          key: 'time'
+        }
+      ],
+      userId: 0,
+      photoId: 0,
+      title: '操作',
+      visible: false,
+      model: [],
+      userModel: {},
+      videoModel: {},
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      },
+      // videojs options
+      playerOptions: {
+        height: '640',
+        width: '360',
+        autoplay: false,
+        muted: true,
+        language: 'en',
+        playbackRates: [0.7, 1.0, 1.5, 2.0],
+        sources: [
+          {
+            type: 'video/mp4',
+            // mp4
+            src: ''
+            // webm
+            // src: "https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm"
+          }
+        ],
+        poster: ''
+      },
+      loadGoodsData: () => {
+        var params = {
+          photoId: this.photoId,
+          userId: this.userId
+        }
+        return getAction('/ctop/adcover/adlist', params).then(res => {
+          this.model = res.result
+          console.log(res.result)
+          return res.result
+        })
+      },
+      defaultActiveKey: '1',
+
+      //   封面预览弹窗
+      coverPreviewVisible: false,
+      coverPreviewMaskStyle: {
+        background: 'rgba(0,0,0,.08)'
+      },
+      coverPreviewUrl: ''
+    }
+  },
+  mounted() {
+    // console.log('this is current player instance object', this.player)
+    setTimeout(() => {
+      console.log('dynamic change options', this.player)
+      // change src
+      // this.playerOptions.sources[0].src = 'https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm';
+      // change item
+      // this.$set(this.playerOptions.sources, 0, {
+      //   type: "video/mp4",
+      //   src: 'https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm',
+      // })
+      // change array
+      // this.playerOptions.sources = [{
+      //   type: "video/mp4",
+      //   src: 'https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm',
+      // }]
+      this.player.muted(false)
+    }, 5000)
+  },
+  computed: {
+    // player() {
+    //   return this.$refs.videoPlayer.player
+    // }
+  },
+  methods: {
+    // listen event
+    onPlayerPlay(player) {
+      // console.log('player play!', player)
+    },
+    onPlayerPause(player) {
+      // console.log('player pause!', player)
+    },
+    onPlayerEnded(player) {
+      // console.log('player ended!', player)
+    },
+    onPlayerLoadeddata(player) {
+      // console.log('player Loadeddata!', player)
+    },
+    onPlayerWaiting(player) {
+      // console.log('player Waiting!', player)
+    },
+    onPlayerPlaying(player) {
+      // console.log('player Playing!', player)
+    },
+    onPlayerTimeupdate(player) {
+      // console.log('player Timeupdate!', player.currentTime())
+    },
+    onPlayerCanplay(player) {
+      // console.log('player Canplay!', player)
+    },
+    onPlayerCanplaythrough(player) {
+      // console.log('player Canplaythrough!', player)
+    },
+    // or listen state event
+    playerStateChanged(playerCurrentState) {
+      // console.log('player current update state', playerCurrentState)
+    },
+    // player is ready
+    playerReadied(player) {
+      // seek to 10s
+      console.log('example player 1 readied', player)
+      // player.currentTime(10)
+      // console.log('example 01: the player is readied', player)
+    },
+    show(value) {
+      this.model = []
+      this.userModel = {}
+      this.videoModel = {}
+      this.playerOptions.sources[0].src = ''
+      this.loadDetail(value)
+      this.visible = true
+      this.defaultActiveKey = '1'
+    },
+    loadDetail(value) {
+      this.videoModel = value
+      this.playerOptions.sources[0].src = value.video_url;
+    },
+    close() {
+      this.$emit('close')
+      this.visible = false
+      this.defaultActiveKey = '1'
+    },
+    handleCancel() {
+      this.close()
+      this.defaultActiveKey = '1'
+    },
+
+    // 封面预览弹窗
+    coverPreviewShowModal(record) {
+      this.coverPreviewVisible = true
+      this.coverPreviewUrl = record.coverUrl
+      this.coverPreviewMaskStyle.background = 'rgba(0,0,0,.08)'
+    },
+    coverPreviewHandleOk() {
+      this.coverPreviewVisible = false
+      this.coverPreviewMaskStyle.background = 'rgba(0,0,0,0)'
+    },
+    coverPreviewHandleCancel() {
+      this.coverPreviewVisible = false
+      this.coverPreviewUrl = ''
+      this.coverPreviewMaskStyle.background = 'rgba(0,0,0,0)'
+    }
+  }
+}
+</script>
+<style lang="scss">
+.ant-carousel >>> .slick-slide {
+  text-align: center;
+  //   height: 160px;
+  //   line-height: 160px;
+  background: #364d79;
+  overflow: hidden;
+}
+
+.ad_cover_container .ant-card-body {
+  padding: 0;
+}
+
+.ant-carousel >>> .slick-slide h3 {
+  color: #fff;
+}
+.ant-carousel >>> .custom-slick-arrow {
+  width: 25px;
+  height: 25px;
+  font-size: 25px;
+  color: #fff;
+  background-color: rgba(31, 45, 61, 0.11);
+  opacity: 0.3;
+}
+.ant-carousel >>> .custom-slick-arrow:before {
+  display: none;
+}
+.ant-carousel >>> .custom-slick-arrow:hover {
+  opacity: 0.5;
+}
+.addetail_left {
+  padding-right: 56px;
+  .custom-slick-arrow {
+    width: 40px;
+    height: 40px;
+  }
+  .slick_arrow_left {
+    background: url(../images/arrow_left.png);
+  }
+  .slick_arrow_right {
+    background: url(../images/arrow_right.png);
+  }
+    .slick_arrow_left:hover {
+    background: url(../images/arrow_left.png)!important;
+  }
+  .slick_arrow_right:hover {
+    background: url(../images/arrow_right.png)!important;
+  }
+}
+</style>

+ 344 - 0
src/views/oceanengine/modules/HotMaterialModal.vue

@@ -0,0 +1,344 @@
+<template>
+  <a-modal
+    :title="title"
+    :width="1300"
+    :visible="visible"
+    @cancel="handleCancel"
+    cancelText="关闭"
+    class="ad_cover_container"
+  >
+    <div>
+      <a-row>
+        <a-col :span="8" class="addetail_left">
+          <a-tabs :defaultActiveKey="defaultActiveKey">
+            <a-tab-pane tab="视频" key="1">
+              <div class="item">
+                <div class="player">
+                  <video-player
+                    class="vjs-custom-skin"
+                    ref="videoPlayer"
+                    :options="playerOptions"
+                    :playsinline="true"
+                    @play="onPlayerPlay($event)"
+                    @pause="onPlayerPause($event)"
+                    @ended="onPlayerEnded($event)"
+                    @loadeddata="onPlayerLoadeddata($event)"
+                    @waiting="onPlayerWaiting($event)"
+                    @playing="onPlayerPlaying($event)"
+                    @timeupdate="onPlayerTimeupdate($event)"
+                    @canplay="onPlayerCanplay($event)"
+                    @canplaythrough="onPlayerCanplaythrough($event)"
+                    @ready="playerReadied"
+                    @statechanged="playerStateChanged($event)"
+                  ></video-player>
+                </div>
+              </div>
+            </a-tab-pane>
+          </a-tabs>
+        </a-col>
+        <a-col :span="16" class="addetail_right">
+          <div v-if="videoModel != null">
+            <detail-list :col="1">
+              <detail-list-item term="标题">{{videoModel.title}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+              <detail-list-item term="视频ID">
+                <a :href="[videoModel.videoUrl]" target="_blank">{{videoModel.vid}}</a>
+              </detail-list-item>
+            </detail-list>
+              <!--<detail-list-item term="发布时间">{{videoModel.time}}</detail-list-item>-->
+            <detail-list :col="1">
+              <detail-list-item term="抓取时间">{{videoModel.createTime}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+              <detail-list-item term="媒体类型">{{videoModel.appName}}</detail-list-item>
+            </detail-list>
+            <detail-list :col="1">
+            <detail-list-item term="媒体编码">{{videoModel.appCode}}</detail-list-item>
+            </detail-list>
+          </div>
+        </a-col>
+      </a-row>
+    </div>
+  </a-modal>
+</template>
+<script>
+// custom skin css
+// import '../src/custom-theme.css'
+import 'video.js/dist/video-js.css'
+import { videoPlayer } from 'vue-video-player'
+import DetailList from '@/components/tools/DetailList'
+import PageLayout from '@/components/page/PageLayout'
+import STable from '@/components/table/'
+import { getAction, deleteAction, putAction, postAction } from '@/api/manage'
+
+const DetailListItem = DetailList.Item;
+export default {
+  components: {
+    videoPlayer,
+    PageLayout,
+    DetailList,
+    DetailListItem,
+    STable
+  },
+  data() {
+    return {
+      goodsColumns: [
+        {
+          title: '封面ID',
+          dataIndex: 'coverId',
+          key: 'coverId'
+        },
+        {
+          title: '封面预览',
+          //   dataIndex: 'coverUrl',
+          //   key: 'coverUrl',
+          dataIndex: 'ADcoverImagePreview',
+          scopedSlots: { customRender: 'ADcoverImagePreview' }
+        },
+        {
+          title: '创意ID',
+          dataIndex: 'creativeId',
+          key: 'creativeId'
+        },
+        {
+          title: '展示数',
+          dataIndex: 'viewCount',
+          key: 'viewCount'
+        },
+        {
+          title: '喜欢数',
+          dataIndex: 'likeCount',
+          key: 'likeCount'
+        },
+        {
+          title: '评论数',
+          dataIndex: 'commentCount',
+          key: 'commentCount'
+        },
+        {
+          title: '质量分',
+          dataIndex: 'score',
+          key: 'score'
+        },
+        {
+          title: 'App名称',
+          dataIndex: 'appName',
+          key: 'appName'
+        },
+        {
+          title: '发布时间',
+          dataIndex: 'time',
+          key: 'time'
+        }
+      ],
+      userId: 0,
+      photoId: 0,
+      title: '操作',
+      visible: false,
+      model: [],
+      userModel: {},
+      videoModel: {},
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 5 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 16 }
+      },
+      // videojs options
+      playerOptions: {
+        height: '640',
+        width: '360',
+        autoplay: false,
+        muted: true,
+        language: 'en',
+        playbackRates: [0.7, 1.0, 1.5, 2.0],
+        sources: [
+          {
+            type: 'video/mp4',
+            // mp4
+            src: ''
+            // webm
+            // src: "https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm"
+          }
+        ],
+        poster: ''
+      },
+      loadGoodsData: () => {
+        var params = {
+          photoId: this.photoId,
+          userId: this.userId
+        }
+        return getAction('/ctop/adcover/adlist', params).then(res => {
+          this.model = res.result
+          console.log(res.result)
+          return res.result
+        })
+      },
+      defaultActiveKey: '1',
+
+      //   封面预览弹窗
+      coverPreviewVisible: false,
+      coverPreviewMaskStyle: {
+        background: 'rgba(0,0,0,.08)'
+      },
+      coverPreviewUrl: ''
+    }
+  },
+  mounted() {
+    // console.log('this is current player instance object', this.player)
+    setTimeout(() => {
+      console.log('dynamic change options', this.player)
+      // change src
+      // this.playerOptions.sources[0].src = 'https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm';
+      // change item
+      // this.$set(this.playerOptions.sources, 0, {
+      //   type: "video/mp4",
+      //   src: 'https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm',
+      // })
+      // change array
+      // this.playerOptions.sources = [{
+      //   type: "video/mp4",
+      //   src: 'https://cdn.theguardian.tv/webM/2015/07/20/150716YesMen_synd_768k_vp8.webm',
+      // }]
+      this.player.muted(false)
+    }, 5000)
+  },
+  computed: {
+    // player() {
+    //   return this.$refs.videoPlayer.player
+    // }
+  },
+  methods: {
+    // listen event
+    onPlayerPlay(player) {
+      // console.log('player play!', player)
+    },
+    onPlayerPause(player) {
+      // console.log('player pause!', player)
+    },
+    onPlayerEnded(player) {
+      // console.log('player ended!', player)
+    },
+    onPlayerLoadeddata(player) {
+      // console.log('player Loadeddata!', player)
+    },
+    onPlayerWaiting(player) {
+      // console.log('player Waiting!', player)
+    },
+    onPlayerPlaying(player) {
+      // console.log('player Playing!', player)
+    },
+    onPlayerTimeupdate(player) {
+      // console.log('player Timeupdate!', player.currentTime())
+    },
+    onPlayerCanplay(player) {
+      // console.log('player Canplay!', player)
+    },
+    onPlayerCanplaythrough(player) {
+      // console.log('player Canplaythrough!', player)
+    },
+    // or listen state event
+    playerStateChanged(playerCurrentState) {
+      // console.log('player current update state', playerCurrentState)
+    },
+    // player is ready
+    playerReadied(player) {
+      // seek to 10s
+      console.log('example player 1 readied', player)
+      // player.currentTime(10)
+      // console.log('example 01: the player is readied', player)
+    },
+    show(value) {
+      this.model = []
+      this.userModel = {}
+      this.videoModel = {}
+      this.playerOptions.sources[0].src = ''
+      this.loadDetail(value)
+      this.visible = true
+      this.defaultActiveKey = '1'
+    },
+    loadDetail(value) {
+      this.videoModel = value
+      this.playerOptions.sources[0].src = value.videoUrl;
+    },
+    close() {
+      this.$emit('close')
+      this.visible = false
+      this.defaultActiveKey = '1'
+    },
+    handleCancel() {
+      this.close()
+      this.defaultActiveKey = '1'
+    },
+
+    // 封面预览弹窗
+    coverPreviewShowModal(record) {
+      this.coverPreviewVisible = true
+      this.coverPreviewUrl = record.coverUrl
+      this.coverPreviewMaskStyle.background = 'rgba(0,0,0,.08)'
+    },
+    coverPreviewHandleOk() {
+      this.coverPreviewVisible = false
+      this.coverPreviewMaskStyle.background = 'rgba(0,0,0,0)'
+    },
+    coverPreviewHandleCancel() {
+      this.coverPreviewVisible = false
+      this.coverPreviewUrl = ''
+      this.coverPreviewMaskStyle.background = 'rgba(0,0,0,0)'
+    }
+  }
+}
+</script>
+<style lang="scss">
+.ant-carousel >>> .slick-slide {
+  text-align: center;
+  //   height: 160px;
+  //   line-height: 160px;
+  background: #364d79;
+  overflow: hidden;
+}
+
+.ad_cover_container .ant-card-body {
+  padding: 0;
+}
+
+.ant-carousel >>> .slick-slide h3 {
+  color: #fff;
+}
+.ant-carousel >>> .custom-slick-arrow {
+  width: 25px;
+  height: 25px;
+  font-size: 25px;
+  color: #fff;
+  background-color: rgba(31, 45, 61, 0.11);
+  opacity: 0.3;
+}
+.ant-carousel >>> .custom-slick-arrow:before {
+  display: none;
+}
+.ant-carousel >>> .custom-slick-arrow:hover {
+  opacity: 0.5;
+}
+.addetail_left {
+  padding-right: 56px;
+  .custom-slick-arrow {
+    width: 40px;
+    height: 40px;
+  }
+  .slick_arrow_left {
+    background: url(../images/arrow_left.png);
+  }
+  .slick_arrow_right {
+    background: url(../images/arrow_right.png);
+  }
+    .slick_arrow_left:hover {
+    background: url(../images/arrow_left.png)!important;
+  }
+  .slick_arrow_right:hover {
+    background: url(../images/arrow_right.png)!important;
+  }
+}
+</style>