<template>
  <div v-if="showReportData" style="width: 100%; height: calc(100% - 70px);">
    <div class="cy-report-content">
      <div class="cy-div0">
        <div class="cy-report-ruler-unit">mm</div>
      </div>
      <div class="cy-div1">
        <div class="cy-ruler-top">
          <ruler-view ruler-position="horizontal"></ruler-view>
        </div>
        <div class="cy-box">
          <div class="cy-ruler-left">
            <ruler-view ruler-position="vertical"></ruler-view>
          </div>
          <div class="cy-box-main">
            <el-input type="text" placeholder="请输入报表模板标题" v-model="templateName" maxlength="20" size="mini" show-word-limit></el-input>
            <div id="luckysheet"
                 style="margin:0px;padding:0px;position:relative;height:calc(100% - 40px);width:100%;left: 0px;top: 0px;bottom:0px;">
            </div>
          </div>
        </div>
      </div>
      <div class="cy-div2">
        <input ref="importFileNode" class="import-file-node" type="file" @change="loadExcel" style="display: none;"></input>
        <div v-if="templateId && templateId != 0 && templateId != -999" class="cy-chart-div" @click="saveReportTemplate('saveAs')">
          <svg-icon icon-class="report_save" style="width: 35px; height: 35px; margin-bottom: 6px;"/>
          <span>另存为</span>
        </div>
        <div class="cy-chart-div" @click="saveReportTemplate">
          <svg-icon icon-class="report_save" style="width: 35px; height: 35px; margin-bottom: 6px;"/>
          <span>保存</span>
        </div>
        <div class="cy-chart-div" @click="resetReport(false)">
          <svg-icon icon-class="report_cancel" style="width: 30px; height: 30px; margin-bottom: 8px;"/>
          <span>重置</span>
        </div>
        <el-divider></el-divider>
        <div class="cy-chart-div" @click="templateEvent()">
          <svg-icon icon-class="report_template" style="width: 35px;"/>
          <span>模板库</span>
        </div>
        <div class="cy-chart-div" @click="dataEvent(1)">
          <svg-icon icon-class="report_basedata" style="width: 35px;"/>
          <span>基础数据项</span>
        </div>
        <div class="cy-chart-div" @click="dataEvent()">
          <svg-icon icon-class="report_data" style="width: 35px;"/>
          <span>数据项</span>
        </div>
        <div class="cy-chart-div" @click="barEvent('bar')">
          <svg-icon icon-class="bar_chart"/>
          <span>柱状图</span>
        </div>
        <div class="cy-chart-div" @click="barEvent('line')">
          <svg-icon icon-class="line_chart"/>
          <span>折线图</span>
        </div>
        <div class="cy-chart-div" @click="barEvent('pie')">
          <svg-icon icon-class="pie_chart"/>
          <span>饼状图</span>
        </div>
      </div>
    </div>

    <!-- 图表右键操作 -->
    <ul v-show="visibleChartMenu"
        :style="{ left: menuLeft + 'px', top: menuTop + 'px' }"
        class="contextmenu contextmenu-black">
      <li @click="updateChartItem">修改</li>
      <li @click="delChartItem">删除</li>
    </ul>

    <!-- 弹出层：图配置 -->
    <el-drawer
        :title="chartConfigTitle"
        :visible.sync="dialogBarChartVisible"
        :show-close="false"
        :close-on-press-escape="false"
        :wrapperClosable="false"
        :before-close="dialogClose">
      <el-form ref="barChartForm" :model="barChartForm" label-position="top" size="mini" style="margin: 0 20px;">
        <el-form-item label="图表标题：" prop="title" class="label-title1">
          <el-input type="text" placeholder="请输入标题" v-model="barChartForm.title" maxlength="80" show-word-limit>
          </el-input>
        </el-form-item>
        <el-form-item label="图表副标题：" prop="subtitle" class="label-title1">
          <el-input type="text" placeholder="请输入副标题" v-model="barChartForm.subtitle" maxlength="60" show-word-limit>
          </el-input>
        </el-form-item>
        <el-form-item label="是否显示图表标题：" prop="showTitle">
          <el-radio v-model="barChartForm.showTitle" label="1">是</el-radio>
          <el-radio v-model="barChartForm.showTitle" label="0">否</el-radio>
        </el-form-item>
        <el-form-item label="是否显示图例：" prop="showLegend">
          <el-radio v-model="barChartForm.showLegend" label="1">是</el-radio>
          <el-radio v-model="barChartForm.showLegend" label="0">否</el-radio>
        </el-form-item>
