<template>
  <div class="mainBox" v-loading="getDataStatus">
    <!-- 搜索区域 -->
    <div class="searchBox">
      <div style="font-size: large">
        <!-- 对比时间：
        <el-date-picker
          v-model="lastTimes"
          type="daterange"
          unlink-panels
          range-separator="到"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          disabled
          size="large"
          style="margin-right: 30px"
        /> -->
        搜索时间：
        <el-date-picker
          v-model="nowTimes"
          type="daterange"
          :clearable="false"
          unlink-panels
          range-separator="到"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          :shortcuts="shortcutsFun"
          size="large"
        />
      </div>
    </div>
    <!-- 服务调用card -->
    <div class="flex">
      <card
        v-for="item in TopCardDatas"
        :key="item.name"
        class="card flex"
        :title="item.name"
        :value="item.value"
        :growth="item.growth"
        :iconName="item.iconName"
        :iconColor="item.iconColor"
        :upStatus="item.upStatus"
      />
    </div>
    <!-- 服务类信息统计 -->
    <div class="bigCard">
      <div class="bigCard_title">服务类信息统计</div>
      <div class="tools">
        <el-button @click="downFileAllServiceDatas" :disabled="exportLoading">
          <!-- 这个要查询查询时间范围内的所有服务数据 -->
          <el-icon v-if="!exportLoading"><Upload /></el-icon>
          <el-icon v-else><Loading class="loading-icon" /></el-icon>
          导出数据
        </el-button>
        <el-button :disabled="dialogLoading" type="primary" @click="showDetailReport">
          <!-- 这个直接弹窗展示所有的服务调用数据，而不是下载 -->
          <el-icon v-if="!dialogLoading"><TrendCharts /></el-icon>
          <!-- 让图标旋转 -->
          <el-icon v-else><Loading class="loading-icon" /></el-icon>
          详细报告
        </el-button>
      </div>
      <div class="flex">
        <div style="width: 48%; height: 400px">
          <EchartsDome :chartOption="chartOptions['服务调用趋势']" title="服务调用趋势" />
        </div>
        <div style="width: 48%; height: 400px">
          <EchartsDome title="服务类别分布" :chartOption="chartOptions['服务类别分布']" />
        </div>
      </div>
      <div style="width: 100%; height: 400px">
        <Table title="服务调用TOP10" :tableData="tableDatas" />
      </div>
    </div>
    <!-- 服务调用详情弹窗 -->
    <el-dialog
      v-model="showServerDetailReport"
      width="80%"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="true"
      title="服务调用详情"
    >
      <div style="width: 100%; position: relative; padding-bottom: 30px" v-loading="dialogLoading">
        <!-- 过滤条件，全字段（除了调用时间）下拉框选择 -->
        <div style="width: 100%; margin-bottom: 10px; z-index: 1000">
          <!-- 再添加一个调用次数筛选 -->
          <div style="display: flex; align-items: center; margin-bottom: 10px">
            <span style="margin-right: 10px">调用次数:</span>
            <el-slider
              v-model="selectedModel['count']"
              :min="countMin"
              :max="countMax"
              range
              @change="changeSelectModel"
              style="width: calc(60%); margin: 0 20px"
            />
            最小值：
            <el-input-number
              v-model="selectedModel.count[0]"
              :min="countMin"
              :max="selectedModel.count[1]"
              @change="changeSelectModel"
            />
            最大值：
            <el-input-number
              v-model="selectedModel.count[1]"
              :min="selectedModel.count[0]"
              :max="countMax"
              @change="changeSelectModel"
            />
          </div>
          <!-- 支持筛选条件清空 -->
          <el-select
            style="width: 200px; margin-right: 10px"
            v-for="(value, key, index) in selectOptions"
            :key="key + index"
            v-model="selectedModel[key]"
            @change="changeSelectModel"
            :placeholder="'请选择' + selectKeyName[key]"
            filterable
            clearable
          >
            <el-option v-for="item in value" :key="item" :label="item" :value="item" />
          </el-select>
          <!-- 再添加一个时间搜索范围，字段是date, 格式是YYYY-MM-DD -->
          <el-date-picker
            style="margin-right: 10px"
            v-model="selectedModel['date']"
            type="daterange"
            clearable
            unlink-panels
            @change="changeSelectModel"
            :disabled-date="disabledDate"
            range-separator="到"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
          />
          <!-- 重置按钮 -->
          <el-button type="primary" @click="resetSelectModel">重置</el-button>
        </div>
        <el-table
          :data="showServerData"
          style="width: 100%"
          height="500px"
          border
          fit
          highlight-current-row
        >
          <el-table-column prop="application" label="应用名称" />
          <el-table-column prop="path_comment" label="服务名称" />
          <el-table-column prop="unit" label="委办单位" width="200" />
          <el-table-column prop="type" label="服务类别" width="120" />
          <el-table-column prop="count" label="调用次数" width="100" />
          <el-table-column prop="date" label="调用时间" width="120" />
        </el-table>
        <div style="float: right; padding-top: 10px">
          <el-pagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            :page-sizes="[50, 100, 200, 500]"
            background
            layout="total, sizes, prev, pager, next, jumper"
            :total="tableDataTotal"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
      </div>
    </el-dialog>
    <!-- 委办信息统计 -->
    <div class="bigCard">
      <div class="bigCard_title">委办信息统计</div>
      <div class="flex">
        <div style="width: 28%; height: 400px">
          <EchartsDome :chartOption="chartOptions['委办分布']" title="委办分布" />
        </div>
        <div style="width: 68%; height: 400px">
          <EchartsDome :chartOption="chartOptions['委办活跃度趋势']" title="委办活跃度趋势" />
        </div>
      </div>
      <!-- <div style="width: 100%; height: 400px">
        <EchartsDome :chartOption="chartOptions['用户部门分布']" title="用户部门分布" />
      </div> -->
    </div>
    <!-- 应用类信息统计 -->
    <div class="bigCard">
      <div class="bigCard_title">应用类信息统计</div>
      <div class="flex">
        <div style="width: 48%; height: 400px">
          <EchartsDome :chartOption="chartOptions['热点应用TOP10排名']" title="热点应用TOP10排名" />
        </div>
        <!-- <div style="width: 33%; height: 400px">
          <EchartsDome :chartOption="chartOptions['栏目统计分布']" title="栏目统计分布" />
        </div> -->
        <div style="width: 48%; height: 400px">
          <EchartsDome :chartOption="chartOptions['应用状态分布']" title="应用状态分布" />
        </div>
      </div>
    </div>
    <!-- 数据类信息统计 -->
    <div class="bigCard">
      <div class="bigCard_title">数据类信息统计</div>
      <div class="flex">
        <div style="width: 50%; height: 400px">
          <EchartsDome :chartOption="chartOptions['数据类别分布']" title="数据类别分布" />
        </div>
        <div style="width: 50%; height: 400px">
          <EchartsDome :chartOption="chartOptions['数据质量评分']" title="数据质量评分" />
        </div>
      </div>
    </div>
    <!-- 区级特色信息统计 -->
    <div class="bigCard">
      <div class="bigCard_title">区级特色信息统计</div>
      <div class="flex" style="margin-top: 20px">
        <div class="flex_column" style="width: 28%; height: 420px">
          <card
            class="card2 flex"
            :title="'服务机构总数'"
            value="8"
            :growth="'较上个月增长了12%'"
            iconColor="#2563db"
            :upStatus="1"
          />
          <card
            class="card2 flex"
            :title="'服务总数'"
            value="100"
            :growth="'较上个月下降了12%'"
            iconColor="#16a34a"
            :upStatus="-1"
          />
          <card
            class="card2 flex"
            :title="'服务调用总次数'"
            value="1000"
            :growth="'较上个月增长了12%'"
            iconColor="#9333ea"
            :upStatus="1"
          />
        </div>
        <div style="width: 68%; height: 420px">
          <EchartsDome :chartOption="chartOptions['服务调用趋势']" title="服务调用趋势" />
        </div>
      </div>
    </div>
    <!-- <HomePage_Demo /> -->


  </div>
