<!-- @desc:自定义报表  @auth:周兴  @time:2023/3/28 17:12 -->
<template>
  <div class="main-div" ref="mainDiv">
    <!--加载中-->
    <loading :loading="loading" v-if="!modalVisible"></loading>
    <BaseIndexButtonGroup id="BaseIndexButtonGroup">
      <template #left>
        <!--    查询    -->
        <BaseIndexButton right-button="user-select" ref="search" name="search"></BaseIndexButton>
        <!--    清空条件    -->
        <BaseIndexButton ref="clear" name="clear"></BaseIndexButton>
      </template>
    </BaseIndexButtonGroup>

    <!--  查询条件区域  -->
    <div id="search-cond-div" ref="search-cond-div" class="search-cond-class">
      <SearchCond ref="searchCond" v-model="searchCond" :default-form-value="searchCond._value"
                  @collapse-change="collapseChange" :setFlag="false" :customChangeFlag="customChangeFlag"
                  :searchContent="searchContent"
      ></SearchCond>
    </div>

    <!--  tab区域 -->
    <DkTabs v-if="tabsOptions.length > 1" v-model="tabName" :options="tabsOptions"
            @on-click="handleChangeSqlTab"></DkTabs>

    <!-- 表格展示  -->
    <!--    {{form['tableData_' + tabIndex]}}-->
    <div v-if="tabsOptions && tabsOptions[tabIndex] && flgVisible">
      <!--透视表-->
      <DkTable v-if="tabsOptions[tabIndex].flgPivot" slot="top"
               :id="'table-'+$options.name" :ref="'table-select-' + tabIndex" :data="form['tableData_' + tabIndex]"
               :height="tableHeight"
               :choose-flag="false"
               :show-setting-flag="false"
               :pageFlag="false"
               :perspective-flag="false">
        <!--行维度-->
        <div v-for="(item,index) in tabsOptions[tabIndex].pivotData.rowFields" :key="index">
          <DkTableColumn :field="item.key" width="auto" :filter="false" :digits="item.digits"
                         :sum="item.sum"
                         :dataType="item.dataType"
                         :align="item.align"
                         :title="item.label"></DkTableColumn>
        </div>

        <!--        <div v-if="colFlag">-->
        <div v-if="tabsOptions[tabIndex].pivotData.colFields && tabsOptions[tabIndex].pivotData.colFields.length > 0">
          <!--列维度(单维度)-->
          <div
            v-if="tabsOptions[tabIndex].pivotData.colFields.length === 1 && tabsOptions[tabIndex].pivotData.dataFields.length <= 1">
            <DkTableColumn v-for="(item,index) in [...tabsOptions[tabIndex].pivotData.colFields[0].values]"
                           ref="col"
                           :key="index"
                           :field="item+''"
                           :digits="tabsOptions[tabIndex].pivotData.dataFields[0].digits"
                           :sum="tabsOptions[tabIndex].pivotData.dataFields[0].sum"
                           :dataType="tabsOptions[tabIndex].pivotData.dataFields[0].dataType"
                           :align="tabsOptions[tabIndex].pivotData.dataFields[0].align"
                           :type="tabsOptions[tabIndex].pivotData.dataFields[0].type"
                           width="auto" :filter="false"
                           :title="getTitle(item)"
                           @on-link="handleLink"></DkTableColumn>
          </div>
          <!--列维度(多维度)-->
          <div v-else>
            <!--顶层-->
            <vxe-colgroup :title="itemTop+''"
                          v-for="(itemTop,index) in [...tabsOptions[tabIndex].pivotData.colFields[0].values]"
                          :key="index">
              <!--中间层-->
              <div
                v-if="tabsOptions[tabIndex].pivotData.groupCols && tabsOptions[tabIndex].pivotData.groupCols.length > 0">
                <div v-for="(it,gIndex) in tabsOptions[tabIndex].pivotData.groupCols" :key="gIndex">
                  <vxe-colgroup :title="item+''"
                                v-for="(item,index) in [...tabsOptions[tabIndex].pivotData.groupCols[gIndex].values]"
                                :key="index">
                    <div
                      v-if="gIndex === tabsOptions[tabIndex].pivotData.groupCols.length - 1 && tabsOptions[tabIndex].pivotData.dataFields.length <= 1">
                      <!--子级(无值列或者一个值列）-->
                      <DkTableColumn
                        v-for="(cItem,cIndex) in [...tabsOptions[tabIndex].pivotData.colFields[tabsOptions[tabIndex].pivotData.colFields.length - 1].values]"
                        ref="col"
                        :key="cIndex"
                        :field="itemTop + '_' + getField(tabsOptions[tabIndex].pivotData.groupCols,index) + cItem"
                        :digits="cItem.digits"
                        :sum="cItem.sum"
                        :dataType="cItem.dataType"
                        :align="cItem.align"
                        width="auto" :filter="false"
                        :title="getTitle(cItem)"></DkTableColumn>
                    </div>
                    <div
                      v-if="gIndex === tabsOptions[tabIndex].pivotData.groupCols.length - 1 && tabsOptions[tabIndex].pivotData.dataFields.length > 1">
                      <!--子级(有多个值列）-->
                      <DkTableColumn v-for="(cItem,cIndex) in tabsOptions[tabIndex].pivotData.dataFields"
                                     ref="col"
                                     :key="cIndex"
                                     :field="itemTop + '_' + getField(tabsOptions[tabIndex].pivotData.groupCols,index) + cItem.key"
                                     :digits="cItem.digits"
                                     :sum="cItem.sum"
                                     :dataType="cItem.dataType"
                                     :align="cItem.align"
                                     width="auto" :filter="false"
                                     :type="cItem.type"
                                     :title="cItem.label"></DkTableColumn>
                    </div>
                  </vxe-colgroup>
                </div>
              </div>
              <div v-else>
                <div v-if="tabsOptions[tabIndex].pivotData.dataFields.length <= 1">
                  <!--子级(无值列或者一个值列）-->
                  <DkTableColumn
                    v-for="(cItem,cIndex) in [...tabsOptions[tabIndex].pivotData.colFields[tabsOptions[tabIndex].pivotData.colFields.length - 1].values]"
                    ref="col"
                    :key="cIndex"
                    :field="itemTop + '_' + cItem"
                    :digits="cItem.digits"
                    :sum="cItem.sum"
                    :dataType="cItem.dataType"
                    :align="cItem.align"
                    width="auto" :filter="false"
                    :title="getTitle(cItem)"></DkTableColumn>
                </div>
                <div v-else>
                  <!--子级(有多个值列）-->
                  <DkTableColumn v-for="(cItem,cIndex) in tabsOptions[tabIndex].pivotData.dataFields"
                                 ref="col"
                                 :key="cIndex"
                                 :field="itemTop + '_' + cItem.key"
                                 :digits="cItem.digits"
                                 :sum="cItem.sum"
                                 :dataType="cItem.dataType"
                                 :align="cItem.align"
                                 width="auto" :filter="false"
                                 :type="cItem.type"
                                 :title="cItem.label"></DkTableColumn>
                </div>
              </div>
            </vxe-colgroup>
          </div>
        </div>
        <!--列维度(无维度)-->
        <div v-else>
          <DkTableColumn v-for="(cItem,cIndex) in tabsOptions[tabIndex].pivotData.dataFields"
                         ref="col"
                         :key="cIndex"
                         :field="cItem.key"
                         width="auto" :filter="false"
                         :digits="cItem.digits"
                         :sum="cItem.sum"
                         :dataType="cItem.dataType"
                         :align="cItem.align"
                         :type="cItem.type"
                         :title="cItem.label"></DkTableColumn>
        </div>
        <!--        </div>-->

      </DkTable>

      <!--正常列表-->
      <DkTable v-else slot="top" :id="'table-'+$options.name" :ref="'table-select-' + tabIndex"
               :data="form['tableData_' + tabIndex]"
               :height="tabsOptions.length > 1?this.tableHeight - 30:this.tableHeight"
               :show-setting-flag="false"
               :choose-flag="false"
               :pageFlag="tabsOptions[tabIndex].flgPage"
               :page-total-flag="tabsOptions[tabIndex].flgPage"
               :loading="loading"
               sumTotalType="subTotal"
               :sortable="(tabsOptions[tabIndex].sortTable || tabsOptions[tabIndex].sortTable == undefined)?true:false"
               :page-total="pageInfo.total"
               :current-page="pageInfo.currentPage"
               :show-footer="form['showFooter_' + tabIndex]"
               :show-tip="!!tabsOptions[tabIndex].changeTabName"
               :choose-data-flag="!!tabsOptions[tabIndex].changeTabName"
               :seq-tip-content="$t('doubleChange')"
               @pageChange="pageSizeChange"
               @chooseData="chooseData">
        <div v-for="(item, index) in tabsOptions[tabIndex].tableColumns" :key="item.field">
          <DkTableColumn
            :type="item.type"
            :field="item.field"
            :title="item.title"
            :digits="item.digits"
            :sum="item.sum"
            :dataType="item.dataType"
            :align="item.align"
            @on-link="handleLink"
          >
          </DkTableColumn>
        </div>

        <!--        :width="index === tabsOptions[tabIndex].tableColumns.length - 1?'auto': item.width"-->
      </DkTable>
    </div>
  </div>
</template>

<script>
import {indexMixin} from "@/mixins";
import HashTable from "_c/base/dk-perspective/HashTable";

export default {
  name: "custom-report-detail",
  mixins: [indexMixin],
  data() {
    return {
      customChangeFlag: false,
      reportId: '',
      flgVisible: true,
      form: {},
      reportForm: {},
      tableData: [],// 报表数据
      searchContent: [],// 查询条件
      tabName: '',// 当前tab的名称
      tabIndex: 0, // tab的顺序
      tabsOptions: [], // tab数据源
      changeFlag: false,// 是否是跳转
      searchParams: {},// 查询条件
      linkChangeTabs: {},// 点击链接跳转到相应的页签
      computingInterval: null,
      reducer: (sum, item) => sum + 1,
    }
  },
  methods: {
    /**
     * @desc   : 翻页
     * @author : 周兴
     * @date   : 2023/4/20 16:31
     */
    pageSizeChange(pageInfo) {
      // 是点击跳转的翻页
      if (this.changeFlag) {
        let params = {...this.searchParams}
        params.currentPage = pageInfo.currentPage;
        params.pageSize = pageInfo.pageSize;
        this.getData(params)              // 执行查询
      } else {
        this.searchData(pageInfo);
      }
    },
    /**
     * @desc   : 选择数据
     * @author : 周兴
     * @date   : 2023/4/19 18:01
     */
    async chooseData(row, rowIndex, changeTabName) {
      this.flgVisible = false
      if (!changeTabName) {
        changeTabName = this.tabsOptions[this.tabIndex].changeTabName
      }
      if (this.tabsOptions[this.tabIndex] && this.tabsOptions[this.tabIndex].changeScript
        // && this.tabsOptions[this.tabIndex].changeTabName && !row.subTotal) {
        && changeTabName && !row.subTotal) {
        let changeScript = this.tabsOptions[this.tabIndex].changeScript
        // let changeTabName = this.tabsOptions[this.tabIndex].changeTabName
        let tabIndex = await this.tabsOptions.findIndex(it => it.name == changeTabName);
        // 先记录之前列表的分页信息
        this.tabsOptions[this.tabIndex].pageInfo = {...this.pageInfo}
        if (tabIndex || tabIndex === 0) {
          this.tabIndex = tabIndex;
          this.tabName = changeTabName;
        }
        // 切换页签，处理小计
        this.changeTabHandleSubTotal();
        this.flgVisible = true;
        this.$nextTick(() => {
          //查询条件
          this.setCondition(this.searchCond)
          let params = {...this.searchList}
          let table = this.$refs['table-select-' + this.tabIndex]
          params.currentPage = table.pageInfo.currentPage;
          params.pageSize = table.pageInfo.pageSize;
          params = this.setSearchParams(params);
          if (changeScript.indexOf(',') >= 0) {
            let changeScripts = changeScript.split(',');
            changeScripts.forEach(it => {
              params[it] = row[it] ? row[it] : null
            })
          } else {
            params[changeScript] = row[changeScript]
          }
          params.ftyId = this.$store.state.user.ftyId;
          this.getData(params)              // 执行查询
          this.searchParams = {...params}  // 记录当时的查询条件
          this.changeFlag = true;
        })
      }
    },
    /**
     * @desc   : 切换页签，修改合计
     * @author : 周兴
     * @date   : 2023/4/23 15:09
     */
    changeTabHandleSubTotal() {
      this.customChangeFlag = true;
      // 如果有小计，切换过来的页签没有需要移除掉
      let filters = this.searchContent.filter(it => it.itemCode === 'subTotal');
      if (filters && filters.length > 0) {
        if (!this.tabsOptions[this.tabIndex].subTotals) {
          this.searchContent = this.searchContent.filter(it => it.itemCode !== 'subTotal')
          // let subTotalFilters = this.searchContent.filter(it => it.itemCode === 'subTotal')
          // if(subTotalFilters && subTotalFilters.length > 0){
          //   this.$set(subTotalFilters[0],'visible',false)
          // }
        } else {
          // 如果有，需要换内容
          let subTotals = this.tabsOptions[this.tabIndex].subTotals;
          // 设置下拉的数据
          let data = this.setSelectData(true, subTotals, filters[0]);
          filters[0].valueFormat.data = data.data;
        }
      } else {
        // 说明当前页签有小计
        if (this.tabsOptions[this.tabIndex].subTotals) {
          this.loadSubTotals();
        }
      }
    },
    /**
     * @desc   : 切换后记录sqlTab的序号
     * @author : 周兴
     * @date   : 2023/3/30 8:48
     */
    handleChangeSqlTab(val) {
      this.flgVisible = false
      this.$nextTick(() => {
        // 先记录现在的页签的表格翻页信息
        // console.log('this.pageInfo', this.pageInfo, this.tabsOptions[this.tabIndex])
        this.tabsOptions[this.tabIndex].pageInfo = {...this.pageInfo};
        this.tabIndex = this.tabsOptions.findIndex(it => it.name == val)
        if (this.tabsOptions[this.tabIndex].pageInfo) {
          this.pageInfo = {...this.tabsOptions[this.tabIndex].pageInfo};
        }
        // 切换页签，处理小计
        this.changeTabHandleSubTotal();
        setTimeout(() => {
          this.flgVisible = true;
        }, 200)
      })
    },
    /**
     * @desc   : 设置参数
     * @author : 周兴
     * @date   : 2023/3/28 20:06
     */
    setSearchParams(params) {
      params.reportId = this.reportId
      params.sqlId = this.tabsOptions[this.tabIndex].sqlId
      params.flgPage = this.tabsOptions[this.tabIndex].flgPage
      params.flgProc = this.tabsOptions[this.tabIndex].flgProc
      // 处理查询条件
      this.searchContent.forEach(it => {
        // 日期,日时，月份范围的处理
        if (it.valueKind === 'DATE_RANGE' || it.valueKind === 'DATETIME_RANGE' || it.valueKind === 'MONTH_RANGE') {
          if (!this.hasKey(params, it.itemCode + 'Start')) {
            params[it.itemCode + 'Start'] = null;
          }
          if (!this.hasKey(params, it.itemCode + 'End')) {
            params[it.itemCode + 'End'] = null;
          }
        }
        // 如果没有输入查询条件，需要设置为null
        if (!this.hasKey(params, it.itemCode)) {
          params[it.itemCode] = null;
        } else {
          if (params[it.itemCode] == undefined) {
            params[it.itemCode] = null;
          }
          // 如果是下拉需要处理数据(小计列不需要处理）
          if ((it.valueKind === 'M-CHOICE' || it.valueKind === 'M-SEARCH') && it.itemCode != 'subTotal') {
            let values = params[it.itemCode];
            if (values && values.length > 0) {
              for (let i in values) {
                if (typeof values[i] === 'string') {
                  if (values[i].toString().indexOf('\'') < 0) {
                    values[i] = '\'' + values[i] + '\'';
                  }
                  // 判断是否是uuid
                  if (values[i].toString().length === 38) {
                    values[i] = values[i] + ' ::uuid '
                  }
                }
              }
            }
          }
        }
      })
      // 跳转条件的赋值
      if (this.tabsOptions[this.tabIndex].changeScriptOthers &&
        this.tabsOptions[this.tabIndex].changeScriptOthers.length > 0) {
        this.tabsOptions[this.tabIndex].changeScriptOthers.forEach(it => {
          if (it.indexOf(',') >= 0) {
            let changeScripts = it.split(',');
            changeScripts.forEach(t => {
              if (!this.hasKey(params, t)) {
                params[t] = null
              }
            })
          } else {
            if (!this.hasKey(params, it)) {
              params[it] = null
            }
          }
        })
      }
      return params;
    },
    /**
     * @desc   : 处理链接
     * @author : 周兴
     * @date   : 2023/4/28 16:00
     */
    handleLink(row, rowIndex, field) {
      let changeTabName = this.linkChangeTabs[field]
      this.chooseData(row, rowIndex, changeTabName);
    },
    /**
     * @desc   : 设置小计行
     * @author : 周兴
     * @date   : 2023/4/23 9:06
     */
    setSubTotalData(data, params) {
      return new Promise(resolve => {
        // 如果有小计
        if (params.subTotal && this.tabsOptions[this.tabIndex].subTotalDataKeys) {
          let subTotalDataKeys = this.tabsOptions[this.tabIndex].subTotalDataKeys;
          let subTotalDataKeysArr = subTotalDataKeys.split(',');
          // 去掉排序
          this.$set(this.tabsOptions[this.tabIndex], 'sortTable', false)
          let values = []
          let filters = []
          let subTotals = []
          if (params.subTotal && Array.isArray(params.subTotal)) {
            subTotals = params.subTotal
          } else if (params.subTotal) {
            subTotals.push(params.subTotal)
          }
          let dataFilters = [];
          let item = null;

          // 兼容小计列多选  (层级递推）
          subTotals.forEach((sub, tIndex) => {
            if (tIndex === 0) {
              filters = data.map(it => it[sub]).unique();
              if (filters && filters.length > 0) {
                filters.forEach((it, index) => {
                  item = {}
                  item.totalFlag = true;
                  item['sortNo'] = tIndex;
                  item['subTotal'] = (1 + index) + '';
                  item[sub] = it + '【小计】'
                  item[sub + '_'] = it
                  item['data'] = data.filter(t => t[sub] === it);
                  item['count'] = item['data'].length;
                  item['level'] = tIndex;
                  item['parent'] = null;
                  values.push(item)
                })
              }
            } else {
              // 获取上一层级的数据
              dataFilters = values.filter(it => it['sortNo'] === tIndex - 1);
              if (dataFilters && dataFilters.length > 0) {
                dataFilters.forEach(tIt => {
                  filters = tIt.data.map(it => it[sub]).unique();
                  if (filters && filters.length > 0) {
                    filters.forEach((it, index) => {
                      item = {}
                      item.totalFlag = true;
                      item['sortNo'] = tIndex;
                      item['subTotal'] = tIt.subTotal + '-' + (1 + index);
                      // 补上第一级的数据
                      item[subTotals[0]] = tIt[subTotals[0] + '_']
                      item[sub] = it + '【小计】'
                      item['data'] = tIt.data.filter(t => t[sub] === it);
                      item['count'] = item['data'].length;
                      item['level'] = tIndex;
                      item['parent'] = tIt.subTotal;
                      values.push(item)
                    })
                  }
                })
              }
            }
          })
          // 计算小计
          if (values && values.length > 0) {
            values.forEach(it => {
              subTotalDataKeysArr.forEach(t => {
                this.$set(it, t, it.data?.sum(t));
              })
            })
          }
          // data.forEach((it, index) => {
          //   // 兼容小计列多选
          //   subTotals.forEach((sub, tIndex) => {
          //     filters = values.filter(t => t[sub] === it[sub] + '【小计】' && it['subTotal'] === '1-' + (1 + tIndex));
          //     let item = null;
          //     it['subTotal'] = '0';
          //     // 如果没有才加
          //     if (filters && filters.length === 0) {
          //       item = {}
          //       it['sortNo'] = index;
          //       item['sortNo'] = index;
          //       item['subTotal'] = '1-' + (1 + tIndex);
          //       item[sub] = it[sub] + '【小计】'
          //       values.push(item)
          //     } else {
          //       item = filters[0];
          //       it['sortNo'] = item['sortNo']
          //     }
          //     subTotalDataKeysArr.forEach(t => {
          //       // 计算公式
          //       reducer = (sum, itm) => sum + itm[t];
          //       const previousValue = item[t] || 0
          //       // console.log('key', key, previousValue, this.reducer(previousValue, it))
          //       this.$set(item, t, reducer(previousValue, it))
          //     })
          //   })
          // })
          // 把小计插入表格中
          // if (values && values.length > 0) {
          //   values.forEach(it => {
          //     delete it.data
          //     data.push(it);
          //   })
          // }
          // // 把data排序
          // data = data.sort((a, b) => a['sortNo'] - b['sortNo'] || a['subTotal'] - b['subTotal']);
          values = values.sort((a, b) => b['level'] - a['level']);
          // values.forEach(it=>{
          //   filters = values.filter(t=>t.parent === it.level);
          //   this.$set(it,'rowNo',it.count + filters?.length)
          // })
          let count = 0;
          if (values[values.length - 1]) {
            let level = values[values.length - 1].level;
            values.forEach((it, index) => {
              // level改变，count重置
              if (level !== it.level) {
                count = 0;
              }
              count += it.count;
              // 计算子级的个数
              filters = values.filter(t => t.parent === it.subTotal);
              if (filters && filters.length > 0) {
                count += filters.length;
              }
              data.splice(count, 0, it);
              level = it.level;
              count++;
            })
          }
          // console.log('bbb444', data, values)
        } else {
          // 没有小计时增加排序
          this.$set(this.tabsOptions[this.tabIndex], 'sortTable', true)
        }
        resolve(data);
      })
    },
    /**
     * @desc   : 查询数据
     * @author : 周兴
     * @date   : 2023/3/28 20:09
     */
    getData(params) {
      this.changeFlag = false;
      return this.excute(this.$service.customReportService, this.$service.customReportService.selectByReportId, params).then(res => {
        if (res.code === this.$config.SUCCESS_CODE) {
          let data = res.data.list;
          // 设置小计
          this.setSubTotalData(data, params).then(resolve => {
            if (this.tabsOptions[this.tabIndex].flgPivot) {
              // 更新数据
              this.updateValues(resolve, this.tabsOptions[this.tabIndex].pivotData.rowFields,
                this.tabsOptions[this.tabIndex].pivotData.colFields, this.tabsOptions[this.tabIndex].pivotData.dataFields);
            } else {
              // 加载动态列
              if(this.tabsOptions[this.tabIndex].flgDynamicCol){
                this.loadDynamicColumns(data);
              }
              this.form['tableData_' + this.tabIndex] = resolve;
              // console.log('rrr',this.form['tableData_' + this.tabIndex])
              this.$refs['table-select-' + this.tabIndex].reloadData(resolve);
              if (params.currentPage == 1) {
                this.pageInfo.total = res.data.total
                this.pageInfo.currentPage = 1;
              }
            }
            this.loading = false;
          });
          this.loading = false;
        }
      });
    },
    /**
     * @desc   : 加载动态列
     * @author : 周兴
     * @date   : 2023/8/10 10:57
     */
    loadDynamicColumns(data){
      if (data && data.length > 0) {
        let tableColumns = this.tabsOptions[this.tabIndex].tableColumns;
        let checkFields = tableColumns.map(m => m.field);
        let keys = Object.keys(data[0])
        keys = keys.filter(it => !checkFields.includes(it)).map(it => {
          let values = it.split('-')
          return {
            num: parseFloat(values[0]),
            key: values[1],
            name:it
          }
        }).sort((a, b) => a.num - b.num);
        keys.forEach(it=>{
          tableColumns.push({
            align: 'right',
            code: it.name,
            field: it.name,
            name: it.name,
            title: it.key,
            dataType: this.$config.dataType.number,
            flgThousandth: true,
            flgVisible: true
          })
        })
      }
    },
    /**
     * @desc   : 设置下拉的数据源
     * @author : 周兴
     * @date   : 2023/4/23 14:02
     */
    setSelectData(flag, subTotals, item, initFlag = false) {
      let data = []
      let filters = []
      // 多个
      if (subTotals.indexOf(',') >= 0) {
        // 获取列名
        let subTotalsArr = subTotals.split(',');
        subTotalsArr.forEach((it, index) => {
          // 加第一个为默认
          if (index === 0) {
            if (initFlag) {
              item.valueFormat.default = it;
            } else {
              // 非初始化时需要单独调用setDefault方法
              this.$refs['searchCond'].setDefault(item.itemCode, it,item.valueKind)
            }
          }
          if (!this.tabsOptions[this.tabIndex].flgPivot) {
            filters = this.tabsOptions[this.tabIndex].tableColumns.filter(t => t.code === it)
            if (filters && filters.length > 0) {
              flag = true;
              data.push({value: it, name: filters[0].title})
            }
          }
        })
      } else {
        if (!this.tabsOptions[this.tabIndex].flgPivot) {
          filters = this.tabsOptions[this.tabIndex].tableColumns.filter(t => t.code === subTotals)

          if (filters && filters.length > 0) {
            flag = true;
            data.push({value: subTotals, name: filters[0].title})
            // 非初始化才需要
            // if (!initFlag) {
              this.$refs['searchCond'].setDefault(item.itemCode, subTotals,item.valueKind)
            // }
          }
        }
      }
      return {data: data, flag: flag};
    },
    /**
     * @desc   : 加载小计列
     * @author : 周兴
     * @date   : 2023/4/23 8:24
     */
    async loadSubTotals() {
      if (this.tabsOptions && this.tabsOptions[this.tabIndex]
        && this.tabsOptions[this.tabIndex].subTotals) {
        let subTotals = this.tabsOptions[this.tabIndex].subTotals
        let item = {
          itemCode: 'subTotal',
          valueKind: this.$config.docUserInput.mChoice,
          valueFormat: {
            valueKey: 'value',
            labelKey: 'name',
          }
        }
        let flag = false
        // 设置下拉的数据
        let data = await this.setSelectData(flag, subTotals, item, true);
        if (data.flag) {
          item.valueFormat.data = data.data;
          this.searchContent.push(item);
        }
      }
    },
    /**
     * @desc   : 查询明细
     * @author : 周兴
     * @date   : 2023/3/28 17:51
     */
    detail(id) {
      this.excute(this.$service.customReportService,
        this.$service.customReportService.selectByReport, {
          reportId: id,
          ftyId: this.$store.state.user.ftyId
        }, false).then(res => {
        if (res.code === this.$config.SUCCESS_CODE) {
          this.reportForm = res.data;
          // 查询条件
          let conditionList = res.data.conditionList;
          this.handleCondition(conditionList);
          // sql设置
          this.tabsOptions = res.data.sqlList;
          this.tabsOptions.forEach((it, index) => {
            if (it.flgPivot && it.pivotData) {
              it.pivotData.colFields.forEach(item => {
                item.getter = t => t[item.key]
                this.setPivotCol(item, it); // 设置列的属性
              })
              it.pivotData.rowFields.forEach(item => {
                item.getter = t => t[item.key]
                this.setPivotCol(item, it); // 设置列的属性
              })
              it.pivotData.dataFields.forEach(item => {
                item.getter = t => t[item.key]
                this.setPivotCol(item, it); // 设置列的属性
              })
              // 说明多个值列，要展开
              if (it.pivotData.dataFields && it.pivotData.dataFields.length > 1) {
                it.pivotData.groupCols = it.pivotData.colFields.filter((a, b) => b !== 0)
              } else {
                it.pivotData.groupCols = it.pivotData.colFields.filter((a, b) => b !== it.pivotData.colFields.length - 1 && b !== 0)
              }
            } else {
              // 表格设置
              this.handleTableSetting(it, index);

              // region 分组表头 todo
              // if (it.tableSettingList.some(s => s.headers && s.headers.length)){
              //   it.groupCol = []
              //   // console.log(it.tableColumns.map(m => m.headers[0]))
              //   // console.log(it.tableColumns.map(m => m.headers[1]))
              //   // console.log(it.tableColumns.map(m => m.headers[2]))
              //
              //   //一级父级
              //   let level1 = it.tableColumns.map(m => m.headers[0])
              //   let level2 = it.tableColumns.map(m => m.headers[1])
              //   let level3 = it.tableColumns.map(m => m.headers[2])
              //
              //   for (let i = 2; i >= 0 ; i--) {
              //     if (it.tableColumns.map(m => m.headers[i]).some(s => s)) {
              //       this.setColGroup(it, it.tableColumns.map(m => m.headers[i]))
              //
              //       for (let gc of it.groupCol){
              //         if (gc.list) {
              //           // this.setColGroup(it, gc.list)
              //         }
              //       }
              //       break
              //     }
              //   }
              //
              // }
              // console.log(it.groupCol)
              // endregion
            }
          })
          // this.tabsOptions.forEach((it, index) => {
          //   if (!it.flgPivot) {
          //     // 表格设置
          //     this.handleTableSetting(it, index);
          //   }
          // })
        }
      })
    },
    /**
     * todo
     * @desc   : 设置多表头合并
     * @author : 洪旭东
     * @date   : 2023-11-20 11:02
     */
    setColGroup(it, list){
      for (let i = 0; i < list.length; i++) {

        let flag = true
        let j = 1
        while (flag) {
          // console.log(level1[i] , level1[i + j], level1[i] === level1[i + j])
          if (list[i + j] && list[i] === list[i + j]) {
            if (j === 1) {
              it.groupCol.push({
                title: list[i],
                list: []
              })
              it.groupCol[it.groupCol.length - 1].list.push(it.tableColumns[i])
            }
            it.groupCol[it.groupCol.length - 1].list.push(it.tableColumns[i+j])
            j++
          } else {
            flag = false
            i = i + j - 1
            // it.groupCol.push([])
          }
        }
        if (j === 1) {
          it.groupCol.push(it.tableColumns[i])
        }

      }
    },
    /**
     * @desc   : desc
     * @author : 周兴
     * @date   : 2023/6/1 13:13
     */
    setPivotCol(item, it) {
      let filterRows = it.tableSettingList.filter(b => b.code === item.key);
      if (filterRows && filterRows.length > 0) {
        item.align = filterRows[0].align;
        item.dataType = filterRows[0].dataType;
        item.width = filterRows[0].width;
        item.digits = filterRows[0].digits;
        // console.log('bbb',filterRows[0],item.key,item,it)
        if (filterRows[0].flgLink) {
          item.type = 'link'
          item.dataType = 'number'
          this.linkChangeTabs[item.key] = filterRows[0].changeTabName
        }
      }
    },
    /**
     * @desc   : 处理查询条件
     * @author : 周兴
     * @date   : 2023/3/28 19:33
     */
    handleCondition(conditionList) {
      if (conditionList && conditionList.length > 0) {
        this.searchContent = []
        conditionList.forEach(it => {
          let item = {
            itemCode: it.code,
            itemName: it.name,
            required: it.flgRequired,
          }
          // 得到类型
          item.valueKind = this.handleReportKind(it.kind);
          item.valueFormat = {}
          // 赋值默认值
          if (it.defaultValue && it.defaultValue.default) {
            item.valueFormat.default = it.defaultValue.default;
          }
          // 如果下拉
          if (it.kind === this.$config.reportKind.single ||
            it.kind === this.$config.reportKind.multiple) {
            item.treeFlag = it.flgTree
            item.treeStrict = it.flgTreeStrict
            item.valueFormat.valueKey = 'value';
            item.valueFormat.labelKey = 'name';
            // 获取下拉数据源
            this.getSelectData(it.conditionId, item, it.defaultValue?.default);
          } else if (it.kind === this.$config.reportKind.dateRange) {
            // 日期范围
            if (it.defaultValue && it.defaultValue.rangeSel) {
              item.valueFormat.default = this.handleDateDefault(it.defaultValue)
            }
          } else if (it.kind === this.$config.reportKind.dateTimeRange) {
            // 日时范围
            if (it.defaultValue && it.defaultValue.rangeSel) {
              item.valueFormat.default = this.handleDateTimeDefault(it.defaultValue)
            }
          } else if (it.kind === this.$config.reportKind.month) {
            // 月份
            if (it.defaultValue && it.defaultValue.rangeSel) {
              item.valueFormat.default = this.handleMonthDefault(it.defaultValue)
            }
          } else if (it.kind === this.$config.reportKind.monthRange) {
            // 月份范围
            if (it.defaultValue && it.defaultValue.rangeSel) {
              item.valueFormat.default = this.handleMonthRangeDefault(it.defaultValue)
            }
          } else if (it.kind === this.$config.reportKind.mSearch ||
            it.kind === this.$config.reportKind.sSearch) {
            // 类型
            if (it.remarks) {
              item.magnifierType = it.remarks;
            }
            // 其他条件
            if (it.otherCondition) {
              this.$set(item, 'otherCondition', it.otherCondition)
            }
          }
          this.searchContent.push(item);
        })
        // 增加小计
        this.$nextTick(() => {
          this.loadSubTotals();
        })
      }
    },
    /**
     * @desc   : 处理日期范围的默认值
     * @author : 周兴
     * @date   : 2023/5/17 8:39
     */
    handleDateDefault(defaultValue) {
      let value = []
      let now = new Date();
      switch (defaultValue.rangeSel) {
        // 今天
        case this.$config.rangeSel.today.value:
          value = [now.toDateStr(), now.toDateStr()];
          break;
        // 昨天
        case this.$config.rangeSel.yesterday.value:
          let yesterday = now.addDays(-1).toDateStr();
          value = [yesterday, yesterday];
          break;
        // 本周
        case this.$config.rangeSel.thisWeek.value:
          value = [now.getWeekFirstDay(), now.getWeekLastDay()];
          break;
        // 近一周
        case this.$config.rangeSel.nearlyWeek.value:
          value = [now.addDays(-6).toDateStr(), now.toDateStr()];
          break;
        // 上一周
        case this.$config.rangeSel.beforeWeek.value:
          let beforeDay = now.addDays(-7);
          value = [beforeDay.getWeekFirstDay(), beforeDay.getWeekLastDay()];
          break;
        // 本月
        case this.$config.rangeSel.thisMonth.value:
          value = [now.getFirstDateStr(), now.getLastDateStr()];
          break;
        // 近一月
        case this.$config.rangeSel.nearlyMonth.value:
          value = [now.addMonths(-1).toDateStr(), now.toDateStr()];
          break;
        // 上一月
        case this.$config.rangeSel.beforeMonth.value:
          let beforeMonth = now.addMonths(-1);
          value = [beforeMonth.getFirstDateStr(), beforeMonth.getLastDateStr()];
          break;
        // 自定义
        case this.$config.rangeSel.custom.value:
          let beforeDayCustom = now;
          // 间隔月份
          if (defaultValue.intervalMonth) {
            beforeDayCustom = beforeDayCustom.addMonths(-1 * defaultValue.intervalMonth)
          }
          // 间隔天数
          if (defaultValue.intervalDay) {
            beforeDayCustom = beforeDayCustom.addDays(-1 * defaultValue.intervalDay)
          }
          value = [beforeDayCustom.toDateStr(), now.toDateStr()];
          break;
      }
      return value;
      // if(defaultValue.rangeSel == this.$config.rangeSel.today.value){
      //
      // }
    },
    /**
     * @desc   : 处理日时范围的默认值
     * @author : 周兴
     * @date   : 2023/5/17 8:39
     */
    handleDateTimeDefault(defaultValue) {
      let value = []
      let now = new Date();
      let nowStr = now.toDateStr();
      switch (defaultValue.rangeSel) {
        // 今天
        case this.$config.rangeSel.today.value:
          value = [new Date(nowStr + ' 00:00:00').toDateTimeStr(), new Date(nowStr + ' 23:59:59').toDateTimeStr()];
          break;
        // 昨天
        case this.$config.rangeSel.yesterday.value:
          let yesterday = now.addDays(-1).toDateStr();
          value = [new Date(yesterday + ' 00:00:00').toDateTimeStr(), new Date(yesterday + ' 23:59:59').toDateTimeStr()];
          break;
        // 本周
        case this.$config.rangeSel.thisWeek.value:
          value = [new Date(now.getWeekFirstDay() + ' 00:00:00').toDateTimeStr(), new Date(now.getWeekLastDay() + ' 23:59:59').toDateTimeStr()];
          break;
        // 近一周
        case this.$config.rangeSel.nearlyWeek.value:
          value = [new Date(now.addDays(-6).toDateStr() + ' 00:00:00').toDateTimeStr(), new Date(nowStr + ' 23:59:59').toDateTimeStr()];
          break;
        // 上一周
        case this.$config.rangeSel.beforeWeek.value:
          let beforeDay = now.addDays(-7);
          value = [new Date(beforeDay.getWeekFirstDay() + ' 00:00:00').toDateTimeStr(), new Date(beforeDay.getWeekLastDay() + ' 23:59:59').toDateTimeStr()];
          break;
        // 本月
        case this.$config.rangeSel.thisMonth.value:
          value = [new Date(now.getFirstDateStr() + ' 00:00:00').toDateTimeStr(), new Date(now.getLastDateStr() + ' 23:59:59').toDateTimeStr()];
          break;
        // 近一月
        case this.$config.rangeSel.nearlyMonth.value:
          value = [new Date(now.addMonths(-1).toDateStr() + ' 00:00:00').toDateTimeStr(), new Date(nowStr + ' 23:59:59').toDateTimeStr()];
          break;
        // 上一月
        case this.$config.rangeSel.beforeMonth.value:
          let beforeMonth = now.addMonths(-1);
          value = [new Date(beforeMonth.getFirstDateStr() + ' 00:00:00').toDateTimeStr(), new Date(beforeMonth.getLastDateStr() + ' 23:59:59').toDateTimeStr()];
          break;
        // 自定义
        case this.$config.rangeSel.custom.value:
          let beforeDayCustom = now;
          // 间隔月份
          if (defaultValue.intervalMonth) {
            beforeDayCustom = beforeDayCustom.addMonths(-1 * defaultValue.intervalMonth)
          }
          // 间隔天数
          if (defaultValue.intervalDay) {
            beforeDayCustom = beforeDayCustom.addDays(-1 * defaultValue.intervalDay)
          }
          value = [new Date(beforeDayCustom.toDateStr() + ' 00:00:00').toDateTimeStr(), new Date(nowStr + ' 23:59:59').toDateTimeStr()];
          break;
      }
      // console.log('value',value,new Date(now.toDateStr() + ' 23:59:59').toDateTimeStr())
      return value;
      // if(defaultValue.rangeSel == this.$config.rangeSel.today.value){
      //
      // }
    },
    /**
     * @desc   : 处理月份的默认值
     * @author : 周兴
     * @date   : 2023/5/25 8:39
     */
    handleMonthDefault(defaultValue) {
      let value = null;
      let now = new Date();
      switch (defaultValue.rangeSel) {
        // 本月
        case this.$config.rangeSel.thisMonth.value:
          value = now.getFirstDateStr();
          break;
        // 近一月
        case this.$config.rangeSel.nearlyMonth.value:
          value = now.addMonths(-1);
          break;
        // 上一月
        case this.$config.rangeSel.beforeMonth.value:
          let beforeMonth = now.addMonths(-1);
          value = beforeMonth.getFirstDateStr();
          break;
        // 自定义
        case this.$config.rangeSel.custom.value:
          let beforeDayCustom = now;
          // 间隔月份
          if (defaultValue.intervalMonth) {
            beforeDayCustom = beforeDayCustom.addMonths(-1 * defaultValue.intervalMonth)
          }
          value = beforeDayCustom;
          break;
      }
      if (value) {
        value = new Date(value).toYearMonth2();
      }
      return value;
    },
    /**
     * @desc   : 处理月份范围的默认值
     * @author : 周兴
     * @date   : 2023/5/25 8:39
     */
    handleMonthRangeDefault(defaultValue) {
      let value = null;
      let values = [];
      let now = new Date();
      switch (defaultValue.rangeSel) {
        // 本月
        case this.$config.rangeSel.thisMonth.value:
          value = now.toYearMonth2();
          values = [value, value];
          break;
        // 近一月
        case this.$config.rangeSel.nearlyMonth.value:
          now = now.addMonths(-1);
          value = now.toYearMonth2();
          values = [value, now.toYearMonth2()];
          break;
        // 上一月
        case this.$config.rangeSel.beforeMonth.value:
          let beforeMonth = now.addMonths(-1);
          value = beforeMonth.toYearMonth2();
          values = [value, value];
          break;
        // 自定义
        case this.$config.rangeSel.custom.value:
          let beforeDayCustom = now;
          // 间隔月份
          if (defaultValue.intervalMonth) {
            beforeDayCustom = beforeDayCustom.addMonths(-1 * defaultValue.intervalMonth)
          }
          value = beforeDayCustom;
          values = [value.toYearMonth2(), now.toYearMonth2()]
          break;
      }
      return values;
    },
    /**
     * @desc   : 处理报表的类型
     * @author : 周兴
     * @date   : 2023/4/20 8:53
     */
    handleReportKind(kind) {
      let valueKind = ''
      if (kind === this.$config.reportKind.single) {
        valueKind = this.$config.docUserInput.sChoice
      } else if (kind === this.$config.reportKind.multiple) {
        valueKind = this.$config.docUserInput.mChoice
      } else if (kind === this.$config.reportKind.date) {
        valueKind = this.$config.docUserInput.date
      } else if (kind === this.$config.reportKind.dateRange) {
        valueKind = this.$config.docUserInput.dateRange
      } else if (kind === this.$config.reportKind.dateTimeRange) {
        valueKind = this.$config.docUserInput.dateTimeRange
      } else if (kind === this.$config.reportKind.month) {
        valueKind = this.$config.docUserInput.month
      } else if (kind === this.$config.reportKind.monthRange) {
        valueKind = this.$config.docUserInput.monthRange
      } else if (kind === this.$config.reportKind.mSearch) {
        valueKind = this.$config.docUserInput.mSearch
      } else if (kind === this.$config.reportKind.sSearch) {
        valueKind = this.$config.docUserInput.sSearch
      }
      return valueKind;
    },
    /**
     * @desc   : 获取下拉的数据源
     * @author : 周兴
     * @date   : 2023/3/29 10:09
     */
    getSelectData(conditionId, item, defaultValue) {
      let params = {
        conditionId: conditionId,
        ftyId: this.$store.state.user.ftyId
      }
      this.excute(this.$service.customReportService, this.$service.customReportService.getSelectDataById, params).then(res => {
        if (res.code === this.$config.SUCCESS_CODE) {
          let defaultV = null;
          if (item.valueKind === 'M-CHOICE') {
            defaultV = defaultValue ? [defaultValue] : null
          } else {
            defaultV = defaultValue;
          }
          // 给下拉数据源赋值
          this.$refs['searchCond'].changeOptions(item.itemCode, res.data, defaultV)
        }
      })
    },
    /**
     * @desc   : 设置表格设置信息
     * @author : 周兴
     * @date   : 2023/3/28 19:55
     */
    handleTableSetting(row, index) {
      let table = row.tableSettingList?.copy();
      row.tableColumns = []
      this.showFooter = false;
      if (table && table.length > 0) {
        table.forEach(it => {
          if (it.flgVisible) {
            let item = {...it}
            item.field = it.code
            item.title = it.name
            item.sum = it.flgSum
            if (it.dataType === 'switch') {
              item.type = it.dataType;
            } else {
              item.type = 'text';
            }
            // 是否是链接
            if (it.flgLink) {
              item.type = 'link'
              this.linkChangeTabs[it.code] = it.changeTabName
            }
            item.dataType = it.dataType ? it.dataType : this.$config.dataType.str
            if (it.flgSum) {
              this.form['showFooter_' + index] = it.flgSum
            }
            row.tableColumns.push(item);
          }
        })
      }
    },
    /**
     * @desc   : 获取标题
     * @author : 周兴
     * @date   : 2023/3/21 13:34
     */
    getField(groupCols, index) {
      let titles = []
      if (groupCols && groupCols.length > 0) {
        groupCols.forEach(it => {
          // if (it.valuesFiltered && Array.isArray(it.valuesFiltered)) {
          //   let values = [...it.valuesFiltered]
          //   if (values[index]) {
          //     titles.push(values[index]);
          //   }
          // }
          if (it.values && it.values.length > 0) {
            if (it.values[index]) {
              titles.push(it.values[index]);
            }
          }
        })
        return titles.join('_') + '_';
      }
      return '';
    },
    /**
     * @desc   : 要处理boolean的显示
     * @author : 周兴
     * @date   : 2023/4/6 15:36
     */
    getTitle(value) {
      if (typeof value === 'boolean') {
        return value ? this.$t('yes') : this.$t('no')
      } else {
        return value + '';
      }
    },
    /**
     * @desc   : 更新数据
     * @author : 周兴
     * @date   : 2023/5/19 13:20
     */
    updateValues(data, rowFields, colFields, dataFields) {
      // Start a task to avoid blocking the page
      clearInterval(this.computingInterval)
      this.computingInterval = setTimeout(() => {
        // this.tableData = this.data.filterColumns(this.rowKeys).unique();
        this.tableData = []
        const valuesHashTable = new HashTable()
        // const fields = [...rowFields, ...colFields]
        let rowKeys = []
        // rowFields.forEach(k => {
        //   rowKeys.push(k.key);
        // })
        const dataKey = []
        data.forEach(it => {
          const rowKey = []
          const colKey = []
          let filtered = false
          // Check if item passes fields value filters
          // for (let field of fields) {
          //   if (field.valuesFiltered && !field.valuesFiltered.has(field.getter(it))) {
          //     filtered = true
          //     break
          //   }
          // }
          // Build item rowKey/colKey if necessary
          if (!filtered) {
            let rowColumns = {}
            rowFields.forEach(field => {
              if (field.getter(it)) {
                rowKey.push(field.getter(it) + '')
                rowColumns[field.key] = field.getter(it) + ''
              }
            })
            if (rowColumns && Object.keys(rowColumns).length > 0) {
              this.tableData.pushNoRepeat(rowColumns)
            }
            colFields.forEach(field => {
              colKey.push(field.getter(it) + '')
            })
            if (dataFields && dataFields.length > 1) {
              dataFields.forEach(field => {
                dataKey.push(field.key)
              })
            }
          }
          // Update valuesHashTable
          // if (updateValuesHashTable) {
          if (dataKey && dataKey.length > 0) {
            let reducer = null
            dataKey.forEach(item => {
              // 计算公式
              this.reducer = (sum, itm) => sum + itm[item];
              const key = [...rowKey, ...colKey, item]
              const previousValue = valuesHashTable.get(key) || 0
              // console.log('key', key, previousValue, this.reducer(previousValue, it))
              valuesHashTable.set(key, this.reducer(previousValue, it))
            })
          } else {
            // 说明值域小于等于1个
            if (dataFields && dataFields.length > 0) {
              let reducer = null
              let item = dataFields[0].key
              // 计算公式
              this.reducer = (sum, itm) => sum + itm[item];
              const key = [...rowKey, ...colKey]
              const previousValue = valuesHashTable.get(key) || 0
              // console.log('key', key, previousValue, this.reducer(previousValue, it))
              valuesHashTable.set(key, this.reducer(previousValue, it))
            }
          }
          // }
        })

        this.$nextTick(() => {
          // 是否包括值域
          let hasData = dataFields.length > 0 ? true : false;
          // 把数据装入table
          if (this.tableData && this.$refs.col && this.$refs.col.length > 0) {
            this.tableData.forEach(item => {
              let rowKeys = []
              rowFields.forEach(k => {
                rowKeys.push(item[k.key]);
              })
              // 循环列
              this.$refs.col.forEach(col => {
                let headerFields = col.field.split('_')
                // 如果只有一个值域，是不要显示
                if (dataFields.length == 1) {
                  let index = headerFields.findIndex(it => it == dataFields[0].key)
                  // 删除掉
                  if (index >= 0) {
                    headerFields.splice(index, 1)
                  }
                }
                let key = [...rowKeys, ...headerFields]
                if (hasData) {
                  let digits = col.digits;
                  let value = valuesHashTable.get(key);
                  // console.log('tt', value, key, valuesHashTable, rowKeys, headerFields, this.groupCols)
                  item[col.field] = value ? value.toThousandth(digits) : null;
                  // console.log('col.field', this.dataFields, headerFields, valuesHashTable, key,col)
                } else {
                  item[col.field] = null;
                }
              })
              // console.log('tableData',this.tableData)
            })
            this.form['tableData_' + this.tabIndex] = this.tableData;
            this.$refs['table-select-' + this.tabIndex].reloadData(this.tableData);
          }
        })
      }, 300)
    },
    /**
     * @desc   : 同一路由加载数据
     * @author : 周兴
     * @date   : 2023/3/31 16:02
     */
    createdInit() {
      this.initSearchFlag = false; // 默认不查询
      this.routeObjName = 'customReport' // 路由
      this.reportId = this.$route.meta.exMenuUuid;
      // 如果为空，就可能是预览，读取预览的方式的id
      if (!this.reportId) {
        if (this.$route.params && this.$route.params.id) {
          this.reportId = this.$route.params.id;
        }
      }
    },
  },
  mounted() {
    this.$nextTick(() => {
      if (this.reportId) {
        // 导出额外的条件
        this.exportCondition = {reportId: this.reportId}
        if (this.tabIndex == 0) {
          this.detail(this.reportId)   // 查询该报表的信息
        }
      }
    })
  }
}
</script>

<style scoped>
/deep/ .ivu-row {
  flex-flow: wrap !important;
  display: flex !important;
}
</style>
