<template>
  <x-page-container class="common-page-container meta-edit toolbar-page-container">
    <template v-slot:header>
      <x-button-group :button-config="buttonConfig">
        <template v-for="(item) in buttonSlotArray" v-slot:[item.name]="scope">
          <slot :name="item.name" v-bind="scope"></slot>
        </template>
      </x-button-group>
      <vxe-toolbar ref="vxeToolbar" class="page-header-toolbar" :custom="custom"></vxe-toolbar>
    </template>
    <template v-slot:sub>
      <div ref="sub">
        <x-condition ref="xCondition" @resize="handleResize" :condition-config="realConditionConfig">
          <template v-for="(item) in conditionSlotArray" v-slot:[item.name]="scope">
            <slot :name="item.name" v-bind="scope"></slot>
          </template>
        </x-condition>
        <x-table-setting-dialog
          title="表格显示格式"
          :visible.sync="tableSettingDialogVisible"
          :mis-configure="tableSettingMisConfigure"
          :handle-select="handleTableSettingSelect"
        ></x-table-setting-dialog>
        <slot name="subSuffix"></slot>
      </div>
    </template>
    <template v-slot:main>
      <x-table
        v-on="$listeners"
        v-bind="$attrs"
        :id="realId"
        :column-cache="realColumnCache"
        ref="xTable"
        column-key
        :data="tableData"
        border
        resizable
        header-align="center"
        height="100%"
        highlight-hover-row
        highlight-current-row
        :keyboard-config="realKeyboardConfig"
        :sort-config="{remote: true, multiple: true}"
        :filter-config="{remote: true}"
        :mouse-config="{area: true, extension: true}"
        :seq-config="realSeqConfig"
        :columns="realColumns"
        :scroll-y="{gt: 60}"
        :menu-config="realMenuConfig"
        :clip-config="realClipConfig"
        :edit-config="realEditConfig"
        @menu-click="handleMenuClick"
        @sort-change="handleSortChange"
        @filter-change="handleFilterChange"
        :table-setting-config=tableSettingConfig
        @cell-area-selection-end="handleCellAreaSelectionEnd"
        @keydown="handleKeyDown"
        @keydown-capture="handleKeyDownCapture"
        :show-footer="realShowFooter"
        :footer-method="realFooterMethod"
        :edit-rules="realEditRules"
        :custom-config="realCustomConfig"
        @mousedown-capture="handleMouseDownCapture"
        :cell-class-name="getCellClassName"
      >
        <template v-for="item in slotArray" v-slot:[item]="scope">
          <slot :name="item" v-bind="scope"></slot>
        </template>
      </x-table>
    </template>
    <template v-slot:footer>
      <x-page-footer class="page-footer-remark" :page-footer-config="realPageFooterConfig" size="mini" @dblclick="handlePageFooterDblclick"></x-page-footer>
      <x-page-footer class="page-footer-dynamic-statistics" v-if="realDynamicStatisticsConfig.enabled" :page-footer-config="dynamicStatisticsPageFooterConfig"></x-page-footer>
      <el-pagination
        v-if="realPageConfig.show"
        background
        @size-change="handleSizeChange"
        @current-change="handlePageCurrentChange"
        :current-page="currentPage"
        highlight-hover-row
        :page-size="pageSize"
        :page-sizes="realPageConfig.pageSizes"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        small
        style="text-align: right"
      ></el-pagination>
    </template>
  </x-page-container>
</template>

