<template>
  <div class="Content">
    <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>
    <el-card class="box-card">
      <el-form
        ref="form"
        :model="form"
        size="small"
        :inline="true"
        label-width="120px"
        class="demo-form-inline"
      >
        <el-form-item label="日期">
          <el-date-picker
            v-if="form.date.length"
            v-model="form.date"
            type="daterange"
            :disabled-date="time => disabledDate(time)"
            range-separator="-"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            :clearable="false"
            @change="dateChange"
          >
          </el-date-picker>
        </el-form-item>
        <el-form-item label="应用">
          <el-select
            v-model="form.app"
            placeholder="请选择时段"
            @change="change"
          >
            <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-select
            multiple
            collapse-tags
            clearable
            v-model="form.version"
            placeholder="请选择版本"
            @change="changeversion"
          >
            <el-option
              v-for="item in version"
              :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
            collapse-tags
            clearable
            v-model="form.content"
            placeholder="请选择内容"
          >
            <el-option
              v-for="item in content"
              :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
            collapse-tags
            clearable
            v-model="form.client"
            placeholder="请选择来源"
          >
            <el-option
              v-for="item in client"
              :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
            collapse-tags
            clearable
            v-model="form.appColumn"
            placeholder="请选择栏目"
          >
            <el-option
              v-for="item in appColumn"
              :key="item"
              :label="item"
              :value="item"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item style="float: right">
          <el-button type="primary" @click="onSubmit">查询</el-button>
          <el-button size="small" type="primary" @click="onExport">
            导出
          </el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <br />
    <el-card class="box-card">
      <div class="head" v-if="total">
        <div v-for="(item, i) in total" :key="i + item.name" class="head-item">
          <div>{{ item.name }}</div>
          <div class="value">
            <!-- oriData.total.activeUser -->
            <countTo
              v-if="!isNaN(item.value)"
              :startVal="0"
              :endVal="item.value - 0"
              :duration="1500"
            ></countTo>
            <span v-else v-text="item.value"></span>
          </div>
        </div>
      </div>
      <!-- 2023年2月1号 因为下边表格同样具备top性质，所以隐藏顶部top -->
      <el-row :gutter="20" v-if="false">
        <el-col :span="6" v-for="(v, i) in top" :key="i + v.name">
          <div class="libTitle" v-text="v.name"></div>
          <el-table
            :data="v.list || []"
            style="width: 100%"
            :header-cell-style="{
              backgroundColor: '#f4f5f7',
              color: '#606266',
            }"
          >
            <el-table-column
              prop="title"
              header-align="center"
              align="center"
              label="标题"
              show-overflow-tooltip
            />
            <el-table-column label="次数" header-align="center" align="center">
              <template #default="scope">
                <countTo
                  :startVal="0"
                  :endVal="scope.row[v.target] || 0"
                  :duration="100"
                ></countTo>
              </template>
            </el-table-column>
          </el-table>
        </el-col>
      </el-row>
      <br />
      <div ref="regionChart"></div>
      <br />
      <el-input
        size="small"
        v-model="match"
        clearable
        style="width: 300px"
        placeholder="请输入内容ID或内容标题"
        class="input-with-select"
      >
        <template #append>
          <el-button @click="onSubmit">
            <el-icon><Search /></el-icon>
          </el-button>
        </template>
      </el-input>
      <br />
      <br />
      <el-table
        :data="table.records || []"
        style="width: 100%"
        @sort-change="tableChange"
        :header-cell-style="{
          backgroundColor: '#f4f5f7',
          color: '#606266',
        }"
      >
        <el-table-column
          prop="contentId"
          header-align="center"
          align="center"
          label="内容ID"
          show-overflow-tooltip
        >
          <template #default="scope">
            <span v-text="scope.row.contentId || '-'"></span>
          </template>
        </el-table-column>
        <el-table-column
          prop="title"
          header-align="center"
          align="center"
          width="300"
          label="标题"
          show-overflow-tooltip
        >
          <template #default="scope">
            <span v-text="scope.row.title || '-'"></span>
          </template>
        </el-table-column>
        <el-table-column
          show-overflow-tooltip
          label="应用名称"
          header-align="center"
          align="center"
        >
          <template #default>
            <span>{{ lastParams.app || '-' }}</span>
          </template>
        </el-table-column>
        <el-table-column
          prop="publishTime"
          header-align="center"
          align="center"
          label="发布时间"
          show-overflow-tooltip
        >
          <template #default="scope">
            <span v-text="scope.row.publishTime || '-'"></span>
          </template>
        </el-table-column>
        <el-table-column
          label="平均阅读时长"
          header-align="center"
          align="center"
          sortable
          :sort-orders="['ascending', 'descending', null]"
          prop="cduration"
        >
          <template #default="scope">
            <span v-text="timeFormat(scope.row.cduration)"></span>
          </template>
        </el-table-column>
        <el-table-column
          label="阅读数"
          header-align="center"
          align="center"
          sortable
          :sort-orders="['ascending', 'descending', null]"
          prop="cpv"
        >
          <template #default="scope">
            <countTo
              :startVal="0"
              :endVal="scope.row.cpv || 0"
              :duration="100"
            ></countTo>
          </template>
        </el-table-column>
        <el-table-column
          label="点赞数"
          header-align="center"
          align="center"
          sortable
          :sort-orders="['ascending', 'descending', null]"
          prop="csupport"
        >
          <template #default="scope">
            <countTo
              :startVal="0"
              :endVal="scope.row.csupport || 0"
              :duration="100"
            ></countTo>
          </template>
        </el-table-column>
        <el-table-column
          label="收藏数"
          header-align="center"
          align="center"
          sortable
          :sort-orders="['ascending', 'descending', null]"
          prop="ccollect"
        >
          <template #default="scope">
            <countTo
              :startVal="0"
              :endVal="scope.row.ccollect || 0"
              :duration="100"
            ></countTo>
          </template>
        </el-table-column>
        <el-table-column
          label="分享次数"
          header-align="center"
          align="center"
          sortable
          :sort-orders="['ascending', 'descending', null]"
          prop="cshare"
        >
          <template #default="scope">
            <countTo
              :startVal="0"
              :endVal="scope.row.cshare || 0"
              :duration="100"
            ></countTo>
          </template>
        </el-table-column>
        <el-table-column
          label="评论数"
          header-align="center"
          align="center"
          sortable
          :sort-orders="['ascending', 'descending', null]"
          prop="ccomments"
        >
          <template #default="scope">
            <countTo
              :startVal="0"
              :endVal="scope.row.ccomments || 0"
              :duration="100"
            ></countTo>
          </template>
        </el-table-column>
        <el-table-column
          label="观看用户数"
          header-align="center"
          align="center"
          sortable
          :sort-orders="['ascending', 'descending', null]"
          prop="cuser"
        >
          <template #default="scope">
            <countTo
              :startVal="0"
              :endVal="scope.row.cuser || 0"
              :duration="100"
            ></countTo>
          </template>
        </el-table-column>
      </el-table>
      <br />
      <el-pagination
        layout="prev, pager, next"
        :page-size="form.size"
        :current-page="form.page"
        :total="table.total"
        background
        @current-change="changePage"
      />
    </el-card>
  </div>