</template>

<script>
import card from "@/components/yxgl/card.vue";
import EchartsDome from "@/components/yxgl/EchartsDome.vue";
import Table from "@/components/yxgl/table.vue";
import appCenter from "@/api/appCenter";
import { countlmType } from "@/api/count";
import HomePage_Demo from "@/views/HomePage_Demo.vue";

export default {
  name: "",
  components: {
    card,
    EchartsDome,
    Table,
    HomePage_Demo,
  },
  data() {
    return {
      // 导出Loading状态
      exportLoading: false,
      // 弹窗加载状态
      dialogLoading: false,
      // 获取数据状态
      getDataStatus: false,
      // 比较的时间范围(默认60天到30天前，主要跟nowTimes有关系)
      lastTimes: [],
      // 当前选中的时间范围
      nowTimes: [],
      // 服务调用详情弹窗是否显示
      showServerDetailReport: false,
      // 服务调用详情数据
      serverData: [],
      // 展示的详细数据（能根据时间和字段模糊筛选）
      showServerData: [],
      // 筛选条件下拉框选项
      selectOptions: {
        application: [],
        path_comment: [],
        unit: [],
        type: [],
      },
      selectKeyName: {
        application: "应用名称",
        path_comment: "服务名称",
        unit: "委办单位",
        count: "调用次数",
        type: "服务类型",
      },
      // 筛选条件下拉框选中的值
      selectedModel: {
        application: "",
        path_comment: "",
        unit: "",
        type: "",
        count: "",
        date: "",
      },
      // 调用次数范围的最小值和最大值
      countMin: 0,
      countMax: 0,
      tableColumns: ["application", "path_comment", "unit", "count", "type", "date"],
      // 分页大小
      pageSize: 50,
      // 当前页码
      currentPage: 1,
      // 表格数据总条数
      tableDataTotal: 0,
      TopCardDatas: [
        {
          name: "委办总数",
          value: "0",
          growth: "--",
          iconColor: "#2563db",
          iconName: "OfficeBuilding",
          upStatus: 0,
        },
        {
          name: "系统总数",
          value: "0",
          growth: "--",
          iconColor: "#16a34a",
          iconName: "WalletFilled",
          upStatus: 0,
        },
        {
          name: "服务总数",
          value: "0",
          growth: "--",
          iconColor: "#9333ea",
          iconName: "CollectionTag",
          upStatus: 0,
        },
        {
          name: "服务调用总数",
          value: "0",
          growth: "--",
          iconColor: "#ca8a04",
          iconName: "Paperclip",
          upStatus: 0,
        },
      ],
      shortcutsFun: this.shortcuts(),
      chartOptions: {},
      tableDatas: [],
      columnList: [],
    };
  },
  watch: {
    nowTimes: {
      handler(newVal, oldVal) {
        if (newVal !== oldVal && newVal.length > 0) {
          // 计算出比较的时间范围
          this.lastTimes = [
            this.$moment(
              new Date(
                new Date(newVal[0]).setTime(
                  new Date(newVal[0]).getTime() - (newVal[1] - newVal[0]) - 24 * 60 * 60 * 1000
                )
              )
            ).format("YYYY-MM-DD 00:00:00"),
            this.$moment(new Date(newVal[0])).format("YYYY-MM-DD 00:00:00"),
          ];

          // this.getColumnListDate();

          this.initChart();
          // 栏目统计分布
          this.getColumnCount();
        }
      },
      deep: true,
      // immediate: true,
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.nowTimes = [
        new Date(new Date().setTime(new Date() - 3600 * 1000 * 24 * 30)),
        new Date(),
      ];
    });
  },
  methods: {
    getColumnListDate(){
      let that = this;
      that.columnList = [];
      appCenter.getColumnListDate().then((res) => {
        // console.log("====getColumnListDate====="+res);
        if (res.code === 200) {
          // this.serverData = res.content;
          res.content.forEach(e => {
              that.getChildren(e)
          });
        }
      });
    },
    //递归查找子目录
    getChildren(e){
        let that = this;
        if(e.columnList.length>0){
            e.value=e.id
            e.label=e.title
            e.children = e.columnList;
            e.columnList.forEach(e2 => {
                that.getChildren(e2)
            });
        }else{
            e.value=e.modelId
            e.label=e.title
            e.children = []
            let str = {id:e.id,mid:e.modelId,title:e.title}
            that.columnList.push(str);
        }
    },
    // 禁用日期选择器中未来的日期(不能选择nowTimes以外的时间)
    disabledDate(time) {
      return (
        time.getTime() > this.nowTimes[1].getTime() ||
        time.getTime() < this.nowTimes[0].getTime() - 24 * 60 * 60 * 1000
      );
    },
    // 分页大小改变时，更新展示数据
    handleSizeChange() {
      this.dialogLoading = true;
      let searchDatas = this.serverData.filter((item) => {
        return (
          (!this.selectedModel.application ||
            item.application === this.selectedModel.application) &&
          (!this.selectedModel.path_comment ||
            item.path_comment === this.selectedModel.path_comment) &&
          (!this.selectedModel.unit || item.unit === this.selectedModel.unit) &&
          (!this.selectedModel.type || item.type === this.selectedModel.type)
        );
      });
      // 添加时间范围搜索逻辑
      if (this.selectedModel.date) {
        searchDatas = searchDatas.filter((item) => {
          return (
            new Date(item.date).getTime() >=
              new Date(
                this.$moment(new Date(this.selectedModel.date[0])).format("YYYY-MM-DD 00:00:00")
              ).getTime() &&
            new Date(item.date).getTime() <=
              new Date(
                this.$moment(new Date(this.selectedModel.date[1])).format("YYYY-MM-DD 23:59:59")
              ).getTime()
          );
        });
      }

      // 添加调用次数范围搜索逻辑
      if (this.selectedModel.count) {
        searchDatas = searchDatas.filter((item) => {
          return (
            item.count >= this.selectedModel.count[0] && item.count <= this.selectedModel.count[1]
          );
        });
      }

      // 格式化日期为YYYY-MM-DD格式
      searchDatas.forEach((item) => {
        item.date = this.$moment(new Date(item.date)).format("YYYY-MM-DD");
      });

      // 分页展示数据
      this.showServerData = searchDatas.slice(
        (this.currentPage - 1) * this.pageSize,
        this.currentPage * this.pageSize
      );

      // 遍历筛选条件下拉框选项，更新每个选项的数组
      for (let key in this.selectOptions) {
        this.selectOptions[key] = [
          ...new Set(searchDatas.map((item) => (item[key] ? item[key] : "未知"))),
        ];
      }
      // 更新分页组件数据
      this.tableDataTotal = searchDatas.length;
      this.showServerDetailReport = true;
      this.dialogLoading = false;
    },
    handleCurrentChange() {
      this.handleSizeChange();
    },
    // 筛选条件下拉框选中值改变时，触发的事件
    changeSelectModel() {
      // console.log(this.selectedModel);
      // 重置当前页码为第一页
      this.currentPage = 1;
      // 处理分页数据
      this.handleSizeChange();
    },
    // 重置筛选条件下拉框选中的值
    resetSelectModel() {
      for (let key in this.selectedModel) {
        this.selectedModel[key] = "";
      }
      this.selectedModel.count = [this.countMin, this.countMax];
      this.handleSizeChange();
    },
    // 打开弹窗，渲染table列表，展示查询时间的所有数据详情
    showDetailReport() {
      this.dialogLoading = true;
      // 要先请求，然后时间排序一下。
      appCenter
        .getServiceDataByDate({
          nowTimes: [
            this.$moment(new Date(this.nowTimes[0])).format("YYYY-MM-DD 00:00:00"),
            this.$moment(new Date(this.nowTimes[1])).format("YYYY-MM-DD 23:59:59"),
          ],
        })
        .then((res) => {
          if (res && res.code == 200) {
            if (res.content && res.content.length > 0) {
              res.content.forEach((item) => {
                this.tableColumns.forEach((key) => {
                  if (item[key] == undefined) {
                    item[key] = "未知";
                  }
                });
              });
              this.serverData = res.content;
              // 得到count的最大值和最小值
              this.countMax = Math.max(...this.serverData.map((item) => item.count));
              this.countMin = Math.min(...this.serverData.map((item) => item.count));
              this.resetSelectModel();
              this.handleSizeChange();
            } else {
              this.$message({
                message: "暂无数据",
                type: "warning",
              });
            }
          }
        })
        .catch((e) => {
          this.$message({
            message: e,
            type: "error",
          });
        })
        .finally(() => {
          this.dialogLoading = false;
        });
    },
    initChart() {
      this.getDataStatus = true;
      // 获取运行管理页面数据
      appCenter
        .getAllYxglDatas({
          nowTimes: [
            this.$moment(new Date(this.nowTimes[0])).format("YYYY-MM-DD 00:00:00"),
            this.$moment(new Date(this.nowTimes[1])).format("YYYY-MM-DD 23:59:59"),
          ],
          lastTimes: this.lastTimes,
        })
        .then((res) => {
          if (res && res.code == 200) {
            if (res.content.TopCardDatas && typeof res.content.TopCardDatas === "object") {
              // 不能覆盖iconName
              this.TopCardDatas.forEach((cardItem) => {
                res.content.TopCardDatas.forEach((cardData) => {
                  if (cardItem.name == cardData.name) {
                    cardItem.value = cardData.value;
                    cardItem.growth = cardData.growth;
                    cardItem.upStatus = cardData.upStatus;
                  }
                });
              });
            }

            this.dataToOption("服务调用趋势", "line", [...res.content.serviceCountTrend], {
              legend: { data: ["调用次数"] },
              xData: [],
              xKey: "date",
              xFormart: "YYYY-MM-DD",
              yAxis: {
                type: "value",
                name: "调用次数",
                axisLine: { lineStyle: { color: "#42a5f5" } }, // 区分样式
              },
              yData: {
                key: "count",
                name: "调用次数",
                color: "#42a5f5",
                data: [],
                yAxisIndex: 0,
              },
            });
            let serviceCountType = [];
            serviceCountType = res.content.serviceCountType;
            if (res.content.serviceCountType && res.content.serviceCountType.length > 0) {
              serviceCountType.forEach((item) => {
                if (!item.type) {
                  item.type = "未知";
                }
              });
            }
            // 初始化服务类别分布,这个地方需要先根据serviceType进行groupBy统计调用次数
            this.dataToOption("服务类别分布", "pie", serviceCountType, {
              pieKey: { value: "count", name: "type" },
              pieData: [],
              padAngle: 0,
              borderRadius: 0,
              label: {
                textStyle: {
                  textShadow: 'none',
                  color: '#fff'
                }
              },
            });

            // 服务调用TOP10
            let serviceDatas = [];
            serviceDatas = res.content.serviceCountTop;
            if (serviceDatas && serviceDatas.length > 0) {
              serviceDatas.forEach((item) => {
                if (!item.path_comment) {
                  item.path_comment = "未知";
                }
                if (!item.type) {
                  item.type = "未知";
                }
              });
            }
            // 排序
            serviceDatas.sort((a, b) => b.count - a.count);
            this.initTableDatas(serviceDatas.slice(0, 10));
            let serviceCountUnit = [];
            serviceCountUnit = res.content.serviceCountUnit;
            if (serviceCountUnit && serviceCountUnit.length > 0) {
              serviceCountUnit.forEach((item) => {
                if (!item.unit) {
                  item.unit = "未知";
                }
              });
            }
            // 委办分布
            this.dataToOption("委办分布", "pie", serviceCountUnit, {
              pieKey: { value: "count", name: "unit" },
              pieData: [],
              legend: {
                show: false,
                bottom: 10,
              },
              radius: "60%",
              padAngle: 0,
              borderRadius: 0,
              label: {
                textStyle: {
                  textShadow: 'none',
                  color: '#fff'
                }
              },
            });

            // 先同步一下legend
            let serviceCountUnitTrendLegend = [];
            serviceCountUnit.forEach((item) => {
              serviceCountUnitTrendLegend.push(item.unit);
            });
            this.dataToOption("委办活跃度趋势", "line", [...res.content.serviceCountUnitTrend], {
              legend: { data: serviceCountUnitTrendLegend },
              xData: [],
              xKey: "date",
              xFormart: "YYYY-MM-DD",
              yAxis: {
                type: "value",
                axisLine: { lineStyle: { color: "#fff" } }, // 区分样式
              },
              yDatas: { auto: true },
            });

            let serviceDatas2 = [];
            serviceDatas2 = res.content.serviceCountApplicationTop;
            // 排序
            serviceDatas2.sort((a, b) => b.count - a.count);
            let forData = serviceDatas2.slice(0, 10);
            let showApplicationTopDatas = [];
            for (let i = forData.length - 1; i >= 0; i--) {
              showApplicationTopDatas.push(forData[i]);
            }
            // 用户部门分布
            this.dataToOption("热点应用TOP10排名", "bar", showApplicationTopDatas, {
              showLegend: false,
              xData: [],
              xKey: "application",
              yData: {
                key: "count",
                name: "调用次数",
                color: "#42a5f5",
                data: [],
              },
            });
            // 数据类别分布
            if (res.content.dataTypes && res.content.dataTypes.length > 0) {
              this.dataToOption("数据类别分布", "pie", [...res.content.dataTypes], {
                pieKey: { value: "count", name: "service_name" },
                pieData: [],
                legend: {
                  bottom: 10,
                },
                radius: "60%",
                padAngle: 0,
                borderRadius: 0,
                label: {
                  textStyle: {
                    textShadow: 'none',
                    color: '#fff'
                  }
                },
              });
            }

            // console.log("getAllYxglDatas", res);
          }
          this.getDataStatus = false;
        })
        .catch((error) => {
          this.getDataStatus = false;
          this.$message({
            type: "error",
            message: "服务器忙碌，请稍后重试！",
          });
        });
      // 应用状态分布，cloumnId:1659
      appCenter
        .getDmsDataList({
          columnId: systemConfig.columnIds[1],
          pageSize: 1000,
          page: 0,
        })
        .then((res) => {
          if (res.code == 200) {
            let dmsDatas = res.content.data;
            let tableDatas = [];
            // 根据状态进行groupBy统计个数
            let statusMap = {};
            dmsDatas.forEach((item) => {
              if (statusMap[item.appstauts + ""]) {
                statusMap[item.appstauts + ""] += 1;
              } else {
                statusMap[item.appstauts + ""] = 1;
              }
            });
            // 转换为数组
            for (let key in statusMap) {
              if (statusMap[key] && key) {
                tableDatas.push({
                  name: this.$getDmsTypes("appstatus", key),
                  value: statusMap[key],
                });
              }
            }
            this.dataToOption("应用状态分布", "pie", tableDatas, {
              pieKey: { value: "value", name: "name" },
              pieData: [],
            });
          } else {
            this.$message({
              type: "error",
              message: "服务器忙碌，请稍后重试！",
            });
          }
        });

      this.dataToOption("数据质量评分", "radar", null, null);
    },
    getColumnCount() {
      let param = {
          start: this.$moment(new Date(this.nowTimes[0])).format("YYYY-MM-DD"),
          end: this.$moment(new Date(this.nowTimes[1])).format("YYYY-MM-DD"),
        };
        countlmType(param.start, param.end).then((res) => {

          if (res.length > 0) {
              this.dataToOption("栏目统计分布", "pie", [...res], {
                pieKey: { value: "count", name: "column" },
                pieData: [],
                legend: {
                  type: 'scroll',
                  bottom: 0,
                  // orient: 'vertical', // 水平布局  horizontal   垂直 vertical
                  pageButtonPosition: 'end', // 翻页按钮放右侧
                  pageIconColor: '#fff',
                  pageIconInactiveColor: '#999',
                  itemWidth: 10, // 图例标记宽度
                  itemHeight: 10, // 图例标记高度
                  pageTextStyle: {
                    color: '#fff'
                  },
                  pageIconSize: 12 // 翻页图标大小
                },
                radius: "60%",
                padAngle: 0,
                borderRadius: 0,
                label: {
                  textStyle: {
                    textShadow: 'none',
                    color: '#fff'
                  }
                },
              });
          }
        })
    },
    // 导出所选时间范围内的所有服务数据
    downFileAllServiceDatas() {
      this.exportLoading = true;
      appCenter
        .downFileAllServiceDatas({ nowTimes: this.nowTimes })
        .then((res) => {
          const blob = res; // 响应体是 Blob 类型
          if (!blob) {
            that.$message.error("下载失败：文件流为空");
            reject("文件流为空");
            return;
          }
          if (!(blob instanceof Blob) || blob.size === 0) {
            this.$message.error("文件流解析失败，无法生成下载链接");
            return;
          }
          const url = window.URL.createObjectURL(blob); // 将 Blob 转为临时 URL
          const link = document.createElement("a");
          link.href = url;
          link.download = "服务信息统计.xlsx"; // 设置下载文件名
          link.style.display = "none";
          document.body.appendChild(link);
          link.click(); // 触发点击下载
          document.body.removeChild(link);
          window.URL.revokeObjectURL(url); // 销毁临时 URL，避免内存泄漏
        })
        .catch((e) => {
          this.$message({
            message: "导出数据失败",
            type: "error",
          });
        })
        .finally(() => {
          this.exportLoading = false;
        });
    },
    /**
     * 数据转换为图表选项
     * @param title 图表标题
     * @param type 图表类型
     * @param datas 原始数据
     * @param keyRule 解析规则
     */
    async dataToOption(title, type, datas, keyRule) {
      // 根据规则解析数据
      if (keyRule) {
        datas.forEach((item) => {
          // 有的图表没有X轴
          if (keyRule.xKey) {
            if (keyRule.xFormart) {
              item[keyRule.xKey] = this.$moment(item[keyRule.xKey]).format(keyRule.xFormart);
            }
            keyRule.xData.push(item[keyRule.xKey]);

          }

          if (keyRule.yData) {
            keyRule.yData.data.push(item[keyRule.yData.key]);
            keyRule.series = [
              {
                name: keyRule.yData.name,
                type: "line",
                smooth: true,
                data: keyRule.yData.data,
                lineStyle: {
                  color: keyRule.yData.color ? keyRule.yData.color : "",
                  type: keyRule.yData.ifDashed ? "dashed" : "",
                }, // 蓝色线条
                itemStyle: keyRule.yData.color,
                symbol: "circle", // 节点形状
                symbolSize: 6, // 节点大小
              },
            ];
          }
          if (keyRule.yDatas) {
            // 先根据lenged得到data集合
            for (let name of keyRule.legend.data) {
              if (keyRule.yDatas[name]) {
                keyRule.yDatas[name].data.push(item[name]);
              } else {
                keyRule.yDatas[name] = {
                  name: name,
                  data: [item[name]],
                };
              }
            }
          }
          if (keyRule.pieKey) {
            keyRule.pieData.push({
              value: item[keyRule.pieKey.value],
              name: item[keyRule.pieKey.name],
            });
          }
        });
        // 专门用来处理多y数据的series
        if (keyRule.yDatas) {
          keyRule.series = [];
          for (let name of keyRule.legend.data) {
            keyRule.series.push({
              name: name,
              type: "line",
              smooth: true,
              data: keyRule.yDatas[name].data,
              symbol: "circle", // 节点形状
              symbolSize: 6, // 节点大小
            });
          }
        }
      }
      let _option = {};
      switch (type) {
        case "line":
          // 折线图基础
          _option = {
            legend: {
              data: keyRule.legend.data,
              // type: 'scroll',
              // top: 0,
              // // orient: 'vertical', // 水平布局  horizontal   垂直 vertical
              // pageButtonPosition: 'end', // 翻页按钮放右侧
              // pageIconColor: '#fff',
              // pageIconInactiveColor: '#999',
              // itemWidth: 10, // 图例标记宽度
              // itemHeight: 10, // 图例标记高度
              // pageTextStyle: {
              //   color: '#fff'
              // },
              // pageIconSize: 12 // 翻页图标大小
            },
            tooltip: {
              show: true,
              trigger: "axis",
              axisPointer: { type: "shadow" },
            },
            // 默认样式
            xAxis: {
              type: "category",
              data: keyRule.xData,
              axisTick: { show: false }, // 隐藏刻度
              splitLine: { show: false }, // 隐藏分割线
              axisLabel: {
                color: "#fff", // 字体颜色（支持十六进制、RGB、颜色名）
                fontSize: 14, // 可选：字体大小
                fontWeight: "normal", // 可选：字体粗细
                textShadow: 'none'
              },
            },
            yAxis: {
              type: "value",
              axisLabel: {
                color: "#fff", // 字体颜色（支持十六进制、RGB、颜色名）
                fontSize: 14, // 可选：字体大小
                fontWeight: "normal", // 可选：字体粗细
                textShadow: 'none'
              },
              splitLine: {
                lineStyle: {
                  type: "dashed", // 虚线网格
                  color: "#113761",
                },
              },
            },
            series: keyRule.series,
          };
          break;
        case "pie":
          // 饼状图
          _option = {
            tooltip: {
              trigger: "item",
            },
            legend: keyRule.legend
              ? keyRule.legend
              : {
                  orient: "vertical",
                  top: "50%",
                  right: 10,
                },
            series: [
              {
                name: title,
                type: "pie",
                radius: keyRule.radius ? keyRule.radius : ["40%", "70%"],
                avoidLabelOverlap: false,
                padAngle: keyRule.padAngle != undefined ? keyRule.padAngle : 5,
                itemStyle: {
                  borderRadius: keyRule.borderRadius != undefined ? keyRule.borderRadius : 10,
                },
                label:
                  keyRule.label != undefined
                    ? keyRule.label
                    : {
                        show: false,
                        position: "center",
                        textStyle: {
                          textShadow: 'none',
                          color: '#fff'
                        }
                      },
                emphasis: {
                  label: {
                    show: true,
                    fontSize: 20,
                    fontWeight: "bold",
                    textStyle: {
                      textShadow: 'none',
                      color: '#fff'
                    }
                  },
                },
                labelLine: {
                  show: true,
                },
                data: keyRule.pieData,
              },
            ],
          };
          break;
        case "bar":
          // 柱状图
          _option = {
            tooltip: {
              trigger: "axis",
              axisPointer: {
                type: "shadow",
              },
            },
            legend: {
              show: keyRule.showLegend ? keyRule.showLegend : false,
              data: keyRule.legend,
            },
            xAxis: {
              type: "value",
              interval: 0,
              axisLabel: {
                color: "#fff", // 字体颜色（支持十六进制、RGB、颜色名）
                fontSize: 12, // 可选：字体大小
                fontWeight: "normal", // 可选：字体粗细
                rotate: 30, // 旋转30度
                textShadow: 'none',
                textStyle: {
                    textShadow: 'none',
                    color: '#fff'
                  }
              },
              splitLine: { lineStyle: { color: "#fff" } },
            },
            yAxis: {
              type: "category",
              data: keyRule.xData,
              axisLabel: {
                color: "#F2F3F5cc", // 字体颜色（支持十六进制、RGB、颜色名）
                fontSize: 14, // 可选：字体大小
                fontWeight: "normal", // 可选：字体粗细
                textShadow: 'none',
                 textStyle: {
                    textShadow: 'none',
                    color: '#fff'
                  }
              },
            },
            series: [
              {
                name: keyRule.yData.name,
                type: "bar",
                label: {
                  show: true,
                  position: 'right',
                  valueAnimation: true,
                  textStyle: {
                    textShadow: 'none',
                    color: '#fff'
                  }
                },
                emphasis: {
                  focus: "series",
                },
                data: keyRule.yData.data,
              },
            ],
          };
          break;
        default:
          // 雷达图
          _option = {
            tooltip: {
              trigger: "axis",
            },
            legend: {
              show: false,
              left: "center",
            },
            radar: [
              {
                indicator: [
                  { name: "健壮性", max: 100 },
                  { name: "完整性", max: 100 },
                  { name: "一致性", max: 100 },
                  { name: "及时性", max: 100 },
                  { name: "准确性", max: 100 },
                ],
                axisLabel: {
                  color: '#fff',
                  fontSize: 14,
                  fontWeight: 'bold'
                },

              },
            ],
            series: [
              {
                type: "radar",
                tooltip: {
                  trigger: 'item'
                },
                itemStyle: {
                  color: '#4169E1',
                  borderColor: '#4169E1',
                  borderWidth: 2
                },
                areaStyle: {},
                data: [
                  {
                    value: [93, 85, 92, 95, 93],
                    name: "数据质量评分",
                  },
                ],
              },
            ],
          };
          break;
      }
      this.chartOptions[title] = _option;
    },
    // 服务调用列表
    initTableDatas(serviceTypeDatas2) {
      this.tableDatas = serviceTypeDatas2;
    },
    // 时间范围自定义时间
    shortcuts() {
      return [
        {
          text: "当天",
          value: () => {
            const end = new Date();
            const start = new Date();
            return [start, end];
          },
        },
        {
          text: "最近7天",
          value: () => {
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 6);
            return [start, end];
          },
        },
        {
          text: "最近30天",
          value: () => {
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 29);
            return [start, end];
          },
        },
        {
          text: "最近90天",
          value: () => {
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 89);
            return [start, end];
          },
        },
        {
          text: "最近1年",
          value: () => {
            const end = new Date();
            const start = new Date();
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 364);
            return [start, end];
          },
        },
      ];
    },
  },
};
</script>