<!--        <el-form-item label="图例：" prop="legendType" v-if="barChartForm.type != 'pie'">-->
<!--          <el-radio v-model="barChartForm.legendType" label="1">数据项</el-radio>-->
<!--          <el-radio v-model="barChartForm.legendType" label="0">值</el-radio>-->
<!--        </el-form-item>-->
        <el-form-item label="数据组：">
          <el-select filterable
                     v-model="chooseDataGroup"
                     placeholder="请选择数据组"
                     @change="dataSourceChange"
                     style="width: calc(100% - 110px);">
            <el-option
                v-for="dict in dataGroupList"
                :key="dict.id"
                :label="dict.groupName"
                :value="dict.id"
            ></el-option>
          </el-select>
          <el-button size="mini" @click="addDataItem" style="float: right;width: 100px;">选择数据项</el-button>
          <el-tag size="mini" v-if="chooseItemData.length > 0"
                  style="margin-top: 10px;"
                  class="cy-item-tag">已选择({{ chooseItemData.length }})项</el-tag>
        </el-form-item>
        <el-button type="warning" size="mini" @click="insertBarChartForm(0)">应用</el-button>
        <el-button type="primary" size="mini" @click="insertBarChartForm(1)">保存</el-button>
        <el-button size="mini" @click="cancelBarChartForm">取消</el-button>
      </el-form>
    </el-drawer>

    <!-- 数据组选择 -->
    <el-dialog
        title="选择数据项"
        width="600px"
        top="10vh"
        center
        v-dialog-drag
        v-if="dialogDataItemVisible"
        :before-close="dialogItemClose"
        :visible.sync="dialogDataItemVisible"
        :close-on-click-modal="false"
        :append-to-body="true">
      <div>
        <div style="margin-bottom: 10px;">
          <span>组名称：{{ itemDataListByGroupName }}（共 {{ itemDataListByTree.length }} 项）</span>
          <el-checkbox v-model="isSelectAllItem" @change="selectAllItem" style="float: right;">全选</el-checkbox>
        </div>
        <el-input placeholder="请输入关键字进行过滤" v-model="filterItemData"></el-input>
        <div style="height: 50vh; margin-top: 10px; overflow: auto;">
          <el-tree class="cy-item-tree"
                   ref="itemTree"
                   :data="itemDataListByTree"
                   :indent="10"
                   node-key="id"
                   show-checkbox
                   :check-on-click-node="true"
                   :filter-node-method="filterItemDataNode"
                   :highlight-current="true"
                   :default-expand-all="true"
                   @check-change="handleItemCheckChange">
              <span class="custom-tree-node" slot-scope="{ node, data }">
                <svg-icon v-if="!data.children || data.children.length == 0" icon-class="file"/>
                <svg-icon v-else-if="node.expanded" icon-class="folder-open"/>
                <svg-icon v-else icon-class="folder"/>
                <span :title='data.itemName || "-"' style="margin-left: 2px;">
                  {{ data.describe
                    ? ((data.itemName ? data.itemName : '') + '（' + data.describe + '）')
                    : data.itemName ? data.itemName : '' }}
                </span>
              </span>
          </el-tree>
        </div>
      </div>
      <div style="width: 100%;text-align: center;">
        <el-button type="primary"
                   @click="chooseItemTreeEvent"
                   style="margin-top: 20px;">确定</el-button>
      </div>
    </el-dialog>

    <!-- 选择基础数据项 -->
    <el-dialog
        title="选择基础数据项"
        width="500px"
        center
        v-dialog-drag
        v-if="dialogBaseDataVisible"
        :before-close="dialogBaseDataClose"
        :visible.sync="dialogBaseDataVisible"
        :close-on-click-modal="false"
        :append-to-body="true">
      <el-select v-model="chooseBaseData" filterable placeholder="请选择数据项" style="width: 100%;">
        <el-option
            v-for="item in this.baseDataList"
            :key="item.id"
            :label="item.dictKey"
            :value="item.dictValue">
        </el-option>
      </el-select>
      <div style="width: 100%; text-align: center; margin-top: 20px;">
        <el-button type="warning" @click="baseItemEvent(0)">应用</el-button>
        <el-button type="primary" @click="baseItemEvent(1)">确定</el-button>
        <el-button @click="dialogBaseDataClose">取消</el-button>
      </div>
    </el-dialog>

    <el-dialog
        title="选择四则运算表达式"
        width="500px"
        top="10vh"
        center
        :before-close="dialogDataModelClose"
        :visible.sync="dialogDataModelVisible"
        :close-on-click-modal="false"
        :append-to-body="true">
      <el-select v-model="chooseDataModel" filterable placeholder="请选择表达式" style="width: 100%;">
        <el-option
            v-for="item in this.dataModelList"
            :key="item.id"
            :label="item.operationRule"
            :value="item.id">
        </el-option>
      </el-select>
      <div style="width: 100%; text-align: center; margin-top: 20px;">
        <el-button type="primary" @click="saveDataModelEvent">确定</el-button>
        <el-button @click="dialogDataModelClose">取消</el-button>
      </div>
    </el-dialog>

    <!-- 公共模板报表类型选择 -->
    <el-dialog
        title="选择模板报表"
        width="60vw"
        center
        v-dialog-drag
        v-if="dialogCommReportVisible"
        :before-close="dialogClose"
        :visible.sync="dialogCommReportVisible"
        :close-on-click-modal="false"
        :append-to-body="true">
      <div style="height: 60vh; overflow: auto;">
        <div style="height: 50px; display: flex;">
          <div style="width: 50%;">
            <label style="margin-right: 15px;">模板名称</label>
            <el-input placeholder="请输入报表模板名称进行过滤"
                      v-model="searchReportTxt"
                      @input="handleReportTypeInputChange"
                      style="width: calc(100% - 100px); margin-bottom: 10px;">
            </el-input>
          </div>
          <div style="width: 50%;">
            <label style="margin-right: 15px;">所属行业</label>
            <el-input placeholder="请选择所属行业"
                      @click.native="clickCascader"
                      v-model="reportTypeInputName"
                      readonly
                      style="width: calc(100% - 100px); z-index: 1;">
            </el-input>
            <el-cascader v-model="reportType"
                         ref="reportType"
                         :options="reportTypes"
                         style="width: calc(100% - 100px); width: 40px; margin-left: calc(-100% + 100px);"
                         :props="{ value: 'id', label: 'dictKey', emitPath: true, multiple: false }"
                         clearable
                         @change="handleReportTypeChange"
                         @expand-change="handleReportTypeNodeChange"></el-cascader>
          </div>
        </div>
        <div style="height: calc(100% - 50px); overflow: auto;">
          <el-empty v-if="commTemplateList.length == 0" description="暂无数据"></el-empty>
          <div v-else style="margin-top: 10px;">
            <div v-for="item in commTemplateList"
                 style="float: left;width: 30%;display: flex;flex-direction: column;align-items: center;margin-top: 10px;">
              <el-image v-if="item.logo == 'zsxt.png'" :src="require('@/assets/images/template/zsxt.png')" fit="contain" style="height: 80px;"></el-image>
              <el-image v-else-if="item.logo == 'jcscs.png'" :src="require('@/assets/images/template/jcscs.png')" fit="contain" style="height: 80px;"></el-image>
              <el-image v-else-if="item.logo == 'ncs.png'" :src="require('@/assets/images/template/ncs.png')" fit="contain" style="height: 80px;"></el-image>
              <el-image v-else :src="require('@/assets/images/template/muban.png')" fit="contain" style="height: 80px;"></el-image>
              <el-radio v-model="commTemplate" :label="item"
                        style="margin-top: 5px;width: 100%;text-overflow: ellipsis;white-space: nowrap;overflow: hidden;text-align: center;">
                {{ item.templateName }}
              </el-radio>
            </div>
          </div>
        </div>
      </div>
      <div style="text-align: center; margin-top: 40px;">
        <el-button type="warning" @click="commReportEvent(0)">应用</el-button>
        <el-button type="primary" @click="commReportEvent(1)">确定</el-button>
        <el-button @click="dialogClose">取消</el-button>
      </div>
    </el-dialog>

    <!-- 选择数据组数据 -->
    <el-dialog
        title="数据项配置"
        width="80%"
        top="10vh"
        center
        v-dialog-drag
        v-if="dialogGroupItemVisible"
        :before-close="dialogClose"
        :visible.sync="dialogGroupItemVisible"
        :close-on-click-modal="false"
        :append-to-body="true">
      <div>
        <div>
          <el-select filterable
                     v-model="chooseDataGroup"
                     placeholder="请选择数据组"
                     style="width: calc(100% - 110px);">
            <el-option
                v-for="dict in dataGroupList"
                :key="dict.id"
                :label="dict.groupName"
                :value="dict.id"
            ></el-option>
          </el-select>
          <el-button size="mini" @click="addDataItem" style="float: right;width: 100px;margin-top: 4px;">选择数据项</el-button>
        </div>
        <div style="height: 30vh; margin-top: 10px; overflow: auto;">
          <el-tree class="cy-item-tree"
                   ref="itemTree"
                   :data="chooseGroupItemList"
                   :indent="10"
                   node-key="id"
                   :check-on-click-node="true"
                   :filter-node-method="filterItemDataNode"
                   :highlight-current="true"
                   :default-expand-all="true">
              <span class="custom-tree-node" slot-scope="{ node, data }">
                <svg-icon v-if="!data.children || data.children.length == 0" icon-class="file"/>
                <svg-icon v-else-if="node.expanded" icon-class="folder-open"/>
                <svg-icon v-else icon-class="folder"/>
                <span v-if="!data.children || data.children.length == 0" :title='data.itemName || "-"' style="margin-left: 2px;">
