liyongli 3 vuotta sitten
vanhempi
commit
faca251926

+ 18 - 0
src/api/index.js

@@ -216,3 +216,21 @@ export function defaultAjax(props) {
       data
     });
   }
+
+
+// 全国接口
+
+  /**
+   * 频道全天节目
+   * 表格查询
+   * @props {}
+   * @return {AxjxPromise}
+   */
+   export function allDayEpg(data) {
+    return ajax({
+      urlType: "url4",
+      url: "/broadcast/list",
+      method: "get",
+      data
+    });
+  }

+ 2 - 0
src/config/index.js

@@ -1,5 +1,6 @@
 let useApiUrl = "http://172.16.101.11:8899",
   useApiUrl1 = "http://172.16.101.11:9000",
+  kyapi = "https://grow.eye.kuyun.com/",
   isRelease = false; //是否是线上发布版本
 if (process.env.NODE_ENV !== "development") {
   useApiUrl = "http://172.16.101.11:8899";
@@ -12,6 +13,7 @@ export default {
     url: useApiUrl,
     url2: useApiUrl1,
     url3: "",
+    url4: kyapi,
     timeout: 60000,
     isRelease,
     requestRetry: 4,

+ 288 - 84
src/views/ChannelEPG/Channel.vue

@@ -1,9 +1,8 @@
 <template>
-  <div class="channel">
+  <div class="channelEPG">
     <el-breadcrumb separator-class="el-icon-arrow-right">
       <el-breadcrumb-item>传统媒体</el-breadcrumb-item>
-      <el-breadcrumb-item>智能电视</el-breadcrumb-item>
-      <el-breadcrumb-item>收视分析</el-breadcrumb-item>
+      <el-breadcrumb-item>频道全天节目</el-breadcrumb-item>
     </el-breadcrumb>
     <el-card class="box-card">
       <el-form
@@ -25,86 +24,104 @@
           >
           </el-date-picker>
         </el-form-item>
-        <el-form-item label="频道">
-          <el-select
-            v-model="form.channel"
-            placeholder="Activity zone"
-            collapse-tags
-            multiple
-            reserve-keyword
-          >
-            <el-option label="Zone one" value="shanghai"></el-option>
-            <el-option label="Zone one1" value="shanghai1"></el-option>
-            <el-option label="Zone one2" value="shanghai2"></el-option>
-            <el-option label="Zone two" value="beijing"></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="固定时刻">
-          <el-select
-            v-model="form.timerange"
-            placeholder="Activity zone"
-            collapse-tags
-            multiple
-            reserve-keyword
-          >
-            <el-option label="Zone one" value="shanghai"></el-option>
-            <el-option label="Zone one1" value="shanghai1"></el-option>
-            <el-option label="Zone one2" value="shanghai2"></el-option>
-            <el-option label="Zone two" value="beijing"></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="时段">
+        <el-form-item label="时间">
           <el-time-picker
-            v-model="form.value1"
+            v-model="form.rangeTime"
             is-range
+            format="HH:mm"
+            @change="() => (form.rangeTimeRange = [])"
             range-separator="-"
-            start-placeholder="开始时刻"
-            end-placeholder="结束时"
+            start-placeholder="开始时间"
+            end-placeholder="结束时间"
           >
           </el-time-picker>
         </el-form-item>
-        <el-form-item label="行业分城">
+        <el-form-item label="时段">
           <el-select
-            v-model="form.city"
-            placeholder="Activity zone"
-            collapse-tags
+            v-model="form.rangeTimeRange"
+            placeholder="请选择时段"
             multiple
-            reserve-keyword
+            collapse-tags
+            clearable
+            @change="timeSelect"
           >
-            <el-option label="Zone one" value="shanghai"></el-option>
-            <el-option label="Zone one1" value="shanghai1"></el-option>
-            <el-option label="Zone one2" value="shanghai2"></el-option>
-            <el-option label="Zone two" value="beijing"></el-option>
+            <el-option
+              v-for="item in cycle"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+              :disabled="item.disabled"
+            >
+            </el-option>
           </el-select>
         </el-form-item>
-        <el-form-item label="全国大区">
+        <el-form-item label="频道组">
+          <el-select
+            v-model="form.channelGroup"
+            placeholder="请选择频道组"
+            @change="channelSelect"
+          >
+            <el-option
+              v-for="item in channelList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+              :disabled="item.disabled"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="区域">
           <el-select
             v-model="form.region"
-            placeholder="Activity zone"
-            collapse-tags
-            multiple
-            reserve-keyword
+            placeholder="请选择区域"
+            @change="regionSelect"
           >
-            <el-option label="Zone one" value="shanghai"></el-option>
-            <el-option label="Zone one1" value="shanghai1"></el-option>
-            <el-option label="Zone one2" value="shanghai2"></el-option>
-            <el-option label="Zone two" value="beijing"></el-option>
+            <el-option-group
+              v-for="group in region"
+              :key="group.value"
+              :label="group.label"
+            >
+              <el-option
+                v-for="item in group.options"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              >
+              </el-option>
+            </el-option-group>
           </el-select>
         </el-form-item>
         <el-form-item style="float: right">
-          <el-button type="primary">查询</el-button>
-          <el-button type="primary">导出</el-button>
+          <el-button type="primary" @click="onSubmit">查询</el-button>
+          <el-button type="primary" @click="onExport">导出</el-button>
         </el-form-item>
       </el-form>
     </el-card>
     <br />
     <el-card class="box-card">
-      <canvas id="linechart"></canvas>
-      <br />
-      <el-table :data="tableData" style="width: 100%">
-        <el-table-column prop="date" label="Date" />
-        <el-table-column prop="name" label="Name"  />
-        <el-table-column prop="address" label="Address" />
+      <line-charts :list="tableData" :keys="chartKeys"></line-charts>
+      <el-table
+        :data="tableData"
+        :header-cell-style="{ backgroundColor: '#f4f5f7', color: '#606266' }"
+        style="width: 100%"
+      >
+        <el-table-column
+          align="center"
+          show-overflow-tooltip
+          width="400px"
+          prop="epg"
+          label="具体节目"
+          class-name="nowrap"
+        />
+        <el-table-column
+          v-for="(item, i) in chartKeys"
+          :key="'table' + i"
+          align="center"
+          :prop="item.key"
+          :formatter="matrer"
+          :label="item.name"
+        />
       </el-table>
     </el-card>
   </div>
@@ -112,52 +129,239 @@
 
 <script>
 // @ is an alias to /src
+// import {  } from "@/api/index";
+
+import lineCharts from "@/views/Country/components/lineCharts";
+
 import config from "@/config/index";
 export default {
   name: "Channel",
   data() {
     return {
-      form: {
-        date: [],
-      },
-      tableData: [
+      chartKeys: [
         {
-          date: "2016-05-03",
-          name: "Tom",
-          address: "No. 189, Grove St, Los Angeles",
+          key: "indicators_tv_ratings",
+          name: "直播关注度",
         },
         {
-          date: "2016-05-02",
-          name: "Tom",
-          address: "No. 189, Grove St, Los Angeles",
+          key: "indicators_market_ratings",
+          name: "市占率",
         },
         {
-          date: "2016-05-04",
-          name: "Tom",
-          address: "No. 189, Grove St, Los Angeles",
+          key: "indicators_arrive",
+          name: "到达率",
         },
         {
-          date: "2016-05-01",
-          name: "Tom",
-          address: "No. 189, Grove St, Los Angeles",
+          key: "indicators_loyal",
+          name: "忠诚度",
+        },
+        {
+          key: "indicators_column_remain",
+          name: "上期节目留存",
+        },
+        {
+          key: "indicators_traction",
+          name: "用户牵引",
+        },
+      ],
+      form: {
+        rangeTime: [],
+        channelGroup: 0,
+        date: [
+          new Date(new Date() - 86400000),
+          new Date(new Date() - 86400000),
+        ],
+        region: -1,
+      },
+      tableData: [
+        {
+          tv_id: "38",
+          week: "星期六",
+          indicators_market_ratings: 0.006637,
+          year: "2022",
+          indicators_tv_ratings: 0.000556,
+          epg_id: 64844469,
+          indicators_traction: 0.018811,
+          weekrange: "12-27 ~ 01-02",
+          ca_types: "电视剧",
+          start_time: 1640997660000,
+          default: "34城",
+          month: "2022-01",
+          channel_0: "黑龙江卫视",
+          abs_epg: "罗龙镇女人",
+          is_live: "重播",
+          indicators_loyal: 0.051348,
+          epg: "罗龙镇女人  - 黑龙江卫视 - 2022-01-01 08:41~18:03",
+          day: "2022-01-01",
+          indicators_column_remain: 0.016143,
+          indicators_arrive: 0.010798,
+        },
+        {
+          tv_id: "46",
+          week: "星期六",
+          indicators_market_ratings: 0.005599,
+          year: "2022",
+          indicators_tv_ratings: 0.000507,
+          epg_id: 64841031,
+          indicators_traction: 0.035236,
+          weekrange: "12-27 ~ 01-02",
+          ca_types: "电视剧",
+          start_time: 1641010680000,
+          default: "34城",
+          month: "2022-01",
+          channel_0: "山东卫视",
+          abs_epg: "前行者",
+          is_live: "重播",
+          indicators_loyal: 0.05778,
+          epg: "前行者  - 山东卫视 - 2022-01-01 12:18~18:03",
+          day: "2022-01-01",
+          indicators_column_remain: 0.062379,
+          indicators_arrive: 0.008762,
         },
       ],
     };
   },
   mounted() {
-    console.log(config);
+    this.onSubmit();
+  },
+  computed: {
+    cycle() {
+      return config.cycle;
+    },
+    channelList() {
+      return config.channelList;
+    },
+    region() {
+      return config.region;
+    },
   },
-  computed: {},
   methods: {
-    disabledDate() {},
+    timeSelect(a) {
+      let end = (a || [])[(a || []).length - 1];
+      if (this.form.rangeTimeRange.length === config.cycle.length - 1) {
+        this.form.rangeTimeRange = ["0000_2400"];
+      } else {
+        let n = (this.form.rangeTimeRange || []).sort((a, b) => {
+          let aNum = a.split("_")[0];
+          let bNum = b.split("_")[0];
+          return aNum - bNum;
+        });
+        let isSelect = true;
+        for (let i = 0; i < n.length - 1; i++) {
+          let aNum = n[i].split("_")[1];
+          let bNum = n[i + 1].split("_")[0];
+          if (aNum !== bNum) {
+            isSelect = false;
+            break;
+          }
+        }
+        if (!isSelect) {
+          let arr = (n.join(",") + ",")
+            .replace(end + ",", "")
+            .replace(/,$/, "");
+          this.form.rangeTimeRange = arr.split(",");
+        }
+      }
+      if (!this.form.rangeTimeRange.length) return;
+      let s = this.form.rangeTimeRange[0].split("_")[0];
+      let e = this.form.rangeTimeRange[
+        this.form.rangeTimeRange.length - 1
+      ].split("_");
+      e = e[e.length - 1];
+      if (e == "2400") e = "2359";
+      this.form.rangeTime = [
+        new Date(1970, 1, 1, s[0] + s[1] - 0, s[2] + s[3] - 0),
+        new Date(1970, 1, 1, e[0] + e[1] - 0, e[2] + e[3] - 0),
+      ];
+    },
+
+    onExport() {},
+    disabledDate(time) {
+      return time.getTime() > Date.now() - 86400000;
+    },
+    onSubmit() {},
+    matrer(row, column, cellValue) {
+      return (cellValue * 100).toFixed(4) + "%";
+    },
+    dateFormat(date) {
+      let D = new Date(date);
+      let m = D.getMonth() + 1;
+      let d = D.getDate();
+      let h = D.getHours();
+      let M = D.getMinutes();
+      let s = D.getSeconds();
+      m > 9 ? m : (m = "0" + m);
+      d > 9 ? d : (d = "0" + d);
+      h > 9 ? h : (h = "0" + h);
+      M > 9 ? M : (M = "0" + M);
+      s > 9 ? s : (s = "0" + s);
+      return {
+        year: D.getFullYear(),
+        month: m,
+        day: d,
+        hour: h,
+        minutes: M,
+        seconds: s,
+      };
+    },
+    formatListData() {
+      let e = new Date(this.form.date[1]);
+      let d1 = this.dateFormat(this.form.date[0]);
+      let d2 = this.dateFormat(e.getTime() + 86400000);
+      let time = "";
+      if (this.form.rangeTime.length) {
+        let start = new Date(this.form.rangeTime[0]);
+        let end = new Date(this.form.rangeTime[1]);
+        let start_hour = start.getHours();
+        let start_min = start.getMinutes();
+        let end_hour = end.getHours();
+        let end_min = end.getMinutes();
+        start_hour = start_hour > 9 ? start_hour + "" : "0" + start_hour;
+        start_min = start_min > 9 ? start_min + "" : "0" + start_min;
+        end_hour = end_hour > 9 ? end_hour + "" : "0" + end_hour;
+        end_min = end_min > 9 ? end_min + "" : "0" + end_min;
+        if (end_hour + end_min === "2359") {
+          end_hour = "24";
+          end_min = "00";
+        }
+        time = start_hour + start_min + "_" + end_hour + end_min;
+      } else {
+        time = "0000_2400";
+      }
+      return {
+        tv_type: this.form.channelGroup || this.channelList[0].value,
+        time_range: time,
+        area_id: this.form.region || this.region[0].value,
+        start: [d1.year, d1.month, d1.day].join("-"),
+        end: [d2.year, d2.month, d2.day].join("-"),
+      };
+    },
+    channelSelect(a) {
+      this.selectAll(a, "channelGroup", 0);
+    },
+    regionSelect(a) {
+      this.selectAll(a, "region", -1);
+    },
+    selectAll(a, key, val) {
+      if (!a.length) return;
+      let select = a[a.length - 1];
+      if (select === val) this.form[key] = [val];
+      else
+        this.form[key] = (a.join(",") + ",")
+          .replace(val + ",", "")
+          .replace(/,$/, "")
+          .split(",");
+    },
   },
-  components: {},
+  components: { lineCharts },
 };
 </script>
 
 <style>
-.channel {
-  padding: 10px 15px;
-  height: 100vh;
+.channelEPG {
+  margin: 10px 15px;
+}
+.channelEPG .nowrap .cell {
+  white-space: nowrap;
 }
 </style>

+ 0 - 0
src/views/ChannelEPG/charts.js


+ 234 - 0
src/views/Country/components/lineCharts.vue

@@ -0,0 +1,234 @@
+<template>
+  <div class="countryLineChart" ref="countryLineChart"></div>
+</template>
+
+<script>
+// import * as echarts from "echarts";
+import config from "@/config/index";
+import * as echarts from "echarts/core";
+import { LineChart } from "echarts/charts";
+import {
+  TitleComponent,
+  TooltipComponent,
+  LegendComponent,
+  GridComponent,
+} from "echarts/components";
+import { CanvasRenderer } from "echarts/renderers";
+echarts.use([
+  TitleComponent,
+  TooltipComponent,
+  GridComponent,
+  LineChart,
+  CanvasRenderer,
+  LegendComponent,
+]);
+
+let chart = undefined;
+export default {
+  name: "countryLineChart",
+  props: ["list", "tab", "channelId", "keys"],
+  data: function() {
+    return {
+      leftList: [],
+      rightList: [],
+      chart: undefined,
+    };
+  },
+  filters: {},
+  methods: {
+    format(v) {
+      if (isNaN(v)) return 0;
+      let o = v.toFixed(4);
+      if (v > 10000) {
+        o = (v / 10000).toFixed(4) + "万";
+      }
+
+      return o;
+    },
+    formatte(list) {
+      let values = [],
+        keys = [];
+      for (let o = 0; o < list.length; o++) {
+        const v = list[o];
+        keys.push(v.epg);
+        for (let i = 0; i < this.keys.length; i++) {
+          const p = this.keys[i];
+          if (!values[i]) values[i] = [];
+          values[i][o] = v[p.key] * 100;
+        }
+      }
+      return {
+        keys,
+        values,
+      };
+    },
+    updata() {
+      if (!chart) return;
+      //   let chartData = this.formatte(data);
+      chart.setOption(
+        {
+          title: {
+            text: "Gradient Stacked Area Chart",
+          },
+          tooltip: {
+            trigger: "axis",
+            axisPointer: {
+              type: "cross",
+              label: {
+                backgroundColor: "#6a7985",
+              },
+            },
+          },
+          legend: {
+            data: ["Line 1"],
+          },
+          toolbox: {
+            feature: {
+              saveAsImage: {},
+            },
+          },
+          grid: {
+            left: "3%",
+            right: "4%",
+            bottom: "3%",
+            containLabel: true,
+          },
+          xAxis: [
+            {
+              type: "category",
+              boundaryGap: false,
+              data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
+            },
+          ],
+          yAxis: [
+            {
+              type: "value",
+            },
+          ],
+          series: [
+            {
+              name: "Line 1",
+              type: "line",
+              stack: "Total",
+              smooth: true,
+              lineStyle: {
+                width: 0,
+              },
+              showSymbol: false,
+              areaStyle: {
+                opacity: 0.8,
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  {
+                    offset: 0,
+                    color: "rgb(128, 255, 165)",
+                  },
+                  {
+                    offset: 1,
+                    color: "rgb(1, 191, 236)",
+                  },
+                ]),
+              },
+              emphasis: {
+                focus: "series",
+              },
+              data: [140, 232, 101, 264, 90, 340, 250],
+            },
+          ],
+        },
+        true
+      );
+    },
+    getTvName(tvId) {
+      let li = config.channelNameList || [];
+      let t = "";
+      for (let i = 0; i < li.length; i++) {
+        const v = li[i];
+        if (v.value !== tvId) continue;
+        t = v.label;
+        break;
+      }
+      return t;
+    },
+    createChart() {
+      if (!this.$refs.countryLineChart) return;
+      chart = echarts.init(this.$refs.countryLineChart);
+      let chartData = this.formatte(this.list);
+      chart.resize({
+        height: (this.$refs.countryLineChart.offsetWidth * 6) / 16,
+      });
+      var option = {
+        tooltip: {
+          trigger: "axis",
+          triggerOn: "mousemove",
+          axisPointer: {
+            type: "line",
+            axis: "x",
+          },
+          formatter: params => {
+            let out = "";
+            let t = "";
+            for (let i = 0; i < params.length; i++) {
+              const par = params[i];
+              if (t === "") {
+                t = par.axisValueLabel;
+                t += "<br />";
+              }
+              out +=
+                par.seriesName + ": " + this.format(par.value) + "% <br />";
+            }
+            return t + out;
+          },
+        },
+        legend: {
+          data: this.keys.map(v => v.name),
+        },
+        grid: { left: 150, top: "10%", buttom: 0, right: 100 },
+        xAxis: {
+          type: "category",
+          boundaryGap: true,
+          data: chartData.keys,
+        },
+        yAxis: {
+          type: "value",
+          scale: true,
+        },
+        dataZoom: [
+          {
+            show: true,
+            realtime: true,
+            start: 30,
+            end: 70,
+            xAxisIndex: [0, 1],
+          },
+          {
+            type: "inside",
+            realtime: true,
+            start: 30,
+            end: 70,
+            xAxisIndex: [0, 1],
+          },
+        ],
+        series: chartData.values.map((v, i) => {
+          return {
+            type: "line",
+            name: this.keys[i].name,
+            data: v,
+            showAllSymbol: false,
+            smooth: true,
+          };
+        }),
+      };
+
+      option && chart.setOption(option);
+    },
+  },
+  mounted() {
+    this.createChart();
+  },
+  beforeUnmount: function() {
+    chart.dispose();
+  },
+  components: {},
+};
+</script>
+<style></style>