<script>
import {
  activeNextCell, getCellClassName,
  getColumnCacheName, getConditionModel,
  getSelectFilterRender, getStatisticsFlag,
  handleError
} from '../../util/componentUtil';
import {
  COMPARISON_OPERATOR_EQUAL, FIELD_INPUT_TYPE_CHECKBOX, FIELD_INPUT_TYPE_DATE, FIELD_INPUT_TYPE_DATETIME,
  FIELD_INPUT_TYPE_POP_MULTI, FIELD_INPUT_TYPE_POP_ONE,
  FIELD_INPUT_TYPE_SELECT_MULTI, LOGICAL_OPERATOR_AND, META_EDIT_OPERATION_TYPE_REMOVE, META_EDIT_OPERATION_TYPE_UPDATE, META_TYPE_EDIT
} from '../x-meta-query/meta-query-constant';
import * as appUtils from '../../util/appUtils';
import metaMixin from '../x-meta-query/meta-mixin';
import singleMetaMixin from '../x-meta-query/single-meta-mixin';
import metaEditMixin from './meta-edit-mixin';
import {
  convertEditCondition,
  convertParamsToNode,
  getEditColumns,
  getForeignKeyFieldList,
  getFormRules,
  getLogicalFieldList,
  getPrimaryKeyFieldList, removeData,
  sortPlanList
} from '../../util/metaQueryUtil';
import tableSettingConfigMixin from '../../mixins/table-setting-config-mixin';
import tableOperateConfigMixin from '../../mixins/table-operate-config-mixin';
import tableOperateMixin, {handleMouseDownCapture} from '../../mixins/table-operate-mixin';
import {cloneDeep} from 'lodash';
import {metaEditRemove, metaEditSaveOrUpdate, searchMetaDataReportList} from '../../api/metaDataApi';
import {ARROW_DOWN, ARROW_UP, compareKeyCode, ENTER, TAB} from '../../constant/keyCode';
import {XButtonGroup, XTable, XPageContainer, XPageFooter, XCondition, XListPageDialog} from '@newpearl/ui';
import {Pagination} from 'element-ui';
import {Toolbar} from 'vxe-table';
function addRule ({rules, key, rule}) {
  if (!Array.isArray(rules[key])) {
    rules[key] = [];
  }
  rules[key].push(rule);
}
function createRule ({message, trigger = 'blur'}) {
  return {required: true, message, trigger};
}
function addItemRule ({rules, item, key = 'fieldCode', name = 'fieldName', trigger = 'blur'}) {
  if (!item.required) {
    return false;
  }
  addRule({rules, key: item[key], rule: createRule({message: item[name] + '不能为空', trigger})});
  return true;
}
export default {
  name: 'XMetaEdit',
  components: {
    [Pagination.name]: Pagination,
    [Toolbar.name]: Toolbar,
    [XButtonGroup.name]: XButtonGroup,
    [XCondition.name]: XCondition,
    [XTable.name]: XTable,
    [XPageContainer.name]: XPageContainer,
    [XPageFooter.name]: XPageFooter,
    [XListPageDialog.name]: XListPageDialog
  },
  mixins: [tableSettingConfigMixin, tableOperateConfigMixin, tableOperateMixin, metaMixin, singleMetaMixin, metaEditMixin],
  props: {
    pageConfig: {
      type: Object,
      default() {
        return {
          show: false // 是否开启分页功能
        };
      }
    },
    dataCodeArray: Array,
    // 列的配置信息,主要用于增加选择列、序号和操作列，已经对某些进行修改，如增加点击事件
    columns: {
      type: Array,
      default () {
        return [];
      }
    },
    apiConfig: {
      type: Object,
      default () {
        return {};
      }
    },
    footerConfig: {
      type: Object,
      default() {
        return {
          show: false,
          data: {
            creatorName: '',
            createTime: '',
            lastModifierName: '',
            lastModifierTime: ''
          }
        };
      }
    },
    editConfig: Object,
    editRules: Object,
    keyboardConfig: Object,
    customConfig: Object,
    /**
     * @desc 单元格是否显示fakeEdit的判断方法，如编辑模式是输入框，如果fakeEditMethod的返回值是true, 此时编辑模式会变成普通的文字显示，
     * 但用户可以选中单元格内部的部分文字
     */
    fakeEditMethod: Function,
    /**
     * @desc 单元格是否能激活的判断方法，如果返回true,表示单元格不能激活，是activeNextCell方法和cell-class-name(单元格样式)的辅助方法
     */
    disabledMethod: Function,
    /**
     * @desc 单元格是否必填的判断方法，如果返回true,表示单元格必填，false表示非必填，和editRules一起作为cell-class-name的判断是否必填的辅助方法，但不用于表单校验。
     * 对于某些场景如保存不做校验，确单时才做校验的场景可以使用改方法显必填项。
     */
    requiredMethod: Function,
    /**
     * @desc 获取查询列表数据的回调，该方法的入参是列表数据，可以通过这个方法来动态修改列表数据，然后返回给调用者
     * 该方法需要返回已处理的字段列表
     */
    handleQueryData: Function,
    cellClassName: {
      type: [String, Function],
      default: null
    }
  },
  data() {
    return {
      tableData: [],
      realEditRules: {}
    };
  },
  created() {
    if (this.conditionConfig && this.conditionConfig.labelWidth) {
      this.realConditionConfig.labelWidth = this.conditionConfig.labelWidth;
    }
    this.deleteRows = [];
  },
  mounted() {
    this.getGridInstance().connect(this.$refs.vxeToolbar);
  },
  methods: {
    handleTableSettingSelect({row}) {
      this.getXTable().setMisConfigure(row);
    },
    handleMouseDownCapture: handleMouseDownCapture,
    getCellClassName(args) {
      const cellClass = getCellClassName(args, {requiredMethod: this.requiredMethod, disabledMethod: this.disabledMethod, editRules: this.realEditRules});
      if (!this.cellClassName) {
        return cellClass;
      }
      let extraCellClass;
      if (appUtils.isFunction(this.cellClassName)) {
        extraCellClass = this.cellClassName(args);
      } else {
        extraCellClass = this.cellClassName;
      }
      if (Array.isArray(extraCellClass)) {
        cellClass.push(...extraCellClass);
      } else {
        if (appUtils.isNotEmpty(extraCellClass)) {
          cellClass.push(extraCellClass);
        }
      }
      return cellClass;
    },
    /**
     * @desc 异步获取业务数据
     * @author liangyongjia
     * @return {model, tableData}
     */
    async getExtraData() {
      const {model, tableData} = await this.getCoreParamsAsync();
      // 如果存在Object, Array等类型的数据，就直接退出，这种类型的数据一般需要根据业务需求来处理
      const treeNodeWrapper = this.getTreeNodeWrapper();
      const mainMetaDataInfo = treeNodeWrapper.data;
      const subMetaDataInfo = treeNodeWrapper.children[0].data;
      let fields = mainMetaDataInfo.fields;
      for (const field of fields) {
        const value = model[field.fieldCode];
        if (value instanceof Object || Array.isArray(value)) {
          throw new RuleError(field.name + '的数据类型是Object或Array无法转换');
        }
      }
      fields = subMetaDataInfo.fields;
      for (const field of fields) {
        for (const item of tableData) {
          const value = item[field.fieldCode];
          if (value instanceof Object || Array.isArray(value)) {
            throw new RuleError(field.name + '的数据类型是Object或Array无法转换');
          }
        }
      }
      return {model, tableData};
    },
    /**
     * @desc 快速提交数据
     * @author liangyongjia
     */
    async quickSaveOrUpdate() {
      try {
        await this.saveOrUpdate(this.getExtraData());
      } catch (error) {
        handleError(error);
      }
    },
    /**
     * @desc 提交数据
     * @param model 主表数据,即表头数据
     * @param tableData 子表数据，即表格数据
     * @author liangyongjia
     */
    async saveOrUpdate({model, tableData}) {
      return metaEditSaveOrUpdate(this.convertParamsToTree({model, tableData}));
    },
    /**
     * @desc 快速提交数据并查询
     * @author liangyongjia
     */
    async quickSaveOrUpdateAndQuery() {
      try {
        await this.saveOrUpdateAndQuery(this.getExtraData());
      } catch (error) {
        handleError(error);
      }
    },
    /**
     * @desc 提交数据并查询
     * @param model 主表数据,即表头数据
     * @param tableData 子表数据，即表格数据
     * @author liangyongjia
     */
    async saveOrUpdateAndQuery({model, tableData} = {}) {
      if (!model || !Array.isArray(tableData)) {
        const obj = await this.getCoreParamsAsync();
        model = obj.model;
        tableData = obj.tableData;
      }
      const response = await this.saveOrUpdate({model, tableData});
      const res = response.data;
      if (!res.isSuccess()) {
        throw new RequestError(res.msg);
      }
      this.queryPageData({
        conditionMethod: () => {
          const extraData = res.data.children[0].extraData;
          const primaryKeyFields = getPrimaryKeyFieldList({fields: this.treeNodeWrapper.data.fields});
          const conditionList = [];
          for (let i = 0; i < primaryKeyFields.length; i++) {
            const fieldCode = primaryKeyFields[i].fieldCode;
            const condition = {fieldCode, fieldValue: extraData[fieldCode], operator: COMPARISON_OPERATOR_EQUAL.value};
            if (i !== 0) {
              condition.logicalOperator = LOGICAL_OPERATOR_AND.value;
            }
            conditionList.push(condition);
          }
          return conditionList;
        }
      });
    },
    isAddNewRowEnabled() {
      return true;
    },
    handleKeyDown({$event, $grid, $table}) {
      const key = $event.key;
      if (compareKeyCode(key, ENTER)) {
        activeNextCell({$grid, $table, disabledMethod: this.disabledMethod}).then(() => {
          this.handleActiveNextCell && this.handleActiveNextCell();
        });
      }
      if (compareKeyCode(key, ARROW_DOWN) || compareKeyCode(key, ARROW_UP) || compareKeyCode(key, TAB)) {
        const tableInstance = $grid || $table;
        // 在单元激活状态下，点击上下键会使上一个或下一个单元格处于选中状态，此时$el会使用焦点导致无法监听keydown-capture
        tableInstance.$el.focus();
      }
    },
    activeNextCell({row, column} = {}) {
      return activeNextCell({$grid: this.getGridInstance(), row, column, disabledMethod: this.disabledMethod});
    },
    getEditRules() {
      return this.realEditRules;
    },
    /**
     * @desc 异步获取组件参数
     * @author liangyongjia
     * @param validate 是否需要校验，默认为true
     * @return promise
     */
    async getCoreParamsAsync({validate = true, raw = false} = {}) {
      const coreParams = this.getCoreParams();
      if (!validate) {
        if (raw) {
          return coreParams;
        }
        return this.convertParams(coreParams);
      }
      await this.getXCondition().validate();
      await this.getGridInstance().fullValidate(true);
      if (this.validateParams) {
        await this.validateParams(coreParams);
      }
      if (raw) {
        return coreParams;
      }
      return this.convertParams(coreParams);
    },
    getTreeNodeWrapper() {
      return this.treeNodeWrapper;
    },
    /**
     * @desc 转换数据，包括深拷贝，日期转换等
     */
    convertParams({model, tableData}) {
      const mainMetaDataInfo = this.treeNodeWrapper.data;
      const subMetaDataInfo = this.treeNodeWrapper.children[0].data;
      const newModel = cloneDeep(model);
      let fieldMap = {};
      for (const item of mainMetaDataInfo.fields) {
        fieldMap[item.fieldCode] = item;
      }
      for (const key in newModel) {
        const value = newModel[key];
        // 普通数据类型
        if (!Array.isArray(value) && !appUtils.isObject(value)) {
          continue;
        }
        const field = fieldMap[key];
        // 根据设定的格式转换成字符串
        if (value instanceof Date) {
          if (field.fieldFormat) {
            newModel[key] = appUtils.dateFormat(field.fieldFormat, value);
          } else {
            newModel[key] = value.getTime();
          }
        }
      }
      fieldMap = {};
      const newTableData = cloneDeep(tableData);
      for (const item of subMetaDataInfo.fields) {
        fieldMap[item.fieldCode] = item;
      }
      for (const row of newTableData) {
        for (const key in row) {
          const value = row[key];
          // 普通数据类型
          if (!Array.isArray(value) && !appUtils.isObject(value)) {
            continue;
          }
          const field = fieldMap[key];
          if (value instanceof Date) {
            if (field.fieldFormat) {
              row[key] = appUtils.dateFormat(field.fieldFormat, value);
            } else {
              row[key] = value.getTime();
            }
          }
        }
      }
      return {model: newModel, tableData: newTableData};
    },
    /**
     * @desc 将数据转成树结构
     */
    convertParamsToTree({model, tableData}) {
      const $treeNodeWrapper = this.getTreeNodeWrapper();
      const mainMetaDataInfo = $treeNodeWrapper.data;
      const subMetaDataInfo = $treeNodeWrapper.children[0].data;
      const children = convertParamsToNode({metaData: mainMetaDataInfo.metaData, metaEditOperationType: META_EDIT_OPERATION_TYPE_UPDATE, extraDataList: [model]});
      children[0].children = convertParamsToNode({metaData: subMetaDataInfo.metaData, metaEditOperationType: META_EDIT_OPERATION_TYPE_UPDATE, extraDataList: tableData});
      // 追加被删除的数据,没有主键值的记录要剔除，这些记录是新增后没有保存直接删除
      const primaryKeyFieldList = getPrimaryKeyFieldList({fields: subMetaDataInfo.fields});
      const deleteRows = [];
      for (const row of this.deleteRows) {
        let flag = false;
        for (const field of primaryKeyFieldList) {
          if (appUtils.isEmpty(row[field.fieldCode])) {
            flag = true;
            break;
          }
        }
        if (flag) {
          continue;
        }
        deleteRows.push(row);
      }
      children[0].children.push(...convertParamsToNode({metaData: subMetaDataInfo.metaData, metaEditOperationType: META_EDIT_OPERATION_TYPE_REMOVE, extraDataList: deleteRows}));
      removeData({list: children});
      return {children};
    },
    /**
     * @desc 删除记录
     */
    async remove({metaData, extraDataList}) {
      const children = convertParamsToNode({metaData, metaEditOperationType: META_EDIT_OPERATION_TYPE_REMOVE, extraDataList});
      return await metaEditRemove({children});
    },
    /**
     * @desc 从当前页最顶层的数据删除记录，最顶层数据对应最顶层的功能号，也就是主表
     */
    async removeTop({extraDataList}) {
      return await this.remove({metaData: this.getTreeNodeWrapper().data.metaData, extraDataList});
    },
    /**
     * @desc 获取组件参数
     * @author liangyongjia
     * @return {}
     */
    getCoreParams() {
      return {
        model: this.realConditionConfig.model,
        tableData: this.tableData
      };
    },
    /**
     * @desc 删除表格中的记录
     * @author liangyongjia
     * @return 被删除的记录
     */
    deleteRow() {
      const records = this.getXTable().getRecords();
      if (!Array.isArray(records) || records.length < 1) {
        this.$notify.error('请选择数据');
        return records;
      }
      for (const item of records) {
        this.tableData.splice(this.tableData.indexOf(item), 1);
      }
      this.deleteRows.push(...records);
      return records;
    },
    async getEditNewRow() {
      return await this.getNewRow({$grid: this.getGridInstance()});
    },
    async getNewRow({$grid, $table}) {
      await this.getXCondition().validate();
      if (this.createNewRow) {
        return await this.createNewRow({$grid: this.getGridInstance()});
      }
      const columns = this.getGridInstance().getTableColumn().fullColumn;
      const row = {};
      for (const column of columns) {
        if (column.type || !column.params || !column.params.metaDataField) {
          continue;
        }
        const field = column.params.metaDataField;
        const fieldInputType = field.fieldInputType;
        if (fieldInputType === FIELD_INPUT_TYPE_POP_ONE.value) {
          row[column.property] = null;
          continue;
        }
        if (fieldInputType === FIELD_INPUT_TYPE_POP_MULTI.value || fieldInputType === FIELD_INPUT_TYPE_SELECT_MULTI.value) {
          row[column.property] = [];
          continue;
        }
        if (fieldInputType === FIELD_INPUT_TYPE_CHECKBOX.value) {
          row[column.property] = false;
          continue;
        }
        row[column.property] = '';
      }
      return row;
    },
    /**
     * @desc 新增一行
     * @author liangyongjia
     */
    async addNewRow() {
      const row = await this.getNewRow({$grid: this.getGridInstance()});
      this.tableData.push(row);
    },
    appendNewRows(rows) {
      this.tableData.push(...rows);
    },
    getTableData() {
      return this.tableData;
    },
    setTableData(tableData) {
      this.tableData = tableData;
    },
    /* updateForeignKey() {
      const model = this.realConditionConfig.model;
      const tableData = this.tableData;
      const list = this.getForeignKeyFieldList({
          masterMetaDataInfo: this.treeNodeWrapper.data,
          slaveMetaDataInfo: this.treeNodeWrapper.children[0].data
      });
      for (const {master, slave} of list) {
        for (const item of tableData) {
          item[slave.fieldCode] = model[master.fieldCode];
        }
      }
    }, */
    /**
     * @desc 查询配置信息并渲染界面
     * @author liangyongjia
     */
    async getMetaDataDetail() {
      // 查找主表数据
      let response = await this.apiConfig.getMetaDataAndFieldsApi({dataCode: this.dataCode});
      let res = response.data;
      if (!res.isSuccess()) {
        this.$notify.error(res.msg);
        return;
      }
      let data = res.data;
      if (!data) {
        this.$notify.error('配置信息为空');
        return;
      }
      if (this.handleMetaData) {
        this.handleMetaData(data);
      }
      this.treeNodeWrapper = {};
      this.treeNodeWrapper.data = data;
      response = await this.apiConfig.getMetaQueryPlanList(this.dataCode, {queryTypeArray: this.queryTypeArray, metaType: META_TYPE_EDIT.value});
      res = response.data;
      if (!res.isSuccess()) {
        this.$notify.error(res.msg);
        return;
      }
      data = res.data;
      if (!Array.isArray(data) || data.length < 1) {
        this.$notify.error('主表暂无查询方案，请新建查询方案');
        return;
      }
      sortPlanList(data);
      response = await this.apiConfig.getMetaQueryPlanDetail(data[0]);
      res = response.data;
      if (!res.isSuccess()) {
        return;
      }
      // this.metaQueryList = data;
      const conditions = res.data.conditions;
      const conditionList = await convertEditCondition({fields: this.treeNodeWrapper.data.fields, presetConditionConfig: this.conditionConfig, conditions});
      // 渲染表头
      this.realConditionConfig.model = getConditionModel({list: conditionList});
      this.realConditionConfig.rules = await getFormRules({fields: conditions, presetRules: this.conditionConfig.rules, modelKey: 'fieldCode'});
      this.realConditionConfig.list = conditionList;
      // 查找副表数据
      response = await this.apiConfig.getMetaDataInfoList({parentDataCode: this.dataCode});
      res = response.data;
      if (!res.isSuccess()) {
        this.$notify.error(res.msg);
        return;
      }
      data = res.data;
      // if (this.handleMetaData) {
      //   this.handleMetaData({metaData, children: data});
      // }
      if (!Array.isArray(data) || data.length < 1) {
        return;
      }
      // 取第一个child
      const metaDataInfo = data[0];
      this.treeNodeWrapper.children = [{data: metaDataInfo}];
      response = await this.apiConfig.getMetaQueryPlanList(metaDataInfo.metaData.dataCode, {queryTypeArray: this.queryTypeArray, metaType: META_TYPE_EDIT.value});
      res = response.data;
      if (!res.isSuccess()) {
        this.$notify.error(res.msg);
        return;
      }
      data = res.data;
      if (!Array.isArray(data) || data.length < 1) {
        this.$notify.error('副表暂无查询方案，请新建查询方案');
        return;
      }
      sortPlanList(data);
      response = await this.apiConfig.getMetaQueryPlanDetail(data[0]);
      res = response.data;
      if (!res.isSuccess()) {
        this.$notify.error(res.msg);
        return;
      }
      const lists = res.data.lists;
      this.realColumns = await getEditColumns({fields: metaDataInfo.fields, presetColumns: this.columns, lists, fakeEditMethod: this.fakeEditMethod});
      this.realEditRules = await getFormRules({fields: lists, presetEditRules: this.editRules, modelKey: 'fieldCode'});
      // this.childMetaData = metaDataInfo.metaData;
      // this.childFields = metaDataInfo.fields;
      if (this.handleInitializationComplete) {
        this.handleInitializationComplete({conditionConfig: this.realConditionConfig, columns: this.realColumns, treeNodeWrapper: this.treeNodeWrapper});
      }
      setTimeout(() => {
        this.getXTable().initTableSetting();
      });
    },
    async queryPageData({conditionMethod}) {
      const treeNodeWrapper = this.treeNodeWrapper;
      let metaDataInfo = treeNodeWrapper.data;
      let metaData = metaDataInfo.metaData;
      let fields = metaDataInfo.fields;
      let logicalFieldList = getLogicalFieldList({fields});
      let conditions = conditionMethod({metaData});
      // 逻辑条件
      for (const field of logicalFieldList) {
        const condition = {fieldCode: field.fieldCode, fieldValue: field.logicalValid, operator: COMPARISON_OPERATOR_EQUAL.value};
        if (conditions.length > 0) {
          condition.logicalOperator = LOGICAL_OPERATOR_AND.value;
        }
        conditions.push(condition);
      }
      let queryParams = {
        dataCode: metaData.dataCode,
        page: 1,
        pageSize: 65535,
        sumAll: false,
        count: false,
        dataName: metaData.dataName,
        conditions
      };
      let response = await searchMetaDataReportList({jsonStr: JSON.stringify(queryParams)});
      let res = response.data;
      if (!res.isSuccess()) {
        throw new RequestError(res.msg);
      }
      let list = res.data.pager.list;
      const listCopy = JSON.parse(JSON.stringify(list));
      let handleQueryDataFields = [];
      if (this.handleQueryData) {
        handleQueryDataFields = this.handleQueryData({metaData, fields, data: list});
      }
      this.$handleQueryData({metaData, fields, data: list, handleQueryDataFields});
      Object.assign(this.realConditionConfig.model, list[0]);
      metaDataInfo = treeNodeWrapper.children[0].data;
      metaData = metaDataInfo.metaData;
      fields = metaDataInfo.fields;
      conditions = [];
      const foreignKeyFieldList = getForeignKeyFieldList({
        masterMetaDataInfo: treeNodeWrapper.data,
        slaveMetaDataInfo: metaDataInfo
      });
      // 外键条件
      for (const {master, slave} of foreignKeyFieldList) {
        const condition = {fieldCode: slave.fieldCode, operator: COMPARISON_OPERATOR_EQUAL.value, fieldValue: listCopy[0][master.fieldCode]};
        if (conditions.length > 0) {
          condition.logicalOperator = LOGICAL_OPERATOR_AND.value;
        }
        conditions.push(condition);
      }
      // 逻辑条件
      logicalFieldList = getLogicalFieldList({fields});
      for (const field of logicalFieldList) {
        const condition = {fieldCode: field.fieldCode, fieldValue: field.logicalValid, operator: COMPARISON_OPERATOR_EQUAL.value};
        if (conditions.length > 0) {
          condition.logicalOperator = LOGICAL_OPERATOR_AND.value;
        }
        conditions.push(condition);
      }
      queryParams = {
        dataCode: metaData.dataCode,
        page: 1,
        pageSize: 65535,
        sumAll: false,
        dataName: metaData.dataName,
        conditions
      };
      response = await searchMetaDataReportList({jsonStr: JSON.stringify(queryParams)});
      res = response.data;
      if (!res.isSuccess()) {
        throw new RequestError(res.msg);
      }
      list = res.data.pager.list;
      handleQueryDataFields = [];
      if (this.handleQueryData) {
        handleQueryDataFields = this.handleQueryData({metaData, fields, data: list});
      }
      this.$handleQueryData({metaData, fields, data: list, handleQueryDataFields});
      this.tableData = list;
    },
    $handleQueryData({metaData, fields, data, handleQueryDataFields}) {
      const fieldMap = {};
      for (const field of fields) {
        fieldMap[field.fieldCode] = field;
      }
      const handleQueryDataFieldMap = {};
      for (const field of handleQueryDataFields) {
        handleQueryDataFieldMap[field.fieldCode] = field;
      }
      for (const item of data) {
        for (const key in item) {
          let field = handleQueryDataFieldMap[key];
          // 调用者已经处理了该字段对应的内容，这里不需要再处理
          if (field) {
            continue;
          }
          field = fieldMap[key];
          // 如果找不到字段也不处理，这些key可能是调用者临时加上的
          if (!field) {
            continue;
          }
          const value = item[key];
          const fieldInputType = field.fieldInputType;
          if (fieldInputType === FIELD_INPUT_TYPE_POP_ONE.value) {
            if (!value) {
              item[key] = null;
              continue;
            }
            if (field.refFieldName && field.refFieldName !== field.refFieldCode) {
              item[key] = {[field.refFieldCode]: value, [field.refFieldName]: item[field.refFieldName]};
            } else {
              item[key] = {[field.refFieldCode]: value};
            }
            continue;
          }
          if (fieldInputType === FIELD_INPUT_TYPE_POP_MULTI.value || fieldInputType === FIELD_INPUT_TYPE_SELECT_MULTI.value) {
            if (!value) {
              continue;
            }
            item[key] = JSON.parse(value);
            continue;
          }
          if (fieldInputType === FIELD_INPUT_TYPE_DATE.value || fieldInputType === FIELD_INPUT_TYPE_DATETIME.value) {
            item[key] = appUtils.toDate(value);
            continue;
          }
        }
      }
    },
    getStatisticsFlag({name}) {
      // 这里做缓存，提高性能
      const cacheName = '$Statistics' + name;
      if (Object.prototype.hasOwnProperty.call(this, cacheName)) {
        return this[cacheName];
      }
      this[cacheName] = getStatisticsFlag({columns: this.realColumns, propertyArray: [name]});
      return this[cacheName];
    },
    handleSortChange({sortList}) {
    },
    handleFilterChange({filterList}) {
    },
    createSelectFilter ({item, options, multiple}) {
      item.filterRender = getSelectFilterRender({options, multiple});
      item.filters = [{data: ''}];
    },
    addRow() {
      this.getXCondition().validate().then(() => {
        const obj = {};
        for (const item of this.realColumns) {
          const fieldInputType = item.fieldInputType;
          switch (fieldInputType) {
            case FIELD_INPUT_TYPE_CHECKBOX.value:
            case FIELD_INPUT_TYPE_SELECT_MULTI.value:
            case FIELD_INPUT_TYPE_POP_MULTI.value:
              obj[item.field] = [];
              break;
            case FIELD_INPUT_TYPE_POP_ONE.value:
              obj[item.field] = null;
              break;
            default:
              obj[item.field] = '';
              break;
          }
        }
        this.tableData.push(obj);
      });
    },
    /**
     * 获取model，方便父组件改变model的数据
     * @return {{}}
     */
    getConditionConfig() {
      return this.realConditionConfig;
    },
    /**
     * 获取页面数据,这些数据时页面数据的备份，修改数据不会影响页面
     * 1. 使用弹窗单选的数据时一个对象，根据rowKey转成基本数据类型
     * @return {{model: any, tableData: any}}
     */
    getFlatData () {
      const model = JSON.parse(JSON.stringify(this.realConditionConfig.model));
      for (const item of this.conditionConfig.list) {
        if (item.fieldInputType === FIELD_INPUT_TYPE_POP_ONE.value) {
          const value = model[item.field];
          if (appUtils.isObject(value)) {
            model[item.field] = value[item.rowKey];
          }
        }
      }
      const tableData = JSON.parse(JSON.stringify(this.tableData));
      for (const item of tableData) {
        for (const key in item) {
          const column = this.columnMap[key];
          if (!column || !column.params) {
            continue;
          }
          const fieldInputType = column.params.fieldInputType;
          if (fieldInputType === FIELD_INPUT_TYPE_POP_ONE.value) {
            const value = item[key];
            if (!appUtils.isObject(value)) {
              continue;
            }
            item[key] = value[column.params.rowKey];
          }
        }
      }
      return {model, tableData};
    },
    getColumns() {
      return this.realColumns;
    },
    getColumnMap() {
      return this.columnMap;
    },
    activeMethod({row, column}) {
      const params = column.params;
      if (!params) {
        return false;
      }
      const metaDataField = params.metaDataField;
      if (metaDataField.readOnly) {
        return false;
      }
      return true;
    }
  },
  computed: {
    realColumnCache () {
      if (this.columnCache) {
        return this.columnCache;
      }
      return getColumnCacheName({ name: this.dataCode, suffix: 'x-meta-edit' });
    },
    columnMap() {
      const map = {};
      for (const item of this.realColumns) {
        map[item.field] = item;
      }
      return map;
    }
  },
  watch: {
    // 'conditionConfig.model': {
    //   handler(newValue) {
    //     Object.assign(this.realConditionConfig.model, newValue);
    //   },
    //   deep: true
    // }
  }
};
</script>