<!--                  {{ data.describe-->
<!--                    ? ((data.itemName ? data.itemName : '') + '【' + data.describe + '】')-->
<!--                    : data.itemName ? data.itemName : '' }}-->
                  {{ '【' + data.groupName + '】' + data.itemName + (data.describe ? ('（' + data.describe + '）') : '') }}
                </span>
                <span v-else :title='data.groupName || "-"' style="margin-left: 2px;">
                  {{ data.groupName }}
                </span>
              </span>
          </el-tree>
        </div>
        <div v-if="chooseGroupItemList.length > 0">
          <template>
            <el-divider content-position="left">数据项排列方式</el-divider>
            <div class="cy-line custom-tree">
              <el-radio-group v-model="itemShowParams.fieldType" @input="showDataTypeEvent">
                <el-radio label="1">横向</el-radio>
                <el-radio label="2">纵向</el-radio>
              </el-radio-group>
            </div>
          </template>
          <template>
            <el-divider content-position="left">值显示数量</el-divider>
            <div class="cy-line custom-tree" style="display: flex; align-items: center;">
              <div style="width: 50%;display: none;">
                <label>显示方式：</label>
                <el-radio v-model="itemShowParams.valType" label="1">横向</el-radio>
                <el-radio v-model="itemShowParams.valType" label="2">纵向</el-radio>
              </div>
              <div style="width: 50%;">
<!--                <label>值显示数量：</label>-->
                <el-input-number label="请输入显示数量"
                                 v-model="itemShowParams.valLine"
                                 :min="1"
                                 :max="50"></el-input-number>
              </div>
            </div>
          </template>
        </div>
      </div>
      <div style="width: 100%;text-align: center;">
        <el-button type="warning" style="margin-top: 20px;" @click="itemEvent(0)">应用</el-button>
        <el-button type="primary" style="margin-top: 20px;" @click="itemEvent(1)">确定</el-button>
        <el-button style="margin-top: 20px;" @click="dialogClose">取消</el-button>
      </div>
    </el-dialog>

  </div>
  <div v-else></div>
</template>

<script>
import RulerView from '@/components/RulerView'
import LuckyExcel from 'luckyexcel'
import {
  getAllDataModel,
  getAllItemGroup, getSysTableTemplate, getSysTableTemplateById,
  getTableItemGroupById,
  getTableTemplateById,
  saveReportTemplate,
  updateReportTemplate
} from "@/api/datasource";
import {getLuckysheetConfig, handleTree, showAlertWin, showLoading, traverseNode, traverseVisible} from "@/utils/cqcy";
import {getDictByKey} from "@/api/basic";
import {exportExcel} from "@/utils/export";
import {insertLuckysheetEChart} from "@/utils/luckysheettool";