<style lang="less" scoped>
.mainBox {
  width: calc(100% - 60px);
  margin: 30px;
  padding-bottom: 80px;
  & > div {
    margin: 20px 0;
    display: flex;
  }
  .card {
    width: calc(25% - 56px);
    border-radius: 5px;
    padding: 20px 18px;
    // background: #00000032;
    background: #eeeeee0b;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
  }

  .card2 {
    width: 100%;
    border-radius: 5px;
    padding: 20px 18px;
    // background: rgba(255, 255, 255, 0.1);
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
  }

  .bigCard {
    width: calc(100% - 36px);
    border-radius: 5px;
    padding: 20px 18px;
    // background: #00000032;
    position: relative;
    flex-direction: column;
    background: #eeeeee0b;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
    .tools {
      position: absolute;
      top: 20px;
      right: 20px;
      display: flex;
      flex-direction: row;
      justify-content: flex-end;
    }
    &_title {
      font-size: 20px;
      font-weight: bold;
    }
  }

  .flex {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
  }
  .flex_column {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: flex-start;
    box-sizing: border-box;
  }

  .searchBox {
    width: 100%;
    height: 50px;
    line-height: 50px;
    text-align: center;
    font-size: 20px;
    font-weight: bold;
    flex-direction: row-reverse;
    display: flex;
  }
}

// 日期选择框样式
.demo-date-picker {
  display: flex;
  width: 100%;
  padding: 0;
  flex-wrap: wrap;
}

.demo-date-picker .block {
  padding: 1.5rem 0;
  text-align: center;
  border-right: solid 1px var(--el-border-color);
  flex: 1;
  min-width: 400px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.demo-date-picker .block:last-child {
  border-right: none;
}

.demo-date-picker .demonstration {
  display: block;
  color: var(--el-text-color-secondary);
  font-size: 14px;
  margin-bottom: 1rem;
}

@media screen and (max-width: 1200px) {
  .demo-date-picker .block {
    flex: 0 0 100%;
    padding: 1rem 0;
    min-width: auto;
    border-right: none;
    border-bottom: solid 1px var(--el-border-color);
  }

  .demo-date-picker .block:last-child {
    border-bottom: none;
  }
}

// 弹窗加载状态图标
.loading-icon {
  // 图标顺时针旋转动画
  animation: loading-icon-spin 2s linear infinite;
}
@keyframes loading-icon-spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>