</template>
<script>
// @ is an alias to /src
import { Search } from '@element-plus/icons-vue';
import {
  getRule,
  getAppList,
  getSearchData,
  getContentTop10,
  getContentChart,
  getContentPage,
  getContentTotle,
  getAppColumn,
} from '@/api/index';

import countTo from '@/components/counto/vue-countTo.vue';
import { defaultAppNameFunc } from '@/utils/tool.js';
import * as echarts from 'echarts/core';
import { LineChart } from 'echarts/charts';
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  ToolboxComponent,
  LegendComponent,
} from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LineChart,
  CanvasRenderer,
  ToolboxComponent,
  LegendComponent,
]);

import config from '@/config/index';
let chart = undefined;
export default {
  name: 'Content',
  data() {
    return {
      lastParams: {},
      table: {},
      form: {
        app: '',
        version: [],
        date: [],
        content: '',
        client: '',
      },
      match: '',
      cycle: [],
      showList: [],
      version: [],
      content: [],
      top: [],
      total: [],
      client: [],
      appColumn: [],
    };
  },
  async mounted() {
    if (chart && chart.dispose) chart.dispose();
    const {
      source,
      appV,
      contentV,
      clentV,
      appli,
      appVLi,
      contentli,
      clentli,
    } = await this.getAppListFunc();
    const keys = {
      value: 'mname',
      label: 'mname',
    };
    const clentliList = clentli.find(r => r.mdefault) || false;
    let client = clentliList ? clentliList.mcode.toString() : -1;
    this.cycle = this.verifyList(appli, source, keys, false);
    this.version = this.verifyList(appVLi, appV, keys, true);
    this.content = this.verifyList(contentli, contentV, keys, true);
    this.client = this.verifyList(
      clentli,
      clentV,
      {
        value: 'mcode',
        label: 'mname',
      },
      true
    );
    this.getAppColFun();
    this.form = {
      //   app: (this.cycle[0] || { value: "" }).value,
      app: defaultAppNameFunc(this.cycle),
      version: [(this.version[0] || { value: '' }).value],
      content: -1,
      date: [new Date(Date.now() - 604800000), new Date(Date.now() - 86400000)],
      client,
      page: 1,
      size: 20,
      sortBy: '',
      appColumn: '不限',
    };
    this.onSubmit();
  },
  computed: {},
  methods: {
    dateChange() {
      this.form.appColumn = '不限';
      this.appColumn = [];
      this.getAppColFun();
    },
    async getAppColFun() {
      const start = this.form.date[0] || new Date(Date.now() - 604800000);
      const end = this.form.date[1] || new Date(Date.now() - 604800000);
      const appColumn = await getAppColumn({
        app: this.form.app || defaultAppNameFunc(this.cycle),
        start,
        end,
      });
      const col = appColumn || [];
      this.appColumn = ['不限', ...col];
    },
    tableChange(e) {
      this.form.page = 1;
      this.form.sortBy = e.column ? e.column.property : '';
      this.lastParams.sortBy = this.form.sortBy;
      this.lastParams.page = this.form.page;
      const sortLibType = {
        descending: 1,
        ascending: 0,
      };
      if (e.order) {
        this.form.order = sortLibType[e.order];
      } else {
        this.form.order = '';
      }
      this.lastParams.order = this.form.order;
      getContentPage(this.lastParams).then(r => (this.table = r || {}));
    },
    verifyList(list, verify, obj, more) {
      if (!obj) return;
      let li = list || [];
      const out = [];
      more && out.push({ value: -1, label: '不限' });
      for (let i = 0; i < li.length; i++) {
        const v = li[i];
        if (verify.length !== 0 && !verify[v.mcode]) continue;
        out.push({
          value: v[obj.value],
          label: v[obj.label],
        });
      }
      return out;
    },
    changePage(e) {
      this.form.page = e;
      this.onSubmit();
    },
    onSubmit() {
      this.lastParams = {
        app: this.form.app,
        start: this.FormData(this.form.date[0]),
        end: this.FormData(this.form.date[1]),
        version: this.form.version == -1 ? undefined : this.form.version,
        contentType: this.form.content == -1 ? undefined : this.form.content,
        page: this.form.page,
        pageSize: this.form.size,
        match: this.match,
        sortBy: this.form.sortBy,
        lib: this.form.client == -1 ? undefined : this.form.client,
        order: this.form.order,
        channelName:
          this.form.appColumn === '不限' || !this.form.appColumn
            ? undefined
            : this.form.appColumn,
      };
      getContentPage(this.lastParams).then(r => (this.table = r || {}));
      getContentTotle({
        start: this.FormData(this.form.date[0]),
        end: this.FormData(this.form.date[1]),
        app: this.form.app,
        version: this.form.version == -1 ? undefined : this.form.version,
        lib: this.form.client == -1 ? undefined : this.form.client,
      }).then(r => {
        this.total = r || [];
      });
      getContentTop10({
        app: this.form.app,
        start: this.FormData(this.form.date[0]),
        end: this.FormData(this.form.date[1]),
        version: this.form.version == -1 ? undefined : this.form.version,
        contentType: this.form.content == -1 ? undefined : this.form.content,
        lib: this.form.client == -1 ? undefined : this.form.client,
      })
        .then(r => {
          this.top = r || [];
          getContentChart({
            app: this.form.app,
            start: this.FormData(this.form.date[0]),
            end: this.FormData(this.form.date[1]),
            version: this.form.version == -1 ? undefined : this.form.version,
            lib: this.form.client == -1 ? undefined : this.form.client,
            contentType:
              this.form.content == -1 ? undefined : this.form.content,
          }).then(resChart => {
            let keyList = [],
              valueList = [],
              titles = [];
            if ((resChart || []).length && chart && chart.clear) chart.clear();
            for (let o = 0; o < (resChart || []).length; o++) {
              const item = (resChart || [])[o];
              keyList.push(item.dt);
              for (let i = 0; i < this.top.length; i++) {
                const v = this.top[i];
                if (!valueList[i]) valueList[i] = [];
                if (titles.length < this.top.length)
                  titles.push(v.name.split('T')[0]);
                valueList[i].push(item[v.target] || 0);
              }
            }
            this.createImage(keyList, valueList, titles);
          });
        })
        .catch(() => {
          chart && chart.clear() && chart.hideLoading();
        });
    },
    createImage(keyList, valueList, title) {
      if (!chart) {
        chart = echarts.init(this.$refs.regionChart);
        window.onresize = chart.resize;
      }
      chart.clear();
      chart.resize({
        height: (this.$refs.regionChart.offsetWidth * 4) / 16,
      });
      chart.setOption({
        tooltip: {
          trigger: 'axis',
          confine: true,
        },
        toolbox: {
          feature: {
            saveAsImage: {
              type: 'jpg',
              name: '内容分析-' + this.form.app,
            },
          },
        },
        legend: {
          data: title,
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true,
        },
        xAxis: {
          type: 'category',
          boundaryGap: true,
          data: keyList,
        },
        yAxis: {
          type: 'value',
          scale: true,
          minInterval: 1,
          axisLabel: {
            formatter(v) {
              let val = v;
              if (val >= 100000000) {
                val = (val / 100000000).toFixed(2) + '亿';
              } else if (val >= 10000) {
                val = (val / 10000).toFixed(2) + '万';
              }
              return val;
            },
          },
        },
        series: valueList.map((v, i) => {
          return {
            name: title[i],
            data: v,
            symbolSize: 0,
            lineStyle: {
              width: 1,
            },
            type: 'line',
            smooth: true,
          };
        }),
      });
    },
    async getAppListFunc() {
      const { r, li, appVersion, contentList, clientList } =
        await this.getAppListOri();
      let source = { length: 0 },
        appli = [];
      let appV = { length: 0 },
        appVLi = [];
      let contentV = { length: 0 },
        contentli = [];
      let clentV = { length: 0 },
        clentli = [];
      let prvList =
        (r.output && r.output.data && r.output.data.prvRolectrl) || [];
      for (let i = 0; i < prvList.length; i++) {
        const v = prvList[i];
        if (v.controlid == 'RMT_SOURCE')
          (source[v.detid] = true), (source.length = source.length + 1);
        if (v.controlid == 'APP_VERSION')
          (appV[v.detid] = true), (appV.length = appV.length + 1);
        if (v.controlid == 'content_TYPE')
          (contentV[v.detid] = true), (contentV.length = contentV.length + 1);
      }
      if (li.status === '0') appli = li.output.data || [];
      if (appVersion.length) appVLi = appVersion || [];
      if (contentList.length) contentli = contentList || [];
      if (clientList.length) clentli = clientList || [];
      return {
        source,
        appV,
        appli,
        clentV,
        contentV,
        appVLi,
        contentli,
        clentli,
      };
    },
    async getAppListOri() {
      const roleid = JSON.parse(
        window.parent.localStorage.userinfo || '{}'
      ).roleid;
      const r = await getRule({
        db: 'authplat',
        exportMark: '0',
        menuid: 399,
        roleid,
      });
      //   应用列表

      const li = await getAppList({
        exportMark: '0',
        gcode: 'SOURCE',
        pageid: 1,
        pagesize: 1000,
      });
      const cycle = li.output ? li.output.data || [] : [];
      // 端列表
      const clientList = await getSearchData({
        gcode: 'CLIENT_TYPE',
        source: defaultAppNameFunc(cycle, 'mname'),
      });
      //   应用版本列表
      const appVersion = await getSearchData({
        gcode: 'APP_VERSION',
        source: defaultAppNameFunc(cycle, 'mname'),
      });
      // 端列表
      let contentList = await getAppList({
        exportMark: '0',
        gcode: 'CONTENT_TYPE',
        pageid: 1,
        pagesize: 1000,
      });
      contentList =
        contentList.status == '0' ? contentList.output.data || [] : [];
      return { r, li, appVersion, contentList, clientList };
    },
    disabledDate(time) {
      const first = new Date('2021-06-21 00:00:00');
      return (
        time.getTime() > Date.now() - 86400000 ||
        time.getTime() < first.getTime()
      );
    },
    FormData(date) {
      const d = new Date(date || Date.now() - 86400000);
      const year = d.getFullYear();
      const month =
        d.getMonth() <= 8 ? '0' + (d.getMonth() + 1) : d.getMonth() + 1;
      const day = d.getDate() <= 9 ? '0' + d.getDate() : d.getDate();
      return [year, month, day].join('-');
    },
    timeFormat(t) {
      const Time = t || 0;
      const mH = Time % 3600;
      let hour = (Time - mH) / 3600;
      let min = (mH - (mH % 60)) / 60;
      let son = Number(mH % 60).toFixed(0);
      hour = hour <= 9 ? '0' + hour : hour;
      min = min <= 9 ? '0' + min : min;
      son = son <= 9 ? '0' + son : son;
      let out = [];
      if (hour * 1 > 0) out.push(hour);
      out.push(...[min, son]);
      return out.join(':');
    },
    change() {
      const roleid = JSON.parse(
        window.parent.localStorage.userinfo || '{}'
      ).roleid;
      const appV = {
        length: 0,
      };
      //   如果应用选择西部网则渠道默认全部
      this.form.app === '西部网' && (this.form.client = -1);
      getRule({
        db: 'authplat',
        exportMark: '0',
        menuid: 399,
        roleid,
      }).then(rule => {
        let prvList =
          (rule.output && rule.output.data && rule.output.data.prvRolectrl) ||
          [];
        for (let i = 0; i < prvList.length; i++) {
          const v = prvList[i];
          if (v.controlid == 'APP_VERSION')
            (appV[v.detid] = true), (appV.length = appV.length + 1);
        }
        getSearchData({
          gcode: 'APP_VERSION',
          source: this.form.app,
        }).then(r => {
          let version = [
            {
              label: '不限',
              value: -1,
            },
          ];
          r.map(v => {
            if ((appV.length && appV[v.mcode]) || appV.length === 0)
              version.push({
                value: v.mname,
                label: v.mname,
              });
          });
          this.version = version;
          this.form = {
            ...this.form,
            version: [-1],
          };
        });
      });

      // 切换应用时重置栏目
      this.form.appColumn = '不限';
      this.appColumn = [];
      this.getAppColFun();
    },
    changeversion(v) {
      if (!v.length) return (this.form.version = [-1]);
      const last = v[v.length - 1];
      if (last == -1) return (this.form.version = [-1]);
      let ver = [];
      for (let i = 0; i < v.length; i++) {
        const element = v[i];
        if (element == -1) continue;
        ver.push(element);
      }
      this.form.version = ver;
    },
    onExport() {
      const S = this.lastParams.start ? this.lastParams.start : undefined;
      const E = this.lastParams.end ? this.lastParams.end : undefined;
      const app = this.lastParams.app || this.form.app;
      const version =
        this.form.version == -1 ? undefined : this.form.version.join(',');
      const contentType = this.lastParams.contentType || this.form.contentType;
      let url =
        config.base.leverAudience +
        '/cxzx-program/new-media/content/export?start=' +
        S +
        '&end=' +
        E +
        '&app=' +
        app;
      version && (url += '&version=' + version);
      contentType && (url += '&contentType=' + contentType);
      this.lastParams.lib && (url += '&lib=' + this.lastParams.lib);
      this.lastParams.channelName &&
        (url += '&channelName=' + this.lastParams.channelName);
      window.open(url);
    },
  },
  components: {
    countTo,
    Search,
  },
};
</script>

<style>
.Content {
  margin: 10px 15px;
}
.libTitle {
  color: tomato;
  font-weight: 700;
  font-size: 14px;
}
.btn-next i,
.btn-prev i {
  margin: 0 auto;
}
.head {
  display: flex;
  font-weight: 500;
}
.head .head-item {
  flex: 1;
  text-align: center;
  font-size: 0.8em;
  border-top: 3px solid #fff;
  padding-top: 10px;
}
.head .value {
  margin: 15px 0;
  color: #396fff;
  font-size: 25px;
}
</style>
