<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:100%;width:100%;left: 0px;top: 0px;bottom:0px;">
            </div>
          </div>
        </div>
      </div>
      <div class="cy-div2">
        <div class="cy-chart-div" @click="newReportTemplate" v-if="templateId">
          <svg-icon icon-class="report_new" 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="clearReportTemplate">
          <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="primary" size="mini" @click="insertBarChartForm">保存</el-button>
        <el-button size="mini" @click="cancelBarChartForm">取消</el-button>
      </el-form>
    </el-drawer>

    <!-- 数据项列表信息 -->
    <el-dialog
        title="数据表配置"
        width="80%"
        top="10vh"
        center
        :before-close="dialogClose"
        :visible.sync="dialogDataVisible"
        :close-on-click-modal="false"
        :append-to-body="true">
      <div style="text-align: center">
        <el-transfer v-model="transferValue"
                     style="text-align: left; display: inline-block"
                     :titles="['数据字段列表', '已选择数据字段']"
                     target-order="push"
                     :data="transferData"></el-transfer>
        <el-divider content-position="left">请选择数据组</el-divider>
        <div class="cy-line" style="height: 100px;">
          <div>
            <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;margin-top: 4px;">选择数据项</el-button>
          </div>
          <el-tag size="mini" v-if="chooseItemData.length > 0"
                  style="margin-top: 10px;"
                  class="cy-item-tag">已选择({{ chooseItemData.length }})项</el-tag>
        </div>
        <el-button type="primary" @click="transferEvent" style="margin-top: 20px;">确定</el-button>
      </div>
    </el-dialog>

    <!-- 数据组选择 -->
    <el-dialog
        title="选择数据项"
        width="80%"
        top="10vh"
        center
        :before-close="dialogClose"
        :visible.sync="dialogDataItemVisible"
        :close-on-click-modal="false"
        :append-to-body="true">
      <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">
              <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
        :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="primary" @click="baseItemEvent">确定</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="500px"
        center
        :before-close="dialogClose"
        :visible.sync="dialogCommReportVisible"
        :close-on-click-modal="false"
        :append-to-body="true">
      <div style="height: 220px; overflow: auto;">
        <div v-for="item in commTemplateList"
             style="float: left;width: 50%;display: flex;flex-direction: column;align-items: center;margin-top: 10px;">
          <el-image :src="require('@/assets/images/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 style="text-align: center; margin-top: 40px;">
        <el-button type="primary" @click="commReportEvent">确定</el-button>
        <el-button @click="dialogClose">取消</el-button>
      </div>
    </el-dialog>

    <!-- 选择数据组数据 -->
    <el-dialog
        title="选择数据项"
        width="80%"
        top="10vh"
        center
        :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: 50vh; margin-top: 10px; overflow: auto;">
          <el-tree class="cy-item-tree"
                   ref="itemTree"
                   :data="chooseGroupItemList"
                   :indent="10"
                   node-key="id"
                   show-checkbox
                   :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>
      <div style="width: 100%;text-align: center;">
        <el-button type="primary" style="margin-top: 20px;" @click="itemEvent">确定</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 { insertEChart } from 'luckytool'
import {
  getAllDataModel,
  getAllItemGroup, getAllTableTemplate, getItemGroupById,
  getTableItemGroupById,
  getTableTemplateById,
  saveReportTemplate,
  updateReportTemplate
} from "@/api/datasource";
import {showLoading} from "@/utils/cqcy";
import {getDictByKey} from "@/api/basic";

