liyongli 1 ano atrás
pai
commit
05574efe94

+ 38 - 38
src/views/BoutiqueColumn/BoutiqueColumn.vue

@@ -1,37 +1,37 @@
 <template>
-  <el-scrollbar height="100vh" always wrap-class="scorll" @scroll="scroll">
-    <div class="boutiqueColumn" ref="nav">
-      <el-breadcrumb separator-class="el-icon-arrow-right">
-        <el-breadcrumb-item>传统媒体</el-breadcrumb-item>
-        <el-breadcrumb-item>重点栏目分析</el-breadcrumb-item>
-      </el-breadcrumb>
-      <el-loading></el-loading>
-      <el-tabs
-        tab-position="top"
-        style="max-height: 100%"
-        @tab-click="selectTab"
-        v-model="select"
+  <!-- <el-scrollbar height="100vh" always wrap-class="scorll" @scroll="scroll"> -->
+  <div class="boutiqueColumn" ref="nav">
+    <el-breadcrumb separator-class="el-icon-arrow-right">
+      <el-breadcrumb-item>传统媒体</el-breadcrumb-item>
+      <el-breadcrumb-item>重点栏目分析</el-breadcrumb-item>
+    </el-breadcrumb>
+    <el-loading></el-loading>
+    <el-tabs
+      tab-position="top"
+      style="max-height: 100%"
+      @tab-click="selectTab"
+      v-model="select"
+    >
+      <el-tab-pane
+        v-for="(item, i) in columnNames"
+        :key="i"
+        :label="item.programName"
+        :name="item.component"
       >
-        <el-tab-pane
-          v-for="(item, i) in columnNames"
-          :key="i"
-          :label="item.programName"
-          :name="item.component"
-        >
-          <!-- <div
+        <!-- <div
             class="tab-body"
             v-if="item.component === select || selectA[item.component]"
           > -->
-          <default-components
-            :select="select"
-            :item="item"
-            ref="child"
-          ></default-components>
-          <!-- </div> -->
-        </el-tab-pane>
-      </el-tabs>
-    </div>
-  </el-scrollbar>
+        <default-components
+          :select="select"
+          :item="item"
+          ref="child"
+        ></default-components>
+        <!-- </div> -->
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+  <!-- </el-scrollbar> -->
 </template>
 
 <script>
@@ -40,7 +40,7 @@ import { epgList } from '@/api/index';
 // 重点栏目分析
 import defaultComponents from './views/default.vue';
 
