<template>
  <div class="Version">
    <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"
          >
          </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
            filterable
            multiple
            collapse-tags
            clearable
            v-model="form.channel"
            @change="changechannel"
            placeholder="请选择渠道"
          >
            <el-option
              v-for="item in channel"
              :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
            filterable
            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 style="float: right">
          <el-button type="primary" @click="onSubmit">查询</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <br />
    <el-card class="box-card">
      <div style="text-align: right">
        <el-button-group>
          <el-button
            size="small"
            :type="numType === 'newUser' ? 'primary' : ''"
            @click="() => selectNumType('newUser')"
          >
            新用户数
          </el-button>
          <el-button
            size="small"
            :type="numType === 'startTimes' ? 'primary' : ''"
            @click="() => selectNumType('startTimes')"
          >
            启动次数
          </el-button> 
        </el-button-group>
      </div>
      <br />
      <div ref="regionChart"></div>
      <br />
      <div style="text-align: right">
        <el-button
          size="small"
          style="margin-left: 0.5em"
          type="primary"
          @click="onExport"
        >
          导出
        </el-button>
      </div>
      <br />
      <br />
      <el-table
        :data="table || []"
        style="width: 100%"
        :header-cell-style="{
          backgroundColor: '#f4f5f7',
          color: '#606266',
        }"
      >
        <el-table-column
          prop="appVersion"
          header-align="center"
          align="center"
          label="版本"
          show-overflow-tooltip
        >
          <template #default="scope">
            <span v-text="scope.row.appVersion || '-'"></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="upgradeUser"
          header-align="center"
          align="center"
          label="升级用户数"
          sortable
          show-overflow-tooltip
        >
          <template #default="scope">
            <countTo
              :startVal="scope.row.upgradeUser || 0"
              :endVal="scope.row.upgradeUser || 0"
              :duration="100"
            ></countTo>
          </template>
        </el-table-column>
        <el-table-column
          label="新用户数"
          header-align="center"
          align="center"
          prop="newUser"
          sortable
        >
          <template #default="scope">
            <countTo
              :startVal="scope.row.newUser || 0"
              :endVal="scope.row.newUser || 0"
              :duration="100"
            ></countTo>
          </template>
        </el-table-column>
        <el-table-column
          label="活跃用户数"
          header-align="center"
          align="center"
          prop="activeUser"
          sortable
        >
          <template #default="scope">
            <countTo
              :startVal="scope.row.activeUser || 0"
              :endVal="scope.row.activeUser || 0"
              :duration="100"
            ></countTo>
          </template>
        </el-table-column>
        <el-table-column
          label="启动次数"
          header-align="center"
          align="center"
          prop="startTimes"
          sortable
        >
          <template #default="scope">
            <countTo
              :startVal="scope.row.startTimes || 0"
              :endVal="scope.row.startTimes || 0"
              :duration="100"
            ></countTo>
          </template>
        </el-table-column>
        <el-table-column
          label="启动用户分布"
          header-align="center"
          align="center"
          prop="distribution"
          sortable
        >
          <template #default="scope">
            <countTo
              :startVal="scope.row.distribution || 0"
              :endVal="scope.row.distribution || 0"
              :duration="100"
            ></countTo
            >%
          </template>
        </el-table-column>
        <el-table-column
          label="平均使用时长"
          header-align="center"
          align="center"
          prop="duration"
          sortable
        >
          <template #default="scope">
            {{ timeFormat(scope.row.duration) }}
          </template>
        </el-table-column>
      </el-table>
    </el-card>
  </div>