export default {
  name: 'index',
  components: {
    RulerView
  },
  data() {
    return {
      showReportData: true,
      dialogBarChartVisible: false,
      dialogDataItemVisible: false,
      dialogDataModelVisible: false,
      dialogCommReportVisible: false,
      dialogGroupItemVisible: false,
      dialogBaseDataVisible: false,
      isSelectAllItem: false,
      menuLeft: 0,
      menuTop: 0,
      visibleChartMenu: false,
      chooseChartClz: '',
      chartConfigTitle: '',
      barChartForm: {
        title: '',
        type: '',
        subtitle: '',
        showTitle: '1',
        showLegend: '1',
        legendType: '1',
        legendData: ['模板数据1', '模板数据2'],
        xAxisData: ['数据1', '数据2', '数据3']
      },
      barChartOption: {
      },
      itemShowParams: {
        fieldType: '1',
        valType: '2',
        valLine: 1,
        dataId: new Date().getTime()
      },
      baseDataList: [],
      chooseBaseData: null,
      dataGroupList: [],
      itemDataListByTree: [],
      itemDataListByGroupName: '',
      itemDataListByCalc: [],
      chooseGroupItemList: [],
      dataModelList: [],
      chooseDataModel: null,
      chooseDataItemIndex: null,
      bomCheckKey: 0,
      chooseDataGroup: null,
      chooseItemData: [],
      filterItemData: '',
      searchReportTxt: '',
      keyType: 'report_template',
      reportTypes: [],
      reportType: null,
      reportTypeInputName: '所有',
      reportTypeInputId: [],
      commTemplate: null,
      commTemplateList: [],
      templateName: '',
      templateId: '',
      templateVersion: '',
      reportTemplateItem: this.$store.getters.sessionName.REPORT_TEMPLATE_ITEM,
      reportInterval: null,
      toolChart: [],
      toolTable: [],
      luckysheetOption: {
        container: 'luckysheet', // 设定 DOM 容器的 id
        title: '报表模板', // 设定表格名称
        lang: 'zh', // 设定表格语言
        showinfobar: false, // 是否显示顶部信息栏
        showtoolbar: false, // 是否显示工具栏
        showtoolbarConfig: {
          paintFormat: true, //格式刷
          moreFormats: true, // 单元格格式
          font: true, // 字体
          fontSize: true, // 字号大小
          bold: true, // 粗体 (Ctrl+B)
          italic: true, // 斜体 (Ctrl+I)
          strikethrough: true, // 删除线 (Alt+Shift+5)
          underline: true, // 下划线 (Alt+Shift+6)
          textColor: true, // 文本颜色
          fillColor: true, // 单元格颜色
          border: true, // 边框
          mergeCell: true, // 合并单元格
          horizontalAlignMode: true, // 水平对齐方式
          verticalAlignMode: true, // 垂直对齐方式
          function: true, // 公式
          // image: true
          // chart: true
        },
        showsheetbar: false, // 是否显示底部 sheet 页按钮
        sheetFormulaBar: false, // 是否显示公式
        row: 100, // 是否显示底部 sheet 页按钮
        data: [{
          "name": "统计报表", //工作表名称
        }],
        cellRightClickConfig: { // 自定义配置单元格右击菜单
          copy: true, // 复制
          copyAs: false, // 复制为
          paste: true, // 粘贴
          insertRow: true, // 插入行
          insertColumn: true, // 插入列
          deleteRow: true, // 删除选中行
          deleteColumn: true, // 删除选中列
          deleteCell: false, // 删除单元格
          hideRow: false, // 隐藏选中行和显示选中行
          hideColumn: false, // 隐藏选中列和显示选中列
          rowHeight: true, // 行高
          columnWidth: true, // 列宽
          clear: false, // 清除内容
          matrix: false, // 矩阵操作选区
          sort: false, // 排序选区
          filter: false, // 筛选选区
          chart: true, // 图表生成
          image: false, // 插入图片
          link: false, // 插入链接
          data: false, // 数据验证
          cellFormat: false // 设置单元格格式
        },
        plugins: ['chart']
      }
    }
  },
  watch: {
    '$route.query.t': {
      handler(now, old) {
        this.initLuckysheet(this.$route.query.id, this.$route.query.type)
      }
    },
    filterItemData(val) {
      this.$refs.itemTree.filter(val)
    },
    visibleChartMenu(value) {
      if (value) {
        document.body.addEventListener('click', this.closeMenu)
      } else {
        document.body.removeEventListener('click', this.closeMenu)
      }
    }
  },
  mounted() {
    let _this = this
    $(function () {
      if (_this.showReportData) {
        let tempId = _this.$route.query.id
        let type = _this.$route.query.type
        _this.initLuckysheet(tempId, type)
      }
    })
    document.onkeyup = function (event) {
      let e = event || window.event || arguments.callee.caller.arguments[0]
      if (!e) return
      const {key, keyCode} = e
      if (keyCode === 46 || keyCode === 8) {
        _this.forceRefreshLuckysheet()
      }
    }
  },
  created() {
    let _this = this

    // 强制关闭自定义图表右键菜单
    document.body.oncontextmenu = (e) => {
      setTimeout(() => {
        if ($('#luckysheet-rightclick-menu') && 'block' == $('#luckysheet-rightclick-menu').css('display')) {
          _this.closeMenu()
        }
      }, 500)
    }
  },
  destroyed() {
    luckysheet.destroy()
    if (this.reportInterval) {
      clearInterval(this.reportInterval)
    }
  },
  methods: {
    /** 初始化操作 */
    initLuckysheet(tempId, type) {
      let _this = this
      if (type && type != 'export') {
        this.withTypeReportTemplate(type)
        return
      }
      if (tempId && tempId != -999) {
        _this.getTableTemplate(tempId, type)
        return
      }
      this.templateId = null
      this.templateVersion = null
      this.templateName = ''
      this.toolChart = []
      this.toolTable = []
      luckysheet.destroy()
      let locItem = localStorage.getItem(_this.reportTemplateItem)
      if (locItem && JSON.parse(locItem).data && Array.isArray(JSON.parse(locItem).data)) {
        let option = JSON.parse(JSON.stringify(_this.luckysheetOption))
        option.data = JSON.parse(locItem).data
        _this.toolChart = JSON.parse(locItem).charts
        _this.toolTable = JSON.parse(locItem).tables
        option.hook = {
          workbookCreateAfter() {
            for (let i in _this.toolChart) {
              _this.insertEChartTool(_this.toolChart[i].info, false)
            }
            _this.autoSaveReportInfo()
          },
          cellUpdated(r, c, newV, oldV) {
            if (!(r === 49 && c === 0)) {
              _this.forceRefreshLuckysheet()
            }
          }
        }
        luckysheet.create(option)
      } else {
        let option = JSON.parse(JSON.stringify(_this.luckysheetOption))
        option.hook = {
          workbookCreateAfter() {
            _this.autoSaveReportInfo()
          },
          cellUpdated(r, c, newV, oldV) {
            if (!(r === 49 && c === 0)) {
              _this.forceRefreshLuckysheet()
            }
          }
        }
        luckysheet.create(option)
      }
    },
    /** 实现类似刷新效果 */
    forceRefreshLuckysheet() {
      if (luckysheet) {
        luckysheet.setCellValue(49, 0, luckysheet.getCellValue(49, 0))
      }
    },
    /** 数据项全选事件 */
    selectAllItem() {
      const data = traverseNode(this.$refs.itemTree.store.root.childNodes)
      if (this.isSelectAllItem) {
        // this.$refs.itemTree.setCheckedNodes(this.itemDataListByTree)
        let arr = traverseVisible(data)
        let ids = Array.from(arr, ({ id }) => id)
        this.$refs.itemTree.setCheckedKeys(ids)
      } else {
        this.$refs.itemTree.setCheckedNodes([])
      }
    },
    /**数据项单项选择判断 */
    handleItemCheckChange(data, checked, indeterminate) {
      const tdata = traverseNode(this.$refs.itemTree.store.root.childNodes)
      let arr = traverseVisible(tdata)
      if (arr.length == this.$refs.itemTree.getCheckedNodes().length) {
        this.isSelectAllItem = true
      } else {
        this.isSelectAllItem = false
      }
    },
    /** 处理日期显示数字问题 */
    withDateData(excelData) {
      if (!excelData) {
        return
      }
      excelData.map((item) => {
        if (item) {
          item.map((ll) => {
            if (ll && ll.ct && ll.ct.t && ll.ct.t === 'd') {
              ll.m = ll.m,
                  ll.v = ll.m,
                  ll.ct = {
                    fa: "@",
                    t: "s",
                  }
            }
          })
        }
      })
    },
    /** 保存模版信息 */
    saveReportTemplate(type) {
      let _templateName = this.templateName
      let _title = '保存'
      if (type == 'saveAs') {
        this.templateName = '副本_' + _templateName
        _title = '另存为'
      }
      this.$prompt('请输入/确认报表模板名称', _title, {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        customClass: 'close_confirm',
        closeOnClickModal: false,
        inputValue: this.templateName,
        inputValidator: (val) => {
          if (!val) {
            return '模板名称不能为空'
          }
          if (val.length > 20) {
            return '模板名称必须在20字以内'
          }
        }
      }).then(({ value }) => {
        const loading = showLoading(this, '保存中，请稍候···')
        let option = JSON.parse(JSON.stringify(this.luckysheetOption))
        let _data = JSON.parse(getLuckysheetConfig())
        let excelData = _data[0].data
        this.withDateData(excelData)
        this.spliceToolTable()
        let result = {
          'charts': this.toolChart,
          'tables': this.toolTable,
          'option': option,
          'data': _data
        }
        let data = {
          'templateName': value,
          'templateData': JSON.stringify(result)
        }
        if (this.templateId && type != 'saveAs') {
          data.id = this.templateId
          data.version = this.templateVersion
          updateReportTemplate(data).then(res => {
            loading.close()
            let msg = res.data ? '修改成功！' : '修改失败！'
            let msgType = res.data ? 'success' : 'error'
            this.$message({
              message: msg,
              type: msgType
            })
            this.resetReport(true)
            this.getTableTemplate(this.$route.query.id, this.$route.query.type)
            this.$emit('refreshReportTemplateData', new Date().getTime())
          }).catch((e) => {
            loading.close()
            this.templateName = _templateName
            showAlertWin(this, e)
          })
        } else {
          saveReportTemplate(data).then(res => {
            loading.close()
            let msg = res.data ? '保存成功！' : '保存失败！'
            let msgType = res.data ? 'success' : 'error'
            this.$message({
              message: msg,
              type: msgType
            })
            this.resetReport(true)
            this.$emit('refreshReportTemplateData', new Date().getTime())
          }).catch((e) => {
            loading.close()
            this.templateName = _templateName
            showAlertWin(this, e)
          })
        }
      }).catch(() => {
        this.templateName = _templateName
      })
    },
    /** 重置报表信息 */
    resetReport(clearFlag) {
      let _this = this
      localStorage.removeItem(this.reportTemplateItem)
      if (clearFlag) {
        this.templateId = null
        this.templateVersion = null
        this.templateName = ''
      }
      this.toolChart = []
      this.toolTable = []
      luckysheet.destroy()
      let option = JSON.parse(JSON.stringify(this.luckysheetOption))
      option.hook = {
        workbookCreateAfter() {
          _this.autoSaveReportInfo()
        },
        cellUpdated(r, c, newV, oldV) {
          if (!(r === 49 && c === 0)) {
            _this.forceRefreshLuckysheet()
          }
        }
      }
      luckysheet.create(option)
    },
    /** 处理报表事件报表内容 */
    withTypeReportTemplate(type) {
      this.resetReport(true)
      if (type === 'import') { // 报表模板导入
        console.log('导入报表')
        this.$refs.importFileNode.dispatchEvent(new MouseEvent('click'))
      }
    },
    /** 导入报表 */
    loadExcel(evt) {
      console.log(evt)
      let _this = this
      const files = evt.target.files
      if (files == null || files.length == 0) {
        _this.$message({
          message: '请选择文件',
          type: 'warning'
        })
        return
      }
      console.log(files)
      // 获取文件名
      let name = files[0].name
      // 获取文件后缀
      let suffixArr = name.split("."),
          suffix = suffixArr[suffixArr.length - 1]
      if (suffix != 'xlsx') {
        _this.$message({
          message: '只能导入xlsx格式文件！',
          type: 'warning'
        })
        return
      }
      const loading = showLoading(this, '文件导入中，请稍候···')
      // 转换导入的excel
      LuckyExcel.transformExcelToLucky(files[0], function (exportJson, luckysheetfile) {
        if (exportJson.sheets == null || exportJson.sheets.length == 0) {
          loading.close()
          _this.$message({
            message: '无法读取excel文件的内容，当前不支持xls文件！',
            type: 'warning'
          })
          return
        }
        console.log('exportJson', exportJson)
        // 销毁之前的表格
        window.luckysheet.destroy()
        // 创建新的表格
        let option = JSON.parse(JSON.stringify(_this.luckysheetOption))
        option.data = exportJson.sheets
        option.title = exportJson.info.name
        option.data = exportJson.sheets
        option.hook = {
          workbookCreateAfter() {
            _this.autoSaveReportInfo()
          },
          cellUpdated(r, c, newV, oldV) {
            if (!(r === 49 && c === 0)) {
              _this.forceRefreshLuckysheet()
            }
          }
        }
        window.luckysheet.create(option)
        document.getElementsByClassName('import-file-node')[0].value = ''
        loading.close()
      })
    },
    /** 生成唯一 ID 字符串 */
    generateRandomKey(prefix) {
      if (prefix == null) {
        prefix = 'chart'
      }
      let userAgent = window.navigator.userAgent
          .replace(/[^a-zA-Z0-9]/g, '')
          .split('')
      let mid = ''
      for (let i = 0; i < 12; i++) {
        mid += userAgent[Math.round(Math.random() * (userAgent.length - 1))]
      }
      let time = new Date().getTime()

      return prefix + '_' + mid + '_' + time
    },
    /** 向 Excel 插入图表 */
    insertEChartTool(info, flag, item, legendType) {
      let _this = this
      let _self = this
      setTimeout(() => {
        const sheet = luckysheet.getLuckysheetfile()[0]
        let optionData = sheet.data
        try {
          insertLuckysheetEChart({
            selector: '#luckysheet',
            info,
            sheet,
            optionData,
            echarts,
            luckysheet,
            $,
            _self
          })
        } catch (e) {
          console.error(e)
        }
        // 保存图表信息
        if (flag) {
          let chart = {
            'info': info,
            'legendType': legendType,
            'item': item
          }
          _this.toolChart.push(chart)
        }
        // 图表事件监听
        $('.' + info.className).mousedown(function(e) {
          if (3 == e.which) {
            _this.closeMenu()
            _this.menuTop = e.pageY
            _this.menuLeft = e.pageX / 2
            _this.visibleChartMenu = true
            _this.chooseChartClz = info.className
            setTimeout(() => {
              $('#luckysheet-rightclick-menu').css('display', 'none')
            }, 100)
          }
        })
      }, 200)
    },
    /** 获取右侧数据组列表 */
    getDataGroupList() {
      getAllItemGroup().then(res => {
        this.dataGroupList = res.data
      }).catch((e) => {
        showAlertWin(this, e)
      })
    },
    /** 选择数据源值改变事件 */
    dataSourceChange(val) {
      this.chooseDataGroup = val
      this.chooseItemData = []
    },
    /** 数据项搜索过滤 */
    filterItemDataNode(value, data) {
      if (!value) return true
      return data.itemName.indexOf(value) !== -1
    },
    /** 添加数据项 */
    addDataItem() {
      let id = this.chooseDataGroup
      if (!id) {
        this.$message({
          message: '请选择数据组！',
          type: 'warning'
        })
        return
      }
      this.isSelectAllItem = false
      this.itemDataListByTree = []
      const loading = showLoading(this, '加载中，请稍候···')
      getTableItemGroupById(id).then(res => {
        loading.close()
        this.itemDataListByGroupName = res.data.groupName
        this.itemDataListByTree = res.data.itemList
        let tempList = this.chooseGroupItemList.length == 0 ? this.chooseItemData : this.chooseGroupItemList
        if (this.$refs.itemTree) this.$refs.itemTree.setCheckedKeys([])
        if (tempList.length > 0) {
          let idList = Array.from(tempList, ({ id }) => id)
          setTimeout(() => {
            if (this.$refs.itemTree) this.$refs.itemTree.setCheckedKeys(idList)
            if (this.itemDataListByTree.length == idList.length) {
              this.isSelectAllItem = true
            } else {
              this.isSelectAllItem = false
            }
          },100)
        }
        this.dialogDataItemVisible = true
      }).catch((e) => {
        loading.close()
        showAlertWin(this, e)
      })
    },
    /** 选择的数据项：第一步 */
    chooseItemTreeEvent() {
      let checkedNodes = this.$refs.itemTree.getCheckedNodes(false, true)
      if (checkedNodes.length == 0) {
        this.$message({
          message: '请选择数据项！',
          type: 'warning'
        })
        return
      }
      let chooseList = []
      for (let i in checkedNodes) {
        let checkedNode = checkedNodes[i]
        if (checkedNode.children && checkedNode.children.length > 0) {
          continue
        }
        chooseList.push(checkedNode)
      }
      this.chooseItemData = chooseList
      this.dialogDataItemVisible = false
      if (this.dialogGroupItemVisible) {
        this.initGroupItem()
      }
      this.filterItemData = ''
      // this.getAllDataModel(chooseList)
    },
    initGroupItem() {
      let group = null
      for (let i = 0; i < this.dataGroupList.length; i ++) {
        if (this.dataGroupList[i].id == this.chooseDataGroup) {
          group = this.dataGroupList[i]
          break
        }
      }
      this.chooseGroupItemList = this.chooseGroupItemList.filter(function (item, index) {
        return item.itemGroupId != group.id;
      })

      for (let j = 0; j < this.chooseItemData.length; j ++) {
        this.chooseItemData[j].groupName = group.groupName
        this.chooseGroupItemList.push(this.chooseItemData[j])
      }
      let obj = {};
      this.chooseGroupItemList = this.chooseGroupItemList.reduce(function(item, next) {
        obj[next.id] ? '' : obj[next.id] = true && item.push(next)
        return item;
      }, [])
    },
    /** 查询所有数据模型 */
    getAllDataModel(itemList) {
      let loading = showLoading(this, '数据加载中，请稍候···')
      let params = {
        'page': 1,
        'limit': 1000
      }
      getAllDataModel(params).then(res => {
        loading.close()
        if (!res.data) {
          this.chooseItemData = itemList
          return
        }
        this.dataModelList = res.data.dataModelList
        this.itemDataListByCalc = JSON.parse(JSON.stringify(itemList))
        for (let i in this.itemDataListByCalc) {
          let temp = this.itemDataListByCalc[i]
          temp.rule = {
            'operationRule': '默认值'
          }
        }
      }).catch((e) => {
        loading.close()
        showAlertWin(this, e)
      })
    },
    /** 选择数据模型 */
    handleChoose(index, row) {
      this.chooseDataItemIndex = index
      this.chooseDataModel = null
      this.dialogDataModelVisible = true
    },
    /** 保存数据模型事件 */
    saveDataModelEvent() {
      if (!this.chooseDataModel) {
        this.$message({
          message: '请选择表达式！',
          type: 'warning'
        })
        return
      }
      let item = {}
      for (let i in this.dataModelList) {
        if (this.chooseDataModel == this.dataModelList[i].id) {
          item = this.dataModelList[i]
        }
      }
      this.$nextTick(() => {
        this.itemDataListByCalc[this.chooseDataItemIndex].rule = item
        this.bomCheckKey ++
      })
      this.dialogDataModelVisible = false
    },
    /** 报表模板库 */
    templateEvent() {
      this.commTemplateList = []
      this.reportTypes = []
      this.reportType = null
      // 获取报表类别
      getDictByKey({
        'keyType': 'report_template'
      }).then(res => {
        this.reportTypes.push({
          'id': -1,
          'dictKey': '所有',
          'dictValue': ''
        })
        let t = handleTree(res.data, 'id', 'parentId', 'children')
        this.reportTypes = this.reportTypes.concat(t)
        this.dialogCommReportVisible = true
        this.handleReportTypeChange([-1])
      }).catch((e) => {
        showAlertWin(this, e)
      })
    },
    clickCascader() {
      this.$refs.reportType.$el.click()
      this.reportType = null
    },
    searchDictTree(nodes, searchKey) {
      for (let _i = 0; _i < nodes.length; _i++) {
        if (nodes[_i].id === searchKey) {
          return nodes[_i].dictKey
        } else {
          if (nodes[_i].children && nodes[_i].children.length > 0) {
            let res = this.searchDictTree(nodes[_i].children, searchKey)
            if (res) {
              return res
            }
          }
        }
      }
      return null
    },
    handleReportTypeInputChange() {
      let arr = this.reportTypeInputId.length == 0 ? [-1] : this.reportTypeInputId
      this.handleReportTypeChange(arr)
    },
    /** 报表行业选择 */
    handleReportTypeNodeChange(val) {
      this.handleReportTypeChange(val)
    },
    /** 报表行业选择 */
    handleReportTypeChange(val) {
      if (!val || val.length == 0) {
        return
      }
      let nameArr = []
      val.forEach(v => {
        let name = this.searchDictTree(this.reportTypes, v)
        nameArr.push(name)
      })
      this.reportTypeInputName = nameArr.join(' / ')
      this.reportTypeInputId = val
      let id = val[val.length - 1]
      if (id === -1) {
        this.reportTypeInputName = '所有'
        this.reportTypeInputId = []
        id = null
      }
      let params = {
        'keyType': this.keyType,
        'dictId': id
      }
      if (this.searchReportTxt && this.searchReportTxt.trim()) {
        params.templateName = this.searchReportTxt.trim()
      }
      getSysTableTemplate(params).then(res => {
        if (!res.data) {
          return
        }
        this.commTemplateList = res.data
      }).catch((e) => {
        showAlertWin(this, e)
      })
    },
    /** 选择模板报表 */
    commReportEvent(flag) {
      let _this = this
      if (!_this.commTemplate) {
        _this.$message({
          message: '请选择模板！',
          type: 'warning'
        })
        return
      }
      const loading = showLoading(_this, '加载中，请稍候···')
      getSysTableTemplateById(_this.commTemplate.id).then(res => {
        if (!res || !res.data) {
          loading.close()
          return
        }
        let locItem = res.data.templateData
        luckysheet.destroy()
        let option = JSON.parse(JSON.stringify(_this.luckysheetOption))
        option.data = JSON.parse(locItem).data
        this.toolChart = JSON.parse(locItem).charts
        this.toolTable = JSON.parse(locItem).tables
        option.hook = {
          workbookCreateAfter() {
            loading.close()
            if (flag == 1) _this.dialogClose()
          },
          cellUpdated(r, c, newV, oldV) {
            if (!(r === 49 && c === 0)) {
              _this.forceRefreshLuckysheet()
            }
          }
        }
        luckysheet.create(option)
      }).catch((e) => {
        loading.close()
        showAlertWin(_this, e)
      })
    },
    /** 数据项 */
    dataEvent(type) {
      let rangeWithFlatten = luckysheet.getRangeWithFlatten()
      if (!rangeWithFlatten || rangeWithFlatten.length != 1) {
        this.$message({
          message: '请选择一项单元格！',
          type: 'warning'
        })
        return
      }
      // 基础数据项
      if (type == 1) {
        this.getBaseDataItem()
        return
      }
      // 初始化数据显示方式
      this.itemShowParams = {
        fieldType: '1',
        valType: '2',
        valLine: 1,
        dataId: new Date().getTime()
      }
      this.chooseDataGroup = null
      this.getDataGroupList()
      this.dialogGroupItemVisible = true
    },
    /** 查询字典表：基础数据项 */
    getBaseDataItem() {
      getDictByKey({
        'keyType': 'base_data_item'
      }).then(res => {
        this.dialogBaseDataVisible = true
        this.baseDataList = res.data
      }).catch((e) => {
        showAlertWin(this, e)
      })
    },
    /** 基础数据项插入 */
    baseItemEvent(flag) {
      if (!this.chooseBaseData) {
        this.$message({
          message: '请选择基础数据项！',
          type: 'warning'
        })
        return
      }
      let rangeWithFlatten = luckysheet.getRangeWithFlatten()
      let c = rangeWithFlatten[0].c
      let r = rangeWithFlatten[0].r
      luckysheet.setCellValue(r, c, this.chooseBaseData)
      if (flag == 1) this.dialogBaseDataClose()
    },
    /** 动态数据项插入 */
    itemEvent(flag) {
      if (this.chooseGroupItemList.length == 0) {
        this.$message({
          message: '请选择数据组项！',
          type: 'warning'
        })
        return
      }
      let rangeWithFlatten = luckysheet.getRangeWithFlatten()
      let c = rangeWithFlatten[0].c
      let r = rangeWithFlatten[0].r
      let fieldList = []
      for (let n = 0; n < this.itemShowParams.valLine; n ++) {
        for (let i in this.chooseGroupItemList) {
          let groupId = this.chooseGroupItemList[i].itemGroupId
          let name = this.chooseGroupItemList[i].itemName
          name = name.substring(name.lastIndexOf('.') + 1)
          let isCopy = ''
          if (n > 0) isCopy = '.copy'
          let v = '${' + groupId + '.' + name + '.' + this.itemShowParams.dataId + isCopy + '}'
          let p_c = parseInt(c)
          let p_r = parseInt(r)
          // fieldType：1 横向 2 纵向
          if (this.itemShowParams.fieldType == '2') {
            p_r += parseInt(i)
            p_c += n
          } else {
            p_c += parseInt(i)
            p_r += n
          }
          if (n === 0) {
            fieldList.push({
              'name': v,
              'r': p_r,
              'c': p_c
            })
          }
          luckysheet.setCellValue(p_r, p_c, v)
        }
      }
      let tableTem = {
        'item': this.chooseGroupItemList,
        'field': fieldList,
        'showType': this.itemShowParams
      }
      this.toolTable.push(tableTem)
      this.spliceToolTable()
      if (flag == 1) {
        this.chooseGroupItemList = []
        this.chooseDataGroup = null
        this.chooseItemData = []
        this.dialogGroupItemVisible = false
      }
    },
    spliceToolTable() {
      for (let i = this.toolTable.length - 1; i >= 0; i --) {
        let info = this.toolTable[i]
        if (info.field && info.field[0]) {
          let v = luckysheet.getCellValue(info.field[0].r, info.field[0].c)
          if (v != info.field[0].name) {
            this.toolTable.splice(i, 1)
          }
        } else {
          this.toolTable.splice(i, 1)
        }
      }
      // 去重
      this.toolTable = this.uniqueFunc(this.toolTable, 'dataId')
    },
    uniqueFunc(arr, uniId){
      try {
        const res = new Map()
        return arr.filter((item) => !res.has(item.showType[uniId]) && res.set(item.showType[uniId], 1))
      } catch (e) {
        return arr
      }
    },
    /** 柱状图 */
    barEvent(type) {
      let _this = this
      // 当前选择范围
      let rangeWithFlatten = luckysheet.getRangeWithFlatten()
      if (!rangeWithFlatten || rangeWithFlatten.length <= 1) {
        _this.$message({
          message: '请选择多项单元格！',
          type: 'warning'
        })
        return
      }
      this.chooseDataGroup = null
      this.getDataGroupList()
      if (!type) {
        type = 'bar'
      }
      if (type == 'bar') {
        this.chartConfigTitle = '柱状图配置'
      } else if (type == 'line') {
        this.chartConfigTitle = '折线图配置'
      } else if (type == 'pie') {
        this.chartConfigTitle = '饼状图配置'
      }
      this.barChartForm.type = type
      // 显示柱状图配置信息
      this.dialogBarChartVisible = true
    },
    /** 柱状图图表插入 */
    insertBarChartForm(flag) {
      if (this.barChartForm.showTitle == '1' && !this.barChartForm.title) {
        this.$message({
          message: '标题不能为空！',
          type: 'warning'
        })
        return
      }
      if (!this.chooseDataGroup) {
        this.$message({
          message: '请选择数据组！',
          type: 'warning'
        })
        return
      }
      if (this.chooseItemData.length == 0) {
        this.$message({
          message: '请选择数据组项！',
          type: 'warning'
        })
        return
      }
      if ((this.barChartForm.legendType == '0' && this.chooseItemData.length > 1)
          || (this.barChartForm.type == 'pie' && this.chooseItemData.length > 1)) {
        this.$message({
          message: '请选择一项数据项！',
          type: 'warning'
        })
        return
      }
      // 图表参数
      this.barChartOption = {
        title: {
          show: this.barChartForm.showTitle == '1',
          text: this.barChartForm.title,
          subtext: this.barChartForm.subtitle,
          left: 'center'
        },
        tooltip: {},
        legend: {
          show: this.barChartForm.showLegend == '1',
          orient: 'vertical',
          left: 'left',
          data: []
        },
        series: []
      }
      if (this.barChartForm.type != 'pie') {
        this.barChartOption.xAxis = {
          data: this.barChartForm.xAxisData
        }
        this.barChartOption.yAxis = {
        }
        // 图表图例类型：1 数据项 0 值
        if (this.barChartForm.legendType == '1') {
          let legendNameList = []
          for (let i in this.chooseItemData) {
            let name = this.chooseItemData[i].describe
            name = name ? name : this.chooseItemData[i].itemName
            legendNameList.push(name)
          }
          this.barChartOption.legend.data = legendNameList
        } else {
          this.barChartOption.legend.data = ['值', '运算值']
        }

        // this.barChartOption.legend.data = this.barChartForm.legendData
        for (let i in this.barChartOption.legend.data) {
          let seriesName = this.barChartOption.legend.data[i]
          let dataList = []
          for (let j in this.barChartForm.xAxisData) {
            dataList.push(Math.ceil(Math.random() * 10))
          }
          let series = {
            name: seriesName,
            type: this.barChartForm.type,
            data: dataList
          }
          this.barChartOption.series.push(series)
        }
      } else {
        this.barChartOption.legend.data = null
        let seriesName = this.barChartForm.legendData[0]
        let dataList = []
        for (let i in this.barChartForm.xAxisData) {
          dataList.push({
            value: Math.ceil(Math.random() * 10),
            name: this.barChartForm.xAxisData[i]
          })
        }
        let series = {
          name: seriesName,
          type: this.barChartForm.type,
          radius: '50%',
          data: dataList
        }
        this.barChartOption.series.push(series)
      }

      if (this.barChartForm.uid) {
        this.delChartItem()
      }

      // 合并当前选择范围
      luckysheet.setRangeMerge('all')
      // 图表插入的 x、y 轴坐标获取
      let range = luckysheet.getRange()
      let x = range[0].column[0]
      let y = range[0].row[0]
      // 随机类名称
      let clz = this.generateRandomKey('chart_clz')
      let info = {
        id: this.generateRandomKey('chart'), // 唯一 id
        pos: [y, x], // eCharts 插入的单元格横、纵坐标
        className: clz, // 给定eCharts容器的 className，自定义
        chart: null, // 创建的 eCharts 实例
        option: this.barChartOption // eCharts 图形配置选项
      }
      this.insertEChartTool(info, true, this.chooseItemData, this.barChartForm.legendType)
      this.chooseDataGroup = null
      if (flag == 0) {
        setTimeout(() => {
          this.chooseChartClz = clz
          this.updateChartItem()
        }, 1000)
        return
      }
      this.$refs.barChartForm.resetFields()
      this.chooseItemData = []
      this.dialogBarChartVisible = false
    },
    /** 取消图表插入 */
    cancelBarChartForm() {
      this.$refs.barChartForm.resetFields()
      this.chooseDataGroup = null
      this.chooseItemData = []
      this.dialogBarChartVisible = false
    },
    /** 图表修改 */
    updateChartItem() {
      this.getDataGroupList()
      let chartInfo = {}
      for (let i in this.toolChart) {
        if (this.toolChart[i].info.className == this.chooseChartClz) {
          chartInfo = this.toolChart[i]
        }
      }
      let temp = chartInfo.info.option
      this.barChartForm.uid = new Date().getTime()
      this.barChartForm.title = temp.title.text
      this.barChartForm.subtitle = temp.title.subtext
      this.barChartForm.showTitle = temp.title.show ? '1' : '0'
      this.barChartForm.showLegend = temp.legend.show ? '1' : '0'
      this.barChartForm.type = temp.series[0].type
      this.barChartForm.legendType = chartInfo.legendType
      this.chooseItemData = chartInfo.item
      this.chooseDataGroup = chartInfo.item[0].itemGroupId
      this.dialogBarChartVisible = true
    },
    /** 图表删除 */
    delChartItem() {
      if (!this.chooseChartClz) {
        return
      }
      $('.' + this.chooseChartClz).remove()
      luckysheet.cancelRangeMerge()
      for (let i in this.toolChart) {
        if (this.toolChart[i].info.className == this.chooseChartClz) {
          this.toolChart.splice(i, 1)
        }
      }
    },
    /** 自动存储报表信息 */
    autoSaveReportInfo() {
      let _this = this
      if (this.reportInterval) {
        clearInterval(this.reportInterval)
      }
      let time = setInterval(() => {
        if (!this.templateId) {
          let result = {
            'charts': _this.toolChart,
            'tables': _this.toolTable,
            'data': JSON.parse(getLuckysheetConfig())
          }
          localStorage.setItem(_this.reportTemplateItem, JSON.stringify(result))
          console.log(new Date().getTime(), 'auto save report template success.')
        }
      }, 5 * 1000)
      this.reportInterval = time
    },
    /** 获取模板报表信息 */
    getTableTemplate(id, type) {
      let _this = this
      if (!id || id == -999) {
        this.resetReport(true)
        return
      }
      getTableTemplateById(id).then(res => {
        if (!res.data) {
          return
        }
        luckysheet.destroy()
        this.templateName = res.data.templateName
        this.templateId = res.data.id
        this.templateVersion = res.data.version
        let templateData = res.data.templateData
        let option = JSON.parse(JSON.stringify(this.luckysheetOption))
        option.data = JSON.parse(templateData).data
        this.toolChart = JSON.parse(templateData).charts
        this.toolTable = JSON.parse(templateData).tables
        option.hook = {
          workbookCreateAfter() {
            for (let i in _this.toolChart) {
              _this.insertEChartTool(_this.toolChart[i].info, false)
            }
            // 报表模板导出
            if (type === 'export' && type === localStorage.getItem('__export')) {
              localStorage.setItem('__export', '')
              exportExcel(luckysheet.getAllSheets(), _this.templateName)
            }
          },
          cellUpdated(r, c, newV, oldV) {
            if (!(r === 49 && c === 0)) {
              _this.forceRefreshLuckysheet()
            }
          }
        }
        luckysheet.create(option)
      }).catch((e) => {
        showAlertWin(this, e)
      })
    },
    /** 数据值显示类型事件 */
    showDataTypeEvent(val) {
      if (val == 1) {
        this.itemShowParams.valType = '2'
      } else {
        this.itemShowParams.valType = '1'
      }
    },
    clearRt() {
      this.reportTypeInputName = '所有'
      this.reportTypeInputId = []
      this.reportType = null
      this.searchReportTxt = ''
    },
    /** 弹出层关闭事件 */
    dialogClose(done) {
      this.chooseDataGroup = null
      this.chooseItemData = []
      this.chooseGroupItemList = []
      this.filterItemData = ''
      this.clearRt()

      this.commTemplate = null
      if (typeof(done) === 'function') {
        done()
      } else {
        this.dialogBarChartVisible = false
        this.dialogDataItemVisible = false
        this.dialogDataModelVisible = false
        this.dialogCommReportVisible = false
        this.dialogGroupItemVisible = false
      }
    },
    /** 弹出层关闭事件 */
    dialogItemClose(done) {
      this.itemDataListByTree = []
      this.filterItemData = ''
      if (typeof(done) === 'function') {
        done()
      } else {
        this.dialogDataItemVisible = false
      }
    },
    /** 弹出层关闭事件 */
    dialogDataModelClose() {
      if (typeof(done) === 'function') {
        done()
      } else {
        this.dialogDataModelVisible = false
      }
    },
    /** 弹出层关闭事件 */
    dialogBaseDataClose() {
      this.chooseBaseData = null
      if (typeof(done) === 'function') {
        done()
      } else {
        this.dialogBaseDataVisible = false
      }
    },
    /** 关闭右键弹出层 */
    closeMenu() {
      this.visibleChartMenu = false
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss">
.cy-report-content {
  width: 100%;
  height: 100%;
  padding-left: 6px;
  color: #FFFFFF;
  font-size: 14px;
  background-color: #2c3e50;
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
}

.cy-div0 {
  width: 30px;
  height: 30px;
  background: #767676;
}

.cy-div1 {
  width: calc(100% - 90px);
  height: 100%;
}

.cy-div2 {
  width: 60px;
  height: 100%;
  z-index: 1;
  background: #2c3e50;
  overflow: auto;
}

.cy-report-ruler-unit {
  width: 30px;
  height: 30px;
  display: flex;
  justify-content: center;
  align-items: center;
  float: left;
  border-right: 1px solid #2c3e50;
  border-bottom: 1px solid #2c3e50;
}

.cy-ruler-top {
  background: #767676;
  width: 100%;
  height: 30px;
}

.cy-box {
  height: calc(100% - 50px);
  width: calc(100% + 30px);
  display: flex;
  margin-left: -30px;
  overflow: hidden;

  .cy-ruler-left {
    background: #767676;
    width: 30px;
    height: 100%;
  }

  .cy-box-main {
    width: 100%;
    height: 100%;
    margin: 10px;
    background: #FFFFFF;
  }
}

.cy-chart-div {
  display: flex;
  flex-direction: column;
  align-items: center;
  cursor: pointer;
  margin-bottom: 15px;

  .svg-icon {
    width: 50px;
    height: 50px;
  }

  span {
    font-size: 12px;
    margin-top: -5px;
  }
}

.label-title {
  display: block !important;

  .el-form-item__content {
    width: calc(100% - 100px);
  }
}

.el-transfer-panel {
 width: 300px !important;
}
</style>