-let lastMoreDate = 0;
+// let lastMoreDate = 0;
 export default {
   name: 'boutiqueColumn',
   data() {
@@ -59,14 +59,14 @@ export default {
   },
   computed: {},
   methods: {
-    scroll(scroll) {
-      let now = Date.now();
-      let allheight = this.$refs.nav.offsetHeight - document.body.offsetHeight;
-      let warn = allheight - scroll.scrollTop;
-      if (now - lastMoreDate < 1000 || warn > 10) return;
-      lastMoreDate = now;
-      return this.$refs.child.changePage(this.$refs.child.current);
-    },
+    // scroll(scroll) {
+    //   let now = Date.now();
+    //   let allheight = this.$refs.nav.offsetHeight - document.body.offsetHeight;
+    //   let warn = allheight - scroll.scrollTop;
+    //   if (now - lastMoreDate < 1000 || warn > 10) return;
+    //   lastMoreDate = now;
+    //   return this.$refs.child.changePage(this.$refs.child.current);
+    // },
     selectTab(tab) {
       try {
         this.select = this.columnNames[tab.index].component;

+ 114 - 0
src/views/BoutiqueColumn/components/line.vue

@@ -0,0 +1,114 @@
+<template>
+  <div ref="chartEle"></div>
+</template>
+
+<script setup>
+// @ is an alias to /src
+import { epgDetail } from '@/api/index';
+//   import { defaultAjax } from '@/api/index';
+import { defineProps, ref, onMounted } from 'vue';
+// import config from '../../../config/index';
+import * as echarts from 'echarts/core';
+import { LineChart, BarChart } from 'echarts/charts';
+import {
+  TitleComponent,
+  TooltipComponent,
+  GridComponent,
+  ToolboxComponent,
+  VisualMapComponent,
+} from 'echarts/components';
+import { LabelLayout, UniversalTransition } from 'echarts/features';
+import { CanvasRenderer } from 'echarts/renderers';
+echarts.use([
+  TitleComponent,
+  TooltipComponent,
+  GridComponent,
+  LineChart,
+  BarChart,
+  CanvasRenderer,
+  ToolboxComponent,
+  VisualMapComponent,
+  LabelLayout,
+  UniversalTransition,
+]);
+
+const props = defineProps({
+  item: Object,
+});
+const chartEle = ref(null);
+
+console.log(props);
+onMounted(() => {
+  epgDetail({
+    epgId: props.item.epg_id,
+    target: '.loadare' + props.item.epg_id,
+  }).then(res => {
+    console.log(res);
+    const keys = [],
+      value = [];
+    const li = res || [];
+    for (let i = 0; i < li.length; i++) {
+      const v = li[i];
+      keys.push(v.metric);
+      value.push(v.watchrate);
+    }
+    const chart = echarts.init(chartEle.value);
+    const height = (chartEle.value.offsetWidth * 6) / 16;
+    chart.resize({
+      height,
+      width: chartEle.value.offsetWidth,
+    });
+    let option = {
+      tooltip: {
+        confine: true,
+        trigger: 'axis',
+        axisPointer: {
+          type: 'cross',
+        },
+        formatter: function (data) {
+          return data[0].value;
+        },
+      },
+      grid: {
+        top: '5%',
+        left: '3%',
+        right: '4%',
+        bottom: '3%',
+        containLabel: true,
+      },
+      xAxis: {
+        type: 'category',
+        boundaryGap: false,
+        data: keys,
+      },
+      yAxis: {
+        type: 'value',
+        axisLabel: {
+          formatter: watchrate => {
+            return watchrate;
+          },
+        },
+        axisPointer: {
+          snap: true,
+        },
+      },
+      series: [
+        {
+          type: 'line',
+          smooth: true,
+          data: value,
+          itemStyle: {
+            opacity: 0,
+          },
+          lineStyle: {
+            width: 1,
+          },
+        },
+      ],
+    };
+    option && chart.setOption(option);
+  });
+});
+</script>
+
+<style lang="scss"></style>

+ 170 - 26
src/views/BoutiqueColumn/components/video.vue

@@ -9,7 +9,63 @@
       @canplay="videoload"
       :src="props.item.video_url"
     ></video>
-    <div ref="chartEle"></div>
+    <div style="position: relative">
+      <div ref="chartEle"></div>
+      <div class="lineinfobackground" :style="'left:' + leftNum + 'px'">
+        <div style="position: relative; width: 100%; height: 100%">
+          <div class="line"></div>
+          <el-row style="padding: 10px 0 0 10px">
+            <el-col :span="6">
+              <span class="icon" style="background-color: #e05c5c"></span>
+              流入
+            </el-col>
+            <el-col :span="6">
+              <span class="icon" style="background-color: #6ab581"></span>
+              流出
+            </el-col>
+            <el-col :span="12">
+              <span class="iconLine"></span>
+              收视率%
+              <div style="float: right; padding: 0 5px 0 0">
+                {{ tof(jindu.audienceRating, 4) }}%
+              </div>
+            </el-col>
+          </el-row>
+          <div style="padding: 5px 10px">
+            当前时间:{{ jindu.date ? jindu.date.split(' ')[1] || '' : '' }}
+            <div style="float: right">人数: {{ formateNum(jindu.uv) }}</div>
+          </div>
+          <el-row>
+            <el-col :span="12">
+              <div style="padding: 0 10px">
+                流入排行
+                <div>
+                  <div
+                    style="font-size: 12px; line-height: 22px"
+                    v-for="(item, i) in jindu.lrTop"
+                    :key="i"
+                    v-text="item"
+                  ></div>
+                </div>
+              </div>
+            </el-col>
+            <el-col :span="12">
+              <div style="padding: 0 10px">
+                流出排行
+                <div>
+                  <div
+                    style="font-size: 12px; line-height: 22px"
+                    v-for="(item, i) in jindu.lcTop"
+                    :key="i"
+                    v-text="item"
+                  ></div>
+                </div>
+              </div>
+            </el-col>
+          </el-row>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
@@ -17,20 +73,26 @@
 // @ is an alias to /src
 import { defaultAjax } from '@/api/index';
 import { ref, defineProps, onMounted } from 'vue';
+import * as echarts from 'echarts';
 const video = ref(null);
 const bg = ref(null);
+const leftNum = ref(100);
 const chartEle = ref(null);
 const props = defineProps({
   item: Object,
 });
-import * as echarts from 'echarts';
+const jindu = ref({});
 let chart = undefined;
 let timeout = undefined;
 let isClick = false;
+let list = [];
+let sec = 0,
+  stepNum = 6.8,
+  page = 0;
 onMounted(() => {
   chart = echarts.init(chartEle.value);
   chart.resize({
-    height: (bg.value.offsetWidth * 6) / 20,
+    height: 300,
     width: bg.value.offsetWidth,
   });
 
@@ -50,17 +112,51 @@ onMounted(() => {
   });
 });
 
-props.item.flow_url &&
-  defaultAjax({
-    url: props.item.flow_url,
-  }).then(r => {
-    console.log(r);
-    draw(r);
-  });
+defaultAjax({
+  url: props.item.flow_url,
+}).then(r => {
+  const li = r || {};
+  const Ir = [],
+    Ic = [],
+    ad = [],
+    keys = [];
+
+  for (const key in li) {
+    if (!Object.hasOwnProperty.call(li, key)) continue;
+    const v = li[key];
+    keys.push(key);
+    Ic.push(-1 * v.lc);
+    Ir.push(v.lr);
+    ad.push(v.audienceRating * 100);
+    v.date = key;
+    list.push(v);
+  }
+  draw(keys, Ir, Ic, ad);
+  jindu.value = list[0];
+});
 
-function timeupdate() {
+function timeupdate(v) {
   // 播放中
-  //   console.log('播放中');
+  if (sec === Math.floor(v.srcElement.currentTime)) return;
+  sec = Math.floor(v.srcElement.currentTime);
+  let width = bg.value.offsetWidth - 100;
+  let item = list[sec] || {};
+  let s = chart.getOption().dataZoom[0].startValue,
+    e = chart.getOption().dataZoom[0].endValue;
+  let iW = width / (e - s),
+    cheng = sec - s < 0 ? 0 : sec - s;
+  let step = iW * cheng > width ? 0 : iW * cheng;
+  if (!item.lrTop) return;
+  jindu.value = item;
+  leftNum.value = 100 + step;
+  if (iW * cheng <= width) return;
+  page++;
+  chart.setOption({
+    dataZoom: {
+      start: stepNum * page,
+      end: stepNum * (page + 1),
+    },
+  });
 }
 
 function videoerror(err) {
@@ -72,20 +168,30 @@ function videoload() {
   console.log('可以播放', video.value);
 }
 
-function draw(r) {
+function formateNum(n) {
+  let num = n;
+  if (isNaN(n)) num = '0';
+  else if (n >= 100000000)
+    num =
+      ((n / 100000000).toFixed(2) - 0 + '').replace(
+        /\B(?=(?:\d{3})+\b)/g,
+        ','
+      ) + '亿';
+  else if (n >= 10000)
+    num =
+      ((n / 10000).toFixed(2) - 0 + '').replace(/\B(?=(?:\d{3})+\b)/g, ',') +
+      '万';
+  else num = (num + '').replace(/\B(?=(?:\d{3})+\b)/g, ',');
+  return num;
+}
+
+function tof(num, t) {
+  return Number(num * 100).toFixed(t || 2);
+}
+
+function draw(key, Ir, Ic, ad) {
   // 绘图
-  const key = Object.keys(r);
-  const value = Object.values(r);
-  const Ir = [],
-    Ic = [],
-    ad = [];
-  let stepNum = 6.8,
-    page = 0;
-  value.map(v => {
-    Ic.push(-1 * v.lc);
-    Ir.push(v.lr);
-    ad.push(v.audienceRating * 100);
-  });
+  let stepNum = 6.8;
   let option = {
     dataZoom: [
       {
@@ -182,7 +288,7 @@ function draw(r) {
       },
     ],
     grid: {
-      left: 50,
+      left: 100,
       right: 50,
     },
     series: [
@@ -242,5 +348,43 @@ function draw(r) {
     margin: 0 auto;
     display: block;
   }
+
+  .lineinfobackground {
+    font-size: 12px;
+    border-radius: 9px;
+    position: absolute;
+    width: 305px;
+    height: 200px;
+    top: 30px;
+    left: 50px;
+    background: rgba(0, 0, 0, 0.5);
+    transform: translateX(-50%);
+    color: #fff;
+
+    .line {
+      position: absolute;
+      width: 2px;
+      height: 110%;
+      margin-top: -5%;
+      margin-left: 50%;
+      background-color: #888;
+    }
+
+    .icon {
+      display: inline-block;
+      width: 30px;
+      height: 10px;
+      border-radius: 10px;
+    }
+
+    .iconLine {
+      background-color: #50abfd;
+      display: inline-block;
+      width: 30px;
+      height: 2px;
+      vertical-align: middle;
+      border-radius: 10px;
+    }
+  }
 }
 </style>

+ 33 - 11
src/views/BoutiqueColumn/views/default.vue

@@ -1,9 +1,10 @@
 <template>
   <el-button type="primary" class="export"> 导出 </el-button>
-  <el-table :data="list">
+  <el-table :data="list" @sort-change="sortFun">
     <el-table-column type="expand">
       <template #default="props">
-        <self-video :item="props.row" />
+        <self-video v-if="props.row.video_url" :item="props.row" />
+        <self-line v-else :item="props.row" />
       </template>
     </el-table-column>
     <el-table-column
@@ -16,15 +17,15 @@
     <el-table-column
       align="center"
       label="市场占有率"
-      prop="stadate"
+      prop="occrate"
       sortable="custom"
     >
       <template #default="scope"> {{ scope.row.occrate }}% </template>
     </el-table-column>
     <el-table-column
       align="center"
-      label="日期"
-      prop="stadate"
+      label="收视率"
+      prop="watchrate"
       sortable="custom"
     >
       <template #default="scope">
@@ -35,31 +36,43 @@
       </template>
     </el-table-column>
   </el-table>
+  <br />
+  <el-pagination
+    @current-change="changePage"
+    background
+    layout="prev, pager, next"
+    :total="resultP.total"
+  />
 </template>
 <script setup>
 // @ is an alias to /src
+import config from '../../../config/index';
 import { epgResult } from '@/api/index';
 import { defineProps, ref } from 'vue';
 import watchrateEle from '../components/watchrate.vue';
 import selfVideo from '../components/video.vue';
+import selfLine from '../components/line.vue';
 
 const props = defineProps({
   item: Object,
   select: String,
 });
-const resultP = {
+const resultP = ref({
   programId: props.item.id,
   page: 1,
   pageSize: 10,
   sort: 'STADATE',
   order: 'DESC',
-};
+  total: 1000,
+});
+
 const list = ref([]);
 
 function getEpgResult() {
-  epgResult(resultP).then(r => {
-    resultP.total = r.total || 0;
-
+  if (resultP.value.page * resultP.value.pageSize >= resultP.value.total)
+    return;
+  epgResult(resultP.value).then(r => {
+    resultP.value.total = r.total || 0;
     list.value = (r.data || []).map(v => {
       v.maxMarketRate = r.maxMarketRate;
       v.maxRate = r.maxRate;
@@ -67,9 +80,18 @@ function getEpgResult() {
     });
   });
 }
-
 getEpgResult();
 
+function sortFun(column) {
+  resultP.value.order = column.order ? config.order[column.order] : 'DESC';
+  resultP.value.sort = column.prop ? column.prop.toUpperCase() : 'STADATE';
+  getEpgResult();
+}
+
+function changePage(num) {
+  resultP.value.page = num;
+  getEpgResult();
+}
 </script>
 
 <style></style>

+ 0 - 0
src/views/BoutiqueColumn/views/default copy.vue → src/views/BoutiqueColumn/views/default_back.vue