export default {
  name: 'index',
  components: {
    RulerView
  },
  data() {
    return {
      showReportData: true,
      dialogBarChartVisible: false,
      dialogDataVisible: false,
      dialogDataItemVisible: false,
      dialogDataModelVisible: false,
      dialogCommReportVisible: false,
      dialogGroupItemVisible: false,
      dialogBaseDataVisible: 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: {
      },
      baseDataList: [],
      chooseBaseData: null,
      dataGroupList: [],
      itemDataListByTree: [],
      itemDataListByCalc: [],
      chooseGroupItemList: [],
      dataModelList: [],
      chooseDataModel: null,
      chooseDataItemIndex: null,
      bomCheckKey: 0,
      chooseDataGroup: null,
      chooseItemData: [],
      filterItemData: '',
      transferSingleData: [
        { key: 'groupName', label: 'groupName（组名称）', sort: 1 },
        { key: 'groupDescribe', label: 'groupDescribe（组描述）', sort: 11 },
        { key: 'dataSourceName', label: 'dataSourceName（数据源名称）', sort: 21 }
      ],
      transferData: [
          { key: 'itemName', label: 'itemName（数据项名称）', sort: 31 },
          { key: 'describe', label: 'describe（数据标签/描述）', sort: 41 },
          { key: 'dataType', label: 'dataType（数据类型）', sort: 51 },
          { key: 'dataValue', label: 'dataValue（数据值）', sort: 61 },
          { key: 'calcDataValue', label: 'calcDataValue（数据计算值）', sort: 71 }
      ],
      transferValue: [],
      commTemplate: null,
      commTemplateList: [],
      templateName: '',
      templateId: '',
      reportTemplateItem: '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: 50, // 是否显示底部 sheet 页按钮
        data: [{
          "name": "统计报表", //工作表名称
        }],
        cellRightClickConfig: { // 自定义配置单元格右击菜单
          copy: false, // 复制
          copyAs: false, // 复制为
          paste: false, // 粘贴
          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.id': {
      handler(now, old) {
        this.getTableTemplate(now)
      }
    },
    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
        if (tempId) {
          _this.getTableTemplate(tempId)
          return
        }
        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
          luckysheet.create(option)
          for (let i in _this.toolChart) {
            _this.insertEChartTool(_this.toolChart[i].info, false)
          }
        } else {
          luckysheet.create(_this.luckysheetOption)
        }
        _this.autoSaveReportInfo()
      }
    })
  },
  created() {
    this.transferData = this.transferData.concat(this.transferSingleData)
    let compare = (obj1, obj2) => {
      if (obj1.sort > obj2.sort) return 1
      else if (obj1.sort < obj2.sort) return -1
      else return 0
    }
    this.transferData.sort(compare)
  },
  destroyed() {
    luckysheet.destroy()
    if (this.reportInterval) {
      clearInterval(this.reportInterval)
    }
  },
  methods: {
    /** 保存模版信息 */
    saveReportTemplate() {
      this.$prompt('请输入/确认报表模版名称', '保存', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputValue: this.templateName,
        inputValidator: (val) => {
          if (!val) {
            return '模版名称不能为空'
          }
          if (val.length > 20) {
            return '模版名称必须在20字以内'
          }
        }
      }).then(({ value }) => {
        const loading = showLoading(this, '保存中，请稍候···')
        let result = {
          'charts': this.toolChart,
          'tables': this.toolTable,
          'option': this.luckysheetOption,
          'data': JSON.parse(this.getLuckysheetConfig())
        }
        let data = {
          'templateName': value,
          'templateData': JSON.stringify(result)
        }
        if (this.templateId) {
          data.id = this.templateId
          updateReportTemplate(data).then(res => {
            loading.close()
            let msg = res.data ? '修改成功！' : '修改失败！'
            let msgType = res.data ? 'success' : 'error'
            this.$message({
              message: msg,
              type: msgType
            })
            this.clearReportTemplate()
            this.$emit('refreshReportTemplateData', true)
          }).catch((e) => {
            loading.close()
          })
        } else {
          saveReportTemplate(data).then(res => {
            loading.close()
            let msg = res.data ? '保存成功！' : '保存失败！'
            let msgType = res.data ? 'success' : 'error'
            this.$message({
              message: msg,
              type: msgType
            })
            this.clearReportTemplate()
            this.$emit('refreshReportTemplateData', true)
          }).catch((e) => {
            loading.close()
          })
        }
      }).catch(() => {
      })
    },
    /** 新建报表内容 */
    newReportTemplate() {
      this.templateId = null
      this.templateName = ''
      this.clearReportTemplate()
    },
    /** 取消报表内容 */
    clearReportTemplate() {
      localStorage.removeItem(this.reportTemplateItem)
      this.toolChart = []
      luckysheet.destroy()
      luckysheet.create(this.luckysheetOption)
    },
    /** 保存数据格式转换 */
    getLuckysheetConfig() {
      let ls = luckysheet.getLuckysheetfile()
      ls.forEach((item, index) => {
        if(item.chart) {
          item.chart.forEach((chart, i) => {
            ls[index].chart[i] = {
              ...ls[index].chart[i],
              chartOptions: {...chartmix.default.getChartJson(chart.chart_id)}
            }
            let div = document.getElementById(chart.chart_id + '_c');
            if(div.style) {
              ls[index].chart[i].left = parseInt(div.style.left)
              ls[index].chart[i].top = parseInt(div.style.top)
              ls[index].chart[i].width = parseInt(div.style.width)
              ls[index].chart[i].height = parseInt(div.style.height)
            }
          })
        }
      })
      return JSON.stringify(ls)
    },
    /** 生成唯一 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
      setTimeout(() => {
        const sheet = luckysheet.getLuckysheetfile()[0]
        let optionData = sheet.data
        try {
          insertEChart({
            selector: '#luckysheet',
            info,
            sheet,
            optionData,
            echarts,
            luckysheet,
            $
          })
        } 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
          }
        })
      }, 200)
    },
    /** 获取右侧数据组列表 */
    getDataGroupList() {
      getAllItemGroup().then(res => {
        this.dataGroupList = res.data
      }).catch((e) => {
        this.$message({
          message: '数据组查询失败！',
          type: 'error'
        })
      })
    },
    /** 选择数据源值改变事件 */
    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
      }
      const loading = showLoading(this, '加载中，请稍候···')
      getTableItemGroupById(id).then(res => {
        loading.close()
        this.itemDataListByTree = res.data.itemList
        if (this.chooseItemData.length > 0) {
          let idList = []
          for (let i in this.chooseItemData) {
            idList.push(this.chooseItemData[i].id)
          }
          this.$refs.itemTree.setCheckedKeys(idList)
        }
        this.dialogDataItemVisible = true
      }).catch((e) => {
        console.error(e)
        loading.close()
        this.$message({
          message: '连接失败！',
          type: 'error'
        })
      })
    },
    /** 选择的数据项：第一步 */
    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.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()
      })
    },
    /** 选择数据模型 */
    handleChoose(index, row) {
      this.chooseDataItemIndex = index
      this.chooseDataModel = null
      this.dialogDataModelVisible = true
    },
    /** 保存数据模型事件 */
    saveDataModelEvent() {
      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() {
      let params = {
        'page': 1,
        'limit': 1000,
        'userId': 'comm'
      }
      getAllTableTemplate(params).then(res => {
        if (!res.data) {
          return
        }
        this.dialogCommReportVisible = true
        this.commTemplateList = res.data.tableTemplateList
      }).catch((e) => {
      })
    },
    /** 选择模板报表 */
    commReportEvent() {
      if (!this.commTemplate) {
        this.$message({
          message: '请选择模板！',
          type: 'warning'
        })
        return
      }
      let locItem = this.commTemplate.templateData
      luckysheet.destroy()
      let option = JSON.parse(JSON.stringify(this.luckysheetOption))
      option.data = JSON.parse(locItem).data
      this.toolChart = JSON.parse(locItem).charts
      luckysheet.create(option)
      this.dialogClose()
    },
    /** 数据项 */
    dataEvent(type) {
      let rangeWithFlatten = luckysheet.getRangeWithFlatten()
      if (!rangeWithFlatten || rangeWithFlatten.length != 1) {
        this.$message({
          message: '请在 Excel 中选择图表需要存放的位置！',
          type: 'warning'
        })
        return
      }
      // 基础数据项
      if (type == 1) {
        this.getBaseDataItem()
        return
      }
      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) => {
        console.error(e)
      })
    },
    /** 基础数据项插入 */
    baseItemEvent() {
      console.log(this.chooseBaseData)
      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)
      this.dialogBaseDataClose()
    },
    /** 动态数据项插入 */
    itemEvent() {
      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 i in this.chooseGroupItemList) {
        let groupId = this.chooseGroupItemList[i].itemGroupId
        let name = this.chooseGroupItemList[i].itemName
        name = name.substring(name.lastIndexOf('.') + 1)
        let v = '${' + groupId + '.' + name + '}'
        let p_c = parseInt(c) + parseInt(i)
        fieldList.push({
          'name': v,
          'r': r,
          'c': p_c
        })
        luckysheet.setCellValue(r, p_c, v)
      }
      let tableTem = {
        'item': this.chooseGroupItemList,
        'field': fieldList
      }
      this.toolTable.push(tableTem)
      this.chooseGroupItemList = []
      this.chooseDataGroup = null
      this.chooseItemData = []
      this.dialogGroupItemVisible = false
    },
    /** 数据字段添加 */
    transferEvent() {
      if (this.transferValue.length == 0) {
        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
      }
      let rangeWithFlatten = luckysheet.getRangeWithFlatten()
      let c = rangeWithFlatten[0].c
      let r = rangeWithFlatten[0].r
      let fieldList = []
      for (let i in this.transferValue) {
        let v = '#{' + this.transferValue[i] + '}'
        let p_c = parseInt(c) + parseInt(i)
        fieldList.push({
          'name': v,
          'r': r,
          'c': p_c
        })
        luckysheet.setCellValue(r, p_c, v)
      }
      let tableTem = {
        'item': this.chooseItemData,
        'field': fieldList
      }
      this.toolTable.push(tableTem)
      this.transferValue = []
      this.chooseDataGroup = null
      this.chooseItemData = []
      this.dialogDataVisible = false
    },
    /** 柱状图 */
    barEvent(type) {
      let _this = this
      // 当前选择范围
      let rangeWithFlatten = luckysheet.getRangeWithFlatten()
      if (!rangeWithFlatten || rangeWithFlatten.length <= 1) {
        _this.$message({
          message: '请在 Excel 中选择图表需要存放的位置范围！',
          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() {
      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.$refs.barChartForm.resetFields()
      this.chooseDataGroup = null
      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() {
      $('.' + 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
      let time = setInterval(() => {
        if (!this.templateId) {
          let result = {
            'charts': _this.toolChart,
            'tables': _this.toolTable,
            'data': JSON.parse(_this.getLuckysheetConfig())
          }
          localStorage.setItem(_this.reportTemplateItem, JSON.stringify(result))
          console.log(new Date().getTime(), 'auto save report template success.')
        }
      }, 30 * 1000)
      this.reportInterval = time
    },
    /** 获取模板报表信息 */
    getTableTemplate(id) {
      if (!id) {
        this.$message({
          message: '获取模板失败！',
          type: 'error'
        })
        return
      }
      getTableTemplateById(id).then(res => {
        if (!res.data) {
          return
        }
        luckysheet.destroy()
        this.templateName = res.data.templateName
        this.templateId = res.data.id
        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
        luckysheet.create(option)
        for (let i in this.toolChart) {
          this.insertEChartTool(this.toolChart[i].info, false)
        }
      }).catch((e) => {
      })
    },
    /** 弹出层关闭事件 */
    dialogClose(done) {
      this.commTemplate = null
      if (typeof(done) === 'function') {
        done()
      } else {
        this.dialogBarChartVisible = false
        this.dialogDataVisible = false
        this.dialogDataItemVisible = false
        this.dialogDataModelVisible = false
        this.dialogCommReportVisible = false
        this.dialogGroupItemVisible = 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%;
  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: auto;

  .cy-ruler-left {
    background: #767676;
    width: 30px;
    height: calc(297mm + 20px);
  }

  .cy-box-main {
    width: 100%;
    height: 297mm;
    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>