</template>
<script>
// @ is an alias to /src
import {
  getRule,
  getAppList,
  getSearchData,
  getVersionChart,
  getVersionPage,
} 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: "Version",
  data() {
    return {
      lastParams: {},
      table: [],
      numType: "newUser",
      form: {
        app: "",
        version: [],
        channel: [],
        date: [],
      },
      cycle: [],
      showList: [],
      channel: [],
      version: [],
    };
  },
  async mounted() {
    if (chart && chart.dispose) chart.dispose();
    const { source, appV, appC, appli, appVLi, appCLi } =
      await this.getAppListFunc();
    const keys = {
      value: "mname",
      label: "mname",
    };
    this.cycle = this.verifyList(appli, source, keys, false);
    this.channel = this.verifyList(appCLi, appC, keys, true);
    this.version = this.verifyList(appVLi, appV, keys, false);
    let V = [];
    const len = this.version.length > 5 ? 5 : this.version.length;
    for (let i = 0; i < len; i++) {
      const item = this.version[i];
      V.push(item.value);
    }
    this.form = {
      //   app: (this.cycle[0] || { value: "" }).value,
      app: defaultAppNameFunc(this.cycle),
      version: V,
      channel: [(this.channel[0] || { value: "" }).value],
      date: [new Date(Date.now() - 604800000), new Date(Date.now() - 86400000)],
    };
    this.onSubmit();
  },
  computed: {},
  methods: {
    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;
    },
    selectNumType(type) {
      this.numType = type;
      getVersionChart({
        app: this.lastParams.app,
        start: this.lastParams.start,
        end: this.lastParams.end,
        version: this.form.version == -1 ? undefined : this.form.version,
      }).then(resChart => {
        const c = resChart || {};
        let keyList = [],
          valueList = [],
          titles = [];
        if ((resChart || []).length && chart && chart.clear) chart.clear();
        for (let index = 0; index < (Object.keys(c) || []).length; index++) {
          const v = (Object.keys(c) || [])[index];
          valueList.push((c[v] || []).map(v => v[this.numType]));
          titles.push(v);
          if (!keyList.length) keyList = (c[v] || []).map(v => v.dt);
        }
        this.createImage(keyList, valueList, titles);
      });
    },
    onSubmit() {
      this.lastParams = {
        app: this.form.app,
        start: this.FormData(this.form.date[0]),
        end: this.FormData(this.form.date[1]),
        manufacturer: this.form.channel == -1 ? undefined : this.form.channel,
        version: this.form.version == -1 ? undefined : this.form.version,
      };
      getVersionPage(this.lastParams).then(r => (this.table = r || []));
      getVersionChart(this.lastParams).then(resChart => {
        const c = resChart || {};
        let keyList = [],
          valueList = [],
          titles = [];
        if ((resChart || []).length && chart && chart.clear) chart.clear();
        for (let index = 0; index < (Object.keys(c) || []).length; index++) {
          const v = (Object.keys(c) || [])[index];
          valueList.push((c[v] || []).map(v => v[this.numType]));
          titles.push(v);
          if (!keyList.length) keyList = (c[v] || []).map(v => v.dt);
        }
        this.createImage(keyList, valueList, titles);
      });
    },
    createImage(keyList, valueList, title) {
      if (!chart) {
        chart = echarts.init(this.$refs.regionChart);
        window.onresize = chart.resize;
      }
      chart.resize({
        height: (this.$refs.regionChart.offsetWidth * 4) / 16,
      });
      chart.clear();
      chart.setOption({
        tooltip: {
          confine: true,
          trigger: "axis",
        },
        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, channel } = await this.getAppListOri();
      let source = { length: 0 },
        appli = [];
      let appV = { length: 0 },
        appVLi = [];
      let appC = { length: 0 },
        appCLi = [];
      let prvList = 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 == "CHANNEL")
          (appC[v.detid] = true), (appC.length = appC.length + 1);
      }
      if (li.status === "0") appli = li.output.data || [];
      if (appVersion.length) appVLi = appVersion || [];
      if (channel.length) appCLi = channel || [];
      return {
        source,
        appV,
        appC,
        appli,
        appVLi,
        appCLi,
      };
    },
    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 appVersion = await getSearchData({
        gcode: "APP_VERSION",
        source: defaultAppNameFunc(cycle, 'mname'),
      });
      //   应用渠道列表
      const channel = await getSearchData({
        gcode: "CHANNEL",
        source: defaultAppNameFunc(cycle, 'mname'),
      });
      return { r, li, appVersion, channel };
    },
    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,
      };
      getRule({
        db: "authplat",
        exportMark: "0",
        menuid: 399,
        roleid,
      }).then(rule => {
        let prvList = 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 = [];
          r.map(v => {
            if ((appV.length && appV[v.mcode]) || appV.length === 0)
              version.push({
                value: v.mname,
                label: v.mname,
              });
          });
          this.version = version;
          let V = [];
          const len = this.version.length > 5 ? 5 : this.version.length;
          for (let i = 0; i < len; i++) {
            const item = this.version[i];
            V.push(item.value);
          }
          this.form = {
            ...this.form,
            version: V,
          };
        });
        getSearchData({
          gcode: "CHANNEL",
          source: this.form.app,
        }).then(r => {
          let channel = [
            {
              label: "不限",
              value: -1,
            },
          ];
          r.map(v => {
            if ((appV.length && appV[v.mcode]) || appV.length === 0)
              channel.push({
                value: v.mname,
                label: v.mname,
              });
          });
          this.channel = channel;
          this.form = {
            ...this.form,
            channel: [-1],
          };
        });
      });
    },
    changeversion(v) {
      if (!v.length)
        return (this.form.version = [(this.version[0] || {}).value]);
      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;
    },
    changechannel(v) {
      if (!v.length) return (this.form.channel = [-1]);
      const last = v[v.length - 1];
      if (last == -1) return (this.form.channel = [-1]);
      let ver = [];
      for (let i = 0; i < v.length; i++) {
        const element = v[i];
        if (element == -1) continue;
        ver.push(element);
      }
      this.form.channel = ver;
    },
    onExport() {
      const S = this.form.date[0]
        ? this.FormData(this.form.date[0])
        : undefined;
      const E = this.form.date[1]
        ? this.FormData(this.form.date[1])
        : undefined;
      let p = this.lastParams.app
        ? this.lastParams
        : {
            app: this.form.app,
            start: S,
            end: E,
            manufacturer:
              this.form.channel == -1 ? undefined : this.form.channel,
            version: this.form.version == -1 ? undefined : this.form.version,
          };
      getVersionPage(p).then(r => {
        // 生成数据
        let strcsv =
          "data:text/csv;charset=utf-8,\uFEFF版本,应用,升级用户数,新用户数,活跃用户数,启动次数,启动用户(分布),平均使用时长\r\n";
        (r || []).map(v => {
          strcsv += [
            v.appVersion,
            p.app,
            v.upgradeUser,
            v.newUser,
            v.activeUser,
            v.startTimes,
            v.distribution + "%",
            this.timeFormat(v.duration),
            "\r\n",
          ].join(",");
        });
        // 导出
        let link = document.createElement("a");
        link.id = "download-csv";
        link.setAttribute("href", encodeURI(strcsv));
        link.setAttribute(
          "download",
          p.app + "版本分析" + S + "_" + E + ".csv"
        );
        // document.body.appendChild(link);
        link.click();
        link = undefined;
      });
    },
  },
  components: {
    countTo,
  },
};
</script>

<style>
.Version {
  margin: 10px 15px;
}
.libTitle {
  color: tomato;
  font-weight: 700;
  font-size: 14px;
}
.btn-next i,
.btn-prev i {
  margin: 0 auto;
}
/* .caret-wrapper .ascending {
  display: none;
} */
</style>
