<template>
  <div>
    <vxe-toolbar v-if="actionButton && !disabled && !(recordConfig.options.disabledAdd && recordConfig.options.disabledDel && extButtons.length === 0)">
      <template #buttons>
        <a-button v-if="!recordConfig.options.disabledAdd" :type="addButton.buttonStyle" :icon="addButton.buttonIcon"
                  @click="callFn(addButton)">
          {{ $locale(addButton.label) }}
        </a-button>
        <span v-if="!recordConfig.options.disabledAdd" class="action-button-gap"></span>
        <template v-for="(button, index) in extButtons">
          <a-button :type="button.buttonStyle" :icon="button.buttonIcon" @click="callFn(button)">
            {{ $locale(button.label) }}
          </a-button>
          <span class="action-button-gap"></span>
        </template>
        <a-button v-if="rowSelection && !recordConfig.options.disabledDel" type="default" icon="minus"
                  @click="deleteRow">{{ $locale('m.common.button.delete') }}
        </a-button>
      </template>
    </vxe-toolbar>

    <!-- 如果有page控件会有问题，需要设置true-->
    <!-- :row-key="dragSort && !disabled"-->
    <!-- :scroll-y="{enabled: !(dragSort && !disabled)}"-->
    <vxe-table
        header-align="center"
        :scroll-y="{enabled: false}"
        ref="xTable"
        class="sortable-row-vxe"
        show-header-overflow
        show-overflow
        :height="height === -1 ? undefined : height"
        :edit-rules="validRules"
        :span-method="mergeRowMethod"
        :row-style="getRowStyle"
        :cell-style="getCellStyle"
        :row-config="{isHover: true, useKey: true, keyField: rowId}"
        :edit-config="{trigger: 'click', mode: 'cell', activeMethod: activeRowMethod}"
        :tree-config="treeEnable ? {transform: true, rowField: rowId, parentField: parentField} : undefined"
        :data="isPage ? currentDataSource : dataSource"
        :seq-config="treeEnable ? undefined : {seqMethod}"
    >
      <vxe-column width="60" align="center" v-if="dragSort && !disabled && !treeEnable">
        <template #default>
          <span class="drag-btn">
            <i class="vxe-icon--menu"></i>
          </span>
        </template>
      </vxe-column>
      <vxe-column type="checkbox" width="50" align="center" v-if="rowSelection && !disabled"></vxe-column>
      <vxe-column type="seq" :title="$locale('m.common.label.number')" :width="treeEnable ? 120 : 60" align="center"
                  v-if="rowNumber" :tree-node="treeEnable && treeNodeField === '_seq'"></vxe-column>
      <template v-for="(item, index) in columnsVxe">
        <vxe-colgroup
          v-if="item.children && item.children.length > 0"
          :title="item.title">
          <vxe-column v-for="(children) in item.children"
                      :key="children.dataIndex"
                      :field="children.key" :title="children.title"
                      :edit-render="children.editRender" :min-width="children.vxeMinWidth" :width="children.vxeWidth"
                      :class-name="children.className"
                      :show-overflow="typeof children.showOverflow !== 'undefined' ? children.showOverflow : undefined"
                      :align="children.align === 'default' ? undefined : children.align"
                      :tree-node="treeEnable && treeNodeField === children.key"
                      :formatter="children.formatter"
                      :fixed="children.fixed">
            <template #default="{ row, rowIndex, column, columnIndex }" v-if="children.slotDefault">
              <!--          <ViewFileSlot @clickItemFile="clickItemFile(row,item)" v-if="children.slotDefault === 'file'" v-model="row[children.key]"/>-->
              <div style="width: 100%;color: blue;cursor: pointer;" v-show="children.slotDefault === 'file'"
                   @click="clickItemSlot(row, rowIndex, column, columnIndex,item,'file')">{{ getFileName(row, item) }}
              </div>
              <div style="color: blue;cursor: pointer;width: 100%"
                   v-show="children.slotDefault === 'radio' && checkHtml(row[children.key])" v-html="row[children.key]"/>
              <div style="cursor: pointer;width: 100%;color: blue;cursor: pointer;" v-show="children.slotDefault === 'fivewhy'"
                   @click="clickItemSlot(row, rowIndex, column, columnIndex,item,'fivewhy')">5WHY图
              </div>
              <div style="cursor: pointer;width: 100%;color: blue;cursor: pointer;" v-show="children.slotDefault === 'mind'"
                   @click="clickItemSlot(row, rowIndex, column, columnIndex,item,'mind')">脑图
              </div>
              <div style="cursor: pointer;width: 100%;color: blue;cursor: pointer;"  v-show="children.slotDefault === 'fishbone'" @click="clickItemSlot(row, rowIndex, column, columnIndex,item,'fishbone')">鱼骨图</div>
              <div v-show="children.slotDefault === 'date'">{{ row[children.key] }}</div>
              <a v-if="children.slotDefault === 'action'" @click="callFn(null, row, item)"
                 :title="row[children.key]">{{ row[children.key] || (children.tempKey === 'Y' ? (children.defaultValue || '操作') : '') }}</a>

              <sub-table-page-button
                v-else-if="children.slotDefault === 'page'"
                :showConfigString="children.showConfig"
                :record="row"
                :property="column.property"
                :disabled="true"
                @setFieldValue="setSubFieldValue"
              ></sub-table-page-button>

              <sub-table-user-button
                v-else-if="children.slotDefault === 'user'"
                :showConfigString="children.showConfig"
                :record="row"
                :property="column.property"
                :disabled="true"
                :linkage="children.enableLinkage ? (children.linkage + '_' + row[rowId]) : null"
                :linkage-map="linkageMap"
                @setFieldValue="setSubFieldValue"
              ></sub-table-user-button>

              <sub-table-dept-button
                v-else-if="children.slotDefault === 'dept'"
                :showConfigString="children.showConfig"
                :record="row"
                :property="column.property"
                :disabled="true"
                @setFieldValue="setSubFieldValue"
              ></sub-table-dept-button>

              <sub-check-tag
                v-else-if="children.slotDefault === 'radio' && !checkHtml(row[children.key])"
                type="radio"
                :options="children.options"
                :record="row"
                :property="column.property"
                :disabled="!children.slotEdit"
                @setFieldValue="setSubFieldValue"
              ></sub-check-tag>

              <Signature
                v-else-if="children.slotDefault === 'signature'"
                :disabled="!children.slotEdit"
                :multiple="children.showConfigJson.multiple || false"
                bizPath="signature"
                :record="row"
                :property="column.property"
                imgStyle="width:200px;height:40px;"
                v-model="row[column.property]"
                @setFieldValue="setSubFieldValue"
              />

              <ych-serialno
                v-else-if="children.slotDefault === 'serialno'"
                :disabled="true"
                :readOnly="true"
                :displayByText="true"
                :ruleCode="children.showConfigJson.ruleCode || 'default_rule'"
                :form="form"
                :record="row"
                :property="column.property"
                v-model="row[column.property]"
                @setFieldValue="setSubFieldValue"
              />

            </template>

            <template #edit="{ row, column }" v-if="children.slotEdit">
              <vxe-input v-if="children.slotEdit === 'date'" v-model="row[children.key]" type="date" :transfer="true"
                         @change="valueChangeDate(row, column)"></vxe-input>
              <vxe-input v-else-if="children.slotEdit === 'datetime'" v-model="row[children.key]" type="datetime"
                         :transfer="true" @change="valueChangeDate(row, column)"></vxe-input>
              <vxe-input v-else-if="children.slotEdit === 'time'" v-model="row[children.key]" type="time"
                         :transfer="true" @change="valueChangeDate(row, column)"></vxe-input>
              <a-select v-else-if="children.slotEdit === 'select'" v-model="row[children.key]" allowClear
                        @change="valueChangeSelect({row, column})">
                <a-select-option
                  v-for="option in (linkageValue(children.linkage, row) ? (linkagesOptions[linkageKey(children.linkage, row, column.property)] || []) : [])"
                  :key="option.value" :value="option.value" class="vxe-table--ignore-clear">
                  {{ option.label }}
                </a-select-option>
              </a-select>
              <a-select v-else-if="children.slotEdit === 'select_default'" v-model="row[children.key]" allowClear
                        @change="valueChangeSelect({row, column})">
                <a-select-option v-for="option in children.options" :key="option.value" :value="option.value"
                                 class="vxe-table--ignore-clear">
                  {{ option.label }}
                </a-select-option>
              </a-select>

              <!-- TODO 存在性能问题 -->
              <sub-table-page-button
                v-else-if="children.slotEdit === 'page'"
                :showConfigString="children.showConfig"
                :record="row"
                :property="column.property"
                :disabled="false"
                :form="form"
                @setFieldValue="setSubFieldValue"
              ></sub-table-page-button>

              <sub-table-user-button
                v-else-if="children.slotEdit === 'user'"
                :showConfigString="children.showConfig"
                :record="row"
                :property="column.property"
                :disabled="false"
                :linkage="children.enableLinkage ? (children.linkage + '_' + row[rowId]) : null"
                :linkage-map="linkageMap"
                @setFieldValue="setSubFieldValue"
              ></sub-table-user-button>

              <sub-table-dept-button
                v-else-if="children.slotEdit === 'dept'"
                :showConfigString="children.showConfig"
                :record="row"
                :property="column.property"
                :disabled="false"
                @setFieldValue="setSubFieldValue"
              ></sub-table-dept-button>

              <sub-check-tag
                v-else-if="children.slotEdit === 'radio'"
                type="radio"
                :options="children.options"
                :record="row"
                :property="column.property"
                :disabled="false"
                @setFieldValue="setSubFieldValue"
              ></sub-check-tag>

              <Signature
                v-else-if="children.slotEdit === 'signature'"
                :disabled="false"
                :multiple="children.showConfigJson.multiple || false"
                bizPath="signature"
                :record="row"
                :property="column.property"
                imgStyle="width:200px;height:40px;"
                v-model="row[column.property]"
                @setFieldValue="setSubFieldValue"
              />

              <ych-serialno
                v-else-if="children.slotEdit === 'serialno'"
                :disabled="true"
                :readOnly="true"
                :displayByText="true"
                :ruleCode="children.showConfigJson.ruleCode || 'default_rule'"
                :form="form"
                :record="row"
                :property="column.property"
                v-model="row[column.property]"
                @setFieldValue="setSubFieldValue"
              />

            </template>

          </vxe-column>
        </vxe-colgroup>

        <vxe-column v-else :field="item.key" :title="item.title"
                    :edit-render="item.editRender" :min-width="item.vxeMinWidth" :width="item.vxeWidth"
                    :class-name="item.className"
                    :show-overflow="typeof item.showOverflow !== 'undefined' ? item.showOverflow : undefined"
                    :align="item.align === 'default' ? undefined : item.align"
                    :tree-node="treeEnable && treeNodeField === item.key"
                    :formatter="item.formatter"
                    :fixed="item.fixed">

          <template #default="{ row, rowIndex, column, columnIndex }" v-if="item.slotDefault">
            <!--          <ViewFileSlot @clickItemFile="clickItemFile(row,item)" v-if="item.slotDefault === 'file'" v-model="row[item.key]"/>-->
            <div style="width: 100%;color: blue;cursor: pointer;" v-show="item.slotDefault === 'file'"
                 @click="clickItemSlot(row, rowIndex, column, columnIndex,item,'file')">{{ getFileName(row, item) }}
            </div>
            <div style="color: blue;cursor: pointer;width: 100%"
                 v-show="item.slotDefault === 'radio' && checkHtml(row[item.key])" v-html="row[item.key]"/>
            <div style="cursor: pointer;width: 100%;color: blue;cursor: pointer;" v-show="item.slotDefault === 'fivewhy'"
                 @click="clickItemSlot(row, rowIndex, column, columnIndex,item,'fivewhy')">5WHY图
            </div>
            <div style="cursor: pointer;width: 100%;color: blue;cursor: pointer;" v-show="item.slotDefault === 'mind'"
                 @click="clickItemSlot(row, rowIndex, column, columnIndex,item,'mind')">脑图
            </div>
            <div style="cursor: pointer;width: 100%;color: blue;cursor: pointer;"  v-show="item.slotDefault === 'fishbone'" @click="clickItemSlot(row, rowIndex, column, columnIndex,item,'fishbone')">鱼骨图</div>
            <div v-show="item.slotDefault === 'date'">{{ row[item.key] }}</div>
            <a v-if="item.slotDefault === 'action'" @click="callFn(null, row, item)"
               :title="row[item.key]">{{ row[item.key] || (item.tempKey === 'Y' ? (item.defaultValue || '操作') : '') }}</a>

            <sub-table-page-button
              v-else-if="item.slotDefault === 'page'"
              :showConfigString="item.showConfig"
              :record="row"
              :property="column.property"
              :disabled="true"
              @setFieldValue="setSubFieldValue"
            ></sub-table-page-button>

            <sub-table-user-button
              v-else-if="item.slotDefault === 'user'"
              :showConfigString="item.showConfig"
              :record="row"
              :property="column.property"
              :disabled="true"
              :linkage="item.enableLinkage ? (item.linkage + '_' + row[rowId]) : null"
              :linkage-map="linkageMap"
              @setFieldValue="setSubFieldValue"
            ></sub-table-user-button>

            <sub-table-dept-button
              v-else-if="item.slotDefault === 'dept'"
              :showConfigString="item.showConfig"
              :record="row"
              :property="column.property"
              :disabled="true"
              @setFieldValue="setSubFieldValue"
            ></sub-table-dept-button>

            <sub-check-tag
              v-else-if="item.slotDefault === 'radio' && !checkHtml(row[item.key])"
              type="radio"
              :options="item.options"
              :record="row"
              :property="column.property"
              :disabled="!item.slotEdit"
              @setFieldValue="setSubFieldValue"
            ></sub-check-tag>

            <Signature
              v-else-if="item.slotDefault === 'signature'"
              :disabled="!item.slotEdit"
              :multiple="item.showConfigJson.multiple || false"
              bizPath="signature"
              :record="row"
              :property="column.property"
              imgStyle="width:200px;height:40px;"
              v-model="row[column.property]"
              @setFieldValue="setSubFieldValue"
            />

            <ych-serialno
              v-else-if="item.slotDefault === 'serialno'"
              :disabled="true"
              :readOnly="true"
              :displayByText="true"
              :ruleCode="item.showConfigJson.ruleCode || 'default_rule'"
              :form="form"
              :record="row"
              :property="column.property"
              v-model="row[column.property]"
              @setFieldValue="setSubFieldValue"
            />

          </template>

          <template #edit="{ row, column }" v-if="item.slotEdit">
            <vxe-input v-if="item.slotEdit === 'date'" v-model="row[item.key]" type="date" :transfer="true"
                       @change="valueChangeDate(row, column)"></vxe-input>
            <vxe-input v-else-if="item.slotEdit === 'datetime'" v-model="row[item.key]" type="datetime"
                       :transfer="true" @change="valueChangeDate(row, column)"></vxe-input>
            <vxe-input v-else-if="item.slotEdit === 'time'" v-model="row[item.key]" type="time"
                       :transfer="true" @change="valueChangeDate(row, column)"></vxe-input>
            <a-select v-else-if="item.slotEdit === 'select'" v-model="row[item.key]" allowClear
                      @change="valueChangeSelect({row, column})">
              <a-select-option
                v-for="option in (linkageValue(item.linkage, row) ? (linkagesOptions[linkageKey(item.linkage, row, column.property)] || []) : [])"
                :key="option.value" :value="option.value" class="vxe-table--ignore-clear">
                {{ option.label }}
              </a-select-option>
            </a-select>
            <a-select v-else-if="item.slotEdit === 'select_default'" v-model="row[item.key]" allowClear
                      @change="valueChangeSelect({row, column})">
              <a-select-option v-for="option in item.options" :key="option.value" :value="option.value"
                               class="vxe-table--ignore-clear">
                {{ option.label }}
              </a-select-option>
            </a-select>

            <!-- TODO 存在性能问题 -->
            <sub-table-page-button
              v-else-if="item.slotEdit === 'page'"
              :showConfigString="item.showConfig"
              :record="row"
              :property="column.property"
              :disabled="false"
              :form="form"
              @setFieldValue="setSubFieldValue"
            ></sub-table-page-button>

            <sub-table-user-button
              v-else-if="item.slotEdit === 'user'"
              :showConfigString="item.showConfig"
              :record="row"
              :property="column.property"
              :disabled="false"
              :linkage="item.enableLinkage ? (item.linkage + '_' + row[rowId]) : null"
              :linkage-map="linkageMap"
              @setFieldValue="setSubFieldValue"
            ></sub-table-user-button>

            <sub-table-dept-button
              v-else-if="item.slotEdit === 'dept'"
              :showConfigString="item.showConfig"
              :record="row"
              :property="column.property"
              :disabled="false"
              @setFieldValue="setSubFieldValue"
            ></sub-table-dept-button>

            <sub-check-tag
              v-else-if="item.slotEdit === 'radio'"
              type="radio"
              :options="item.options"
              :record="row"
              :property="column.property"
              :disabled="false"
              @setFieldValue="setSubFieldValue"
            ></sub-check-tag>

            <Signature
              v-else-if="item.slotEdit === 'signature'"
              :disabled="false"
              :multiple="item.showConfigJson.multiple || false"
              bizPath="signature"
              :record="row"
              :property="column.property"
              imgStyle="width:200px;height:40px;"
              v-model="row[column.property]"
              @setFieldValue="setSubFieldValue"
            />

            <ych-serialno
              v-else-if="item.slotEdit === 'serialno'"
              :disabled="true"
              :readOnly="true"
              :displayByText="true"
              :ruleCode="item.showConfigJson.ruleCode || 'default_rule'"
              :form="form"
              :record="row"
              :property="column.property"
              v-model="row[column.property]"
              @setFieldValue="setSubFieldValue"
            />

          </template>

        </vxe-column>
      </template>
      <vxe-column :title="$locale('m.common.label.operate')" width="120" v-if="actionButton && !disabled && treeEnable">
        <template #default="{ row }">
          <vxe-button type="text" status="primary" @click="handleClickAddByRow(row)">{{ $locale('m.common.button.add') }}
          </vxe-button>
          <vxe-button type="text" @click="handleRemoveRow(row)">{{ $locale('m.common.button.delete') }}</vxe-button>
        </template>
      </vxe-column>
    </vxe-table>
    <!--分页组件-->
    <vxe-pager v-if="isPage"
      align="center"
      size="mini"
      background
      :current-page="tablePage.currentPage"
      :page-size="tablePage.pageSize"
      :total="tablePage.totalResult"
      :page-sizes="[2,4,10,20,50,100]"
      :layouts="['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']"
      @page-change="handlePageChange"
    ></vxe-pager>
<!--    &lt;!&ndash;5why&ndash;&gt;-->
<!--    <sub-table-five-why-button-->
<!--        v-if="fiveShowFlag"-->
<!--        :item-detail="itemDetail"-->
<!--        :showConfigString="itemRow.showConfig"-->
<!--        :record="recordConfig"-->
<!--        @setFieldValue="setSubFieldValue"-->
<!--        :item-row="itemRow"-->
<!--        :row-number="rowNumber"-->
<!--        :columns="columns.filter(item => item.key === itemDetail.key)"-->
<!--        :data-source="dataSource"-->
<!--        :showModal="fiveShowFlag"-->
<!--        :disabled="false"-->
<!--        @close="fiveShowFlag = false"-->
<!--    />-->
    <!--    附件-->
    <sub-table-file-button
        v-if="fileShowFlag"
        :item-detail="itemDetail"
        :record="recordConfig"
        @setFieldValue="setSubFieldValue"
        :item-row="itemRow"
        :data-source="dataSource"
        :showModal="fileShowFlag"
        :disabled="false"
        @close="fileShowFlag = false"
    />
<!--    &lt;!&ndash;    脑图&ndash;&gt;-->
<!--    <sub-table-mind-button-->
<!--        v-if="mindShowFlag"-->
<!--        :item-detail="itemDetail"-->
<!--        :record="recordConfig"-->
<!--        @setFieldValue="setSubFieldValue"-->
<!--        :item-row="itemRow"-->
<!--        :data-source="dataSource"-->
<!--        :showModal="mindShowFlag"-->
<!--        :disabled="false"-->
<!--        @close="mindShowFlag = false"-->
<!--    />-->
<!--    &lt;!&ndash;    鱼骨图&ndash;&gt;-->
<!--    <sub-table-fish-button-->
<!--      v-if="fishShowFlag"-->
<!--      :item-detail="itemDetail"-->
<!--      :record="recordConfig"-->
<!--      @setFieldValue="setSubFieldValue"-->
<!--      :item-row="itemRow"-->
<!--      :data-source="dataSource"-->
<!--      :showModal="fishShowFlag"-->
<!--      :disabled="false"-->
<!--      @close="fishShowFlag = false"-->
<!--    />-->
    <view-select-modal
        ref="viewSelectModal"
        :multi="page.multi"
        :viewCode="page.viewCode"
        :rows="page.rows"
        :keys="page.keys"
        :labelField="page.labelField"
        :stores="stores"
        :hide-clear-but="true"
        @ok="handleSelectPageOK"/>

    <!--只在页面暂时存储 saveInPage=true-->
    <form-redirect-modal ref="form" @refreshParent="modalFormOk" :saveInPage="true"
                         :stores="stores"></form-redirect-modal>
  </div>
</template>

<script>

import Sortable from 'sortablejs'
import {uuid} from 'vue-uuid'
import {VALIDATE_NO_PASSED} from '../../utils/YchVxeTableUtil'
import SubTablePageButton from "../SubCompButton/SubTablePageButton";
import SubTableDeptButton from "../SubCompButton/SubTableDeptButton";
import SubTableUserButton from "../SubCompButton/SubTableUserButton";
// import SubTableFiveWhyButton from "@/views/eform/modules/designer/packages/SubTableFiveWhyButton";
import ViewFileSlot from '../../../packages/components/Common/ViewFileSlot'
import {handleCreateFunc, handleExecFunc} from '../../utils/actions'
import ViewSelectModal from "../../../packages/components/viewSelect/ViewSelectModal";
import moment from "moment";
import SubCheckTag from '../SubCompButton/SubCheckTag'
import {
  ajaxGetSqlConfigItems,
  ajaxGetHttpConfigItems,
  ajaxGetSqlConfigItemsBatch,
  ajaxGetHttpConfigItemsBatch
} from '../../utils/api/api';
import Signature from "../../Signature/signature";
import SubTableFileButton from "../../SubTableFileButton";
// import SubTableMindButton from "@/views/eform/modules/designer/packages/SubTableBaiduMindButton";
// import SubTableFishButton from "@/views/eform/modules/designer/packages/SubTableFishBoneButton/index.vue";
import YchSerialno from "../Common/YchSerialno.vue";
import LocleUtil from "../../utils/LocleUtil";
import common from "../../utils/common";
// import FormRedirectModal from "../redirect/FormRedirectModal.vue";


export default {
  name: "YchVxeTable",
  components: {
    // FormRedirectModal,
    // SubTableFishButton,
    // SubTableMindButton,
    SubTableFileButton,
    // SubTableFiveWhyButton,
    SubTablePageButton,
    SubTableDeptButton,
    SubTableUserButton,
    ViewFileSlot,
    ViewSelectModal,
    SubCheckTag,
    Signature,
    YchSerialno,
    FormRedirectModal: () => import('../redirect/FormRedirectModal.vue')
  },
  props: {
    // 所有配置数据
    recordConfig: {
      type: Object,
      default: () => {
      }
    },
    // 数据源
    dataSource: {
      type: Array,
      required: true,
      default: () => []
    },
    // 列信息
    columns: {
      type: Array,
      required: true,
      default: () => []
    },
    // 是否显示行号
    rowNumber: {
      type: Boolean,
      default: false
    },
    // 是否可选择行
    rowSelection: {
      type: Boolean,
      default: false
    },
    // 是否显示操作按钮
    actionButton: {
      type: Boolean,
      default: false
    },
    // 增删按钮配置
    actionButtonConfig: {
      type: Array,
      default: () => []
    },
    // 是否禁用全部组件
    disabled: {
      type: Boolean,
      default: false
    },
    // 是否可拖拽排序
    dragSort: {
      type: Boolean,
      default: false
    },
    // 排序关键字
    dragSortKey: {
      type: String,
      default: null
    },
    // 页面最大高度，auto表示铺满页面，-1表示不设置，auto好像没啥用
    height: {
      type: Number | String,
      default: 400
    },
    // 树形表格
    treeEnable: {
      type: Boolean,
      default: false
    },
    // 树父节点的字段名
    parentField: String,
    // 树节点字段
    treeNodeField: String,
    // 主键字段
    rowId: {
      type: String,
      default: "id"
    },
    // 新增行位置
    insertIndex: {
      type: Number,
      default: -1
    },
    // 表单对象
    form: {
      type: Object,
      default: () => {
      }
    },
    fks: {
      type: Array,
      default: () => []
    },
    parentLinkageMap: {
      type: Object,
      default: () => {
      }
    },
    stores: {
      type: Object,
      default: () => {
        return {}
      }
    },
    // 解决子表下拉框选项异步加载时不能回显的问题
    reloadDataFlg: {
      type: Boolean,
      default: false
    },
    isPage:  {
      type: Boolean,
      default: false
    }
  },
  inject: {
    getMainFormLoaded: {
      from: 'getMainFormLoaded',
      default: () => {
        return () => {}
      }
    },
  },
  computed: {
    columnsVxe() {
      this.linkages = []
      let result = this.columns.filter(item => item.type !== 'hidden').map(item => {
        const column = {...item}
        //合并表头
        column.showConfigJson = column.showConfig ? JSON.parse(column.showConfig) : {}

        if (column.disabled || this.initDisabled) {
          // 动态设置 this.disabled，导致重绘，有报错
          // if (column.disabled || this.disabled) {
          // 列禁用
          if (column.type === "select") {
            if (column.linkage) {
              // 把需要联动的控件记录下来
              this.linkages.push({
                linkage: column.linkage,
                column: column
              })
              // 如果是联动的情况，选项内容与数据有关，需要自定义
              column.formatter = this.formatterWithLinkagesOptions
            } else {
              column.formatter = this.formatterWithOptions
            }
          }
        } else {
          if (column.type === "textarea") {
            column.editRender = {
              name: 'textarea',
              events: {input: this.valueChangeInput, blur: this.valueChangeBlur},
              immediate: true
            }
            column.className = "ych-vxe-table-textarea"
          } else if (column.type === "input") {
            column.editRender = {
              name: 'input',
              events: {input: this.valueChangeInput, blur: this.valueChangeBlur},
              immediate: true
            }
          } else if (column.type === "inputNumber") {
            column.editRender = {
              name: 'input',
              attrs: {type: 'number'},
              events: {input: this.valueChangeInput, blur: this.valueChangeBlur},
              immediate: true
            }
          } else if (column.type === "select") {
            if (column.linkage) {
              // 把需要联动的控件记录下来
              this.linkages.push({
                linkage: column.linkage,
                column: column
              })
              // 如果是联动的情况，选项内容与数据有关，需要自定义
              column.editRender = {}
              column.formatter = this.formatterWithLinkagesOptions
              column.slotEdit = "select";
            } else {
              // 统一下拉框样式
              column.editRender = {}
              column.formatter = this.formatterWithOptions
              column.slotEdit = "select_default";
            }
          } else if (column.type === "radio") {
            column.editRender = {}
            column.slotEdit = "radio";
          } else if (column.type === "date") {
            column.editRender = {}
            column.slotEdit = "date";
          } else if (column.type === "datetime") {
            column.editRender = {}
            column.slotEdit = "datetime";
          } else if (column.type === "time") {
            column.editRender = {}
            column.slotEdit = "time";
          } else if (column.type === "user") {
            column.editRender = {}
            column.slotEdit = "user";

            const showConfigJson = column.showConfigJson
            if (showConfigJson.linkage) {
              // 把需要联动的控件记录下来
              this.linkages.push({
                linkage: showConfigJson.linkage,
                column: column
              })
              column.enableLinkage = true;
              column.linkage = showConfigJson.linkage
            }
          } else if (column.type === "dept") {
            column.editRender = {}
            column.slotEdit = "dept";
          } else if (column.type === "page") {
            column.editRender = {}
            column.slotEdit = "page";
          } else if (column.type === "fivewhy") {
            column.editRender = {}
            column.slotEdit = "fivewhy";
          } else if (column.type === "mind") {
            column.editRender = {}
            column.slotEdit = "mind";
          } else if (column.type === "fishbone") {
            column.editRender = {}
            column.slotEdit = "fishbone";
          } else if (column.type === "signature") {
            column.editRender = {}
            column.slotEdit = "signature";
          } else if (column.type === "serialno") {
            column.editRender = {}
            column.slotEdit = "serialno";
          }
        }

        // TODO 图片控件目前缺少编辑功能
        if (column.type === "file") {
          column.slotDefault = "file";
          column.editRender = {}
          column.showOverflow = false
        } else if (column.type === "user") {
          column.slotDefault = "user";

          const showConfigJson = column.showConfigJson
          if (showConfigJson.linkage) {
            column.enableLinkage = true;
            column.linkage = showConfigJson.linkage
          }
        } else if (column.type === "dept") {
          column.slotDefault = "dept";
        } else if (column.type === "page") {
          column.slotDefault = "page";
        } else if (column.type === "date") {
          column.slotDefault = "date";
          column.showOverflow = false;
          column.formatter = this.formatterWithDate
        } else if (column.type === "datetime") {
          column.formatter = this.formatterWithDatetime
        } else if (column.type === "time") {
          column.formatter = this.formatterWithTime
        } else if (column.type === "action") {
          column.slotDefault = "action";
        } else if (column.type === "radio") {
          column.slotDefault = "radio";
          column.showOverflow = false
        } else if (column.type === "textarea") {
          column.showOverflow = false
        } else if (column.type === "signature") {
          column.showOverflow = false
          column.slotDefault = "signature";
        } else if (column.type === "serialno") {
          column.slotDefault = "serialno";
        } else if (column.type === "fivewhy") {
          column.slotDefault = "fivewhy";
        } else if (column.type === "mind") {
          column.slotDefault = "mind";
        } else if (column.type === "fishbone") {
          column.slotDefault = "fishbone";
        }

        // 最小宽度 固定宽度
        if (column.width) {
          column.vxeMinWidth = column.width
        } else if (column.fixedWidth) {
          column.vxeWidth = column.fixedWidth
        }

        return column
      })
      result = this.mergeHeader(result)
      this.initLinkage++;
      return result;
    },
    validRules() {
      const result = {}
      this.columns.filter(item => item.type !== 'hidden').forEach(item => {
        if (item.validateRules) {
          result[item.key] = item.validateRules
        }
        if (item.validScript) {
          result[item.key] = result[item.key] || []
          result[item.key].push({
            validator: this.validScript
          })
        }
      })
      return result
    },
    addButton() {
      let result = null;
      if (this.actionButtonConfig && this.actionButtonConfig.length > 0) {
        result = this.actionButtonConfig.find(vo => vo.isDefault === 'Y')
      }
      if (!result) {
        result = {
          label: LocleUtil.getLocale('m.common.button.add'),
          openType: 'handleClickAdd',
          buttonIcon: 'plus',
          buttonStyle: 'primary',
        }
      }
      return result;
    },
    extButtons() {
      if (this.actionButtonConfig && this.actionButtonConfig.length > 0) {
        return this.actionButtonConfig.filter(vo => vo.isDefault !== 'Y')
      }
      return []
    },
    // 监听两个对象
    initLinkageFlg() {
      return {initLinkage: this.initLinkage, dataSource: this.dataSource}
    },
  },
  data() {
    return {
      tablePage: {
        currentPage: 1,
        pageSize: 10,
        totalResult: 0
      },
      //仅分页时有值
      dataSourceIdMap: {},
      //当前页数据
      currentDataSource: [],
      itemRow: {},
      itemDetail: {},
      sortable: null,
      fiveShowFlag: false,
      fileShowFlag: false,
      mindShowFlag: false,
      fishShowFlag: false,
      page: {
        multi: false,
        viewCode: null,
        rows: [],
        keys: [],
        labelField: null,
        fields: [],
      },
      // 动态设置 this.disabled，导致重绘，有报错
      initDisabled: this.disabled,
      linkages: [], // 需要联动的控件
      linkageChanged: {}, // 当前变化的控件
      linkagesOptions: {}, // 缓存联动下拉框的值，key是父控件标识_值
      initLinkage: 0, // 初始化联动选项
      linkageMap: {}, // 联动，非下拉框控件使用
    }
  },
  methods: {
    $locale(params) {
      return LocleUtil.getLocale(params)
    },
    // 处理分页
    handlePageChange({ currentPage, pageSize }) {
      this.tablePage.currentPage = currentPage;
      this.tablePage.pageSize = pageSize;
      //todo 临时列表处理
      this.resetCurrentDataSource();
    },
    //检查是否包含html标签
    checkHtml(htmlStr) {
      const reg = /<[^>]+>/g;
      return reg.test(htmlStr);
    },
    getFieldValueMethod(value) {
      this.$emit('change', value);
    },
    getDataSource() {
      return this.dataSource;
    },
    getColumns() {
      return this.columns;
    },
    validScript({cellValue, rule, rules, row, rowIndex, column, columnIndex}) {
      const validScript = this.columns.find(item => item.key === column.property).validScript
      const func = handleCreateFunc(validScript, this)
      const func_result = handleExecFunc(func, {cellValue, rule, rules, row, rowIndex, column, columnIndex})
      if (func_result && func_result !== true) {
        return new Error(func_result)
      }
    },
    async insertRow(formData, currRow) {
      const activeCell = null
      const $table = this.$refs.xTable
      const record = formData || this.getNewRow(currRow)
      const index = this.insertIndex;

      // 新增前事件
      if (this.recordConfig.options && this.recordConfig.options.beforeAdded) {
        const func = handleCreateFunc(this.recordConfig.options.beforeAdded, this)
        const func_result = handleExecFunc(func, {$table, record})
        if (func_result === false) {
          return
        }
      }

      if (this.treeEnable) {
        // 树行表格暂时不支持通过dataSource操作数据
        if (typeof index === "undefined" || index === null || index < 0) {
          await $table.insert(record)
        } else {
          await $table.insertAt(record, -1)
        }
        if (currRow) {
          await $table.setTreeExpand(currRow, true) // 将父节点展开
        }
      } else {
        if (typeof index === "undefined" || index === null || index >= this.dataSource.length || index < 0) {
          this.dataSource.push(record)
        } else {
          this.dataSource.splice(index, 0, record)
        }

        // TODO 暂时不支持新增后激活编辑的设置
        if (activeCell) {
          await $table.setActiveCell(record, activeCell)
        }
        this.$emit("added", record, this.dataSource)
      }
    },
    getNewRow(currRow) {
      const initData = {}
      this.columns.forEach(item => {
        initData[item.key] = item.defaultValue || null
      })
      let id = uuid.v1()
      const record = {
        ...initData
      }
      record[this.rowId] = id

      // 排序，判断规则保持和保存的规则一样
      if (!this.disabled && this.dragSortKey) {
        // if (this.dragSort && !this.treeEnable) {
        // } else {
        //   // 不允许拖拽排序的情况下，以排序字段顺序为准
        //   // 支持自增
        //   // 寻找最大值
        //   let sortValue = 0;
        //   this.dataSource.forEach(item => {
        //     const iSort1 = Number(item[this.dragSortKey]) || 0;
        //     if (iSort1 > sortValue) {
        //       sortValue = iSort1
        //     }
        //   })
        //   record[this.dragSortKey] = sortValue + 1
        // }

        let sortValue = 0;
        this.dataSource.forEach(item => {
          const iSort1 = Number(item[this.dragSortKey]) || 0;
          if (iSort1 > sortValue) {
            sortValue = iSort1
          }
        })
        record[this.dragSortKey] = sortValue + 1
      }

      if (this.treeEnable && this.parentField && currRow) {
        record[this.parentField] = currRow[this.rowId]
      }

      return record
    },
    async deleteRow({currRows}) {
      const $table = this.$refs.xTable
      let selectRecords = currRows
      if (!selectRecords) {
        selectRecords = $table.getCheckboxRecords()
        if (selectRecords.length === 0) {
          this.$message.warning(this.$locale('m.eform.formDesign.label.mei-you-xuan-zhong-shu-ju'))
          return
        }
      }

      // 删除前事件
      if (this.recordConfig.options && this.recordConfig.options.beforeDelete) {
        const func = handleCreateFunc(this.recordConfig.options.beforeDelete, this)
        const func_result = handleExecFunc(func, {$table, selectRecords})
        if (func_result === false) {
          return
        }
      }

      if (this.treeEnable) {
        // 树行表格暂时不支持通过dataSource操作数据
        await $table.remove(selectRecords)
      } else {
        const ids = selectRecords.map(item => item[this.rowId])
        for (let i = this.dataSource.length - 1; i >= 0; i--) {
          if (ids.indexOf(this.dataSource[i][this.rowId]) !== -1) {
            this.dataSource.splice(i, 1)
          }
        }
        this.$emit("deleted", ids, this.dataSource)
      }
    },
    valueChangeInput(e) {
      if (this.treeEnable) {
        // 树行表格暂时不支持通过dataSource操作数据
        return;
      }
      this.$emit("valueChange", e)
    },
    valueChangeSelect(e) {
      this.$refs.xTable.updateStatus(e)
      // 触发联动控件
      this.addLinkageChanged(e.column.property, e.row)

      if (this.treeEnable) {
        // 树行表格暂时不支持通过dataSource操作数据
        return;
      }
      this.$emit("valueChange", e)
    },
    valueChangeBlur(e) {
      // 触发联动控件
      this.addLinkageChanged(e.column.property, e.row)
    },
    valueChangeDate(row, column) {
      this.$refs.xTable.updateStatus({row: row, column: column})
      // 触发联动控件
      this.addLinkageChanged(column.property, row)

      if (this.treeEnable) {
        // 树行表格暂时不支持通过dataSource操作数据
        return;
      }
      // 模拟参数
      const e = {row: row, column: column}
      this.$emit("valueChange", e)
    },
    setSubFieldValue(key, value, record) {
      record[key] = value
      // keep-source
      // this.$refs.xTable.updateData()

      // 触发联动控件
      this.addLinkageChanged(key, record)

      if (this.treeEnable) {
        // 树行表格暂时不支持通过dataSource操作数据
        return;
      }

      //尝试更新数据
      for (let rowIndex in this.dataSource) {
        if (this.dataSource[rowIndex][this.rowId] === record[this.rowId]) {
          this.dataSource[rowIndex] = record;
          console.log(`尝试当前数据, rowId: ${this.rowId}, ${this.rowId}:  ${record[this.rowId]}`, record)
        }
      }

      // 模拟参数
      const e = {row: record, column: {property: key}}
      this.$emit("valueChange", e)
    },
    activeRowMethod({row, rowIndex, column, columnIndex}) {

      if (this.recordConfig.options && this.recordConfig.options.clickCell) {
        const func = handleCreateFunc(this.recordConfig.options.clickCell, this)
        const func_result = handleExecFunc(func, {row, rowIndex, column, columnIndex})
        if (func_result === false) {
          return false
        }
      }

      if (this.disabled) {
        this.$refs.xTable.clearActived()
        return false
      }
      return true;
    },
    rowDrop() {
      if (this.sortable !== null) {
        return
      }
      this.$nextTick(() => {
        const xTable = this.$refs.xTable
        this.sortable = Sortable.create(xTable.$el.querySelector('.body--wrapper>.vxe-table--body tbody'), {
          handle: '.drag-btn',
          onEnd: ({newIndex, oldIndex}) => {
            this.afterRowDrop(newIndex, oldIndex)
          }
        })
      })
    },
    afterRowDrop(newIndex, oldIndex) {
      //isPage新旧索引加上整体数据偏移量
      if (this.isPage) {
        const pageOffset = (this.tablePage.currentPage - 1) * this.tablePage.pageSize
        newIndex = pageOffset + newIndex
        oldIndex = pageOffset + oldIndex
      }

      const currRow = this.dataSource.splice(oldIndex, 1)[0]
      this.dataSource.splice(newIndex, 0, currRow)

      //序号重排
      if (this.dragSort && this.dragSortKey && !this.treeEnable) {
        let curSort = 0;
        if (newIndex > 0) {
          let preSort = Number.parseInt(this.dataSource[newIndex - 1][this.dragSortKey])
          if (!Number.isNaN(curSort)) {
            curSort = preSort;
          }
        }
        for (let loopIdx = newIndex; loopIdx < this.dataSource.length; loopIdx++) {
          ++curSort;
          this.dataSource[loopIdx][this.dragSortKey] = curSort;
        }
      }
    },
    formatterWithOptions({cellValue, row, column}) {
      const columnConfig = this.columnsVxe.find(item => item.key === column.property)
      const options = columnConfig.options || []
      const item = options.find(item => item.value === cellValue)
      return item ? item.label : ''
    },
    formatterWithLinkagesOptions({cellValue, row, column}) {
      // TODO 不知为何，每次增加数据都会调用一遍
      const columnConfig = this.columnsVxe.find(item => item.key === column.property)
      const options = (this.linkageValue(columnConfig.linkage, row) ? (this.linkagesOptions[this.linkageKey(columnConfig.linkage, row, column.property)] || []) : [])
      const item = options.find(item => item.value === cellValue)
      return item ? item.label : ''
    },
    formatterWithDate({cellValue, row, column}) {
      return cellValue ? moment(cellValue, "YYYY-MM-DD HH:mm:ss").format("YYYY-MM-DD") : cellValue
    },
    formatterWithDatetime({cellValue, row, column}) {
      return cellValue
    },
    formatterWithTime({cellValue, row, column}) {
      return cellValue
    },
    getAll() {
      return new Promise(async (resolve, reject) => {
        let dataSource;
        if (this.treeEnable) {
          // 树行表格暂时不支持通过dataSource操作数据
          const {visibleData} = await this.$refs.xTable.getTableData()
          dataSource = visibleData
        } else {
          dataSource = this.dataSource
        }
        const values = await this.getTableDataSource(this.$refs.xTable, dataSource);
        if (values === false) {
          // 返回空，终止保存动作
          reject(VALIDATE_NO_PASSED)
        } else {
          resolve({values})
        }
      })
    },
    async getTableDataSource($table, dataSource) {
      let errMap = false
      //分页时如果本页无错误额外检查
      if (!this.isPage) {
        errMap = await $table.fullValidate(true).catch(errMap => errMap)
      } else {
        errMap = await $table.fullValidate(dataSource).catch(errMap => errMap)
        //处理序号--提示信息修正
        if (errMap) {
          Object.values(errMap).forEach(errList => {
            errList.forEach(params => {
              params.rowIndex = Number.parseInt(this.dataSourceIdMap[params.row[this.rowId]])
            })
          })
        }
      }

      if (errMap) {
        const msgList = []
        Object.values(errMap).forEach(errList => {
          errList.forEach(params => {
            const {rowIndex, column, rules} = params
            rules.forEach(rule => {
              msgList.push(this.$locale('m.eform.formDesign.label.vxe_error', [rowIndex + 1, column.title, rule.message]))
            })
          })
        })
        // this.$message.warning({
        //   icon: () => {
        //     return null
        //   },
        //   content: (
        //     <div style="color: red; max-hclassName: 400px; overflow: auto;">
        //       {
        //         msgList.map((msg, index) => index < 10 ? <div>{msg}</div> : (index === 10 ? <div>{'...'}</div> : ''))
        //       }
        //     </div>
        //   )
        // })
        return false
      } else {
        // 排序
        if (!this.disabled && this.dragSortKey) {
          // 树行表格暂时不支持通过dataSource操作数据
          if (this.dragSort && !this.treeEnable) {
            // 允许拖拽排序的情况下，以拖拽顺序为准
            dataSource.forEach((item, index) => {
              item[this.dragSortKey] = index + 1
            })
          } else {
            // 不允许拖拽排序的情况下，以排序字段顺序为准
            for (let j = 0; j < dataSource.length - 1; j++) {
              for (let i = 0; i < dataSource.length - 1 - j; i++) {
                const iSort1 = Number(dataSource[i][this.dragSortKey]) || 0;
                const iSort2 = Number(dataSource[i + 1][this.dragSortKey]) || 0;
                if (iSort1 > iSort2) {
                  let tmp = dataSource[i]
                  dataSource[i] = dataSource[i + 1]
                  dataSource[i + 1] = tmp
                }
              }
            }
          }
        }
        if (this.treeEnable) {
          // 树行表格，保存数据时去掉children对象
          dataSource.forEach((item) => {
            delete item.children
            delete item['_X_ROW_CHILD']
          })
        }
        return dataSource
      }
    },
    handleClickAdd() {
      this.insertRow()
    },
    handleClickAddByRow(currRow) {
      this.insertRow(null, currRow)
    },
    handleRemoveRow(currRow) {
      const currRows = [currRow]
      this.deleteRow({currRows})
    },
    //文件，脑图，5why,鱼骨图
    clickItemSlot(row, rowIndex, column, columnIndex, item, type) {
      this.itemRow = row;
      this.itemDetail = item;
      const obj = {
        fivewhy: 'fiveShowFlag',
        file: 'fileShowFlag',
        mind: 'mindShowFlag',
        fishbone: 'fishShowFlag',
      };
      console.log(obj[type], 'obj[type]')
      if (this.recordConfig.options && this.recordConfig.options.clickCell) {
        const func = handleCreateFunc(this.recordConfig.options.clickCell, this)
        const func_result = handleExecFunc(func, {row, rowIndex, column, columnIndex})
        console.log(func_result, 'func_result')
        if (func_result) {
          setTimeout(() => {
            this[obj[type]] = true;
          }, 500);
        }
      } else {
        setTimeout(() => {
          this[obj[type]] = true;
        }, 500);
      }
    },
    getFileName(row, item) {
      const value = row[item.key];
      if (value == "[]" || value == "null" || value == "undefined" || !value) {
        return '无附件'
      }
      return item.defaultValue == row[item.key] ? '无附件' : '查看附件';
    },
    callFn(button, record, item) {
      if (!button && item && item.actionConfig) {
        button = JSON.parse(item.actionConfig)
      }
      if (button) {
        this[button.openType].apply(this, [button, record])
      }
    },
    handleAddByPage(button) {
      const buttonConfig = button.buttonConfig ? JSON.parse(button.buttonConfig) : {}
      this.page = {
        multi: buttonConfig.multiple || false,
        viewCode: buttonConfig.viewCode || null,
        rows: [],
        keys: [],
        labelField: null,
        fields: buttonConfig.fields || [],
      };
      let parameterValue = [];
      if (buttonConfig.parameterConfig && this.form) {
        let success = true;
        parameterValue = buttonConfig.parameterConfig.map(item => {
          let value = null;
          if (item.outKey) {
            value = this.form.getFieldValue(item.outKey)
          }
          if (!value && item.defaultValue) {
            value = item.defaultValue
          }
          if (!value && item.isRequired) {
            this.$message.warning(item.customMessage || this.$locale('m.eform.formDesign.label.Not_allowed_to_be_empty', [item.parameterKey]))
            success = false
          }
          return {
            colCode: item.parameterKey,
            queryValue: value
          }
        })
        if (!success) {
          return
        }
      }
      this.$refs.viewSelectModal.show(parameterValue)
    },
    handleSelectPageOK(rows) {
      if (this.treeEnable) {
        // 树行表格暂时不支持通过dataSource操作数据
        return;
      }
      const that = this;
      if (rows && rows.length > 0 && this.page.fields && this.page.fields.length > 0) {
        rows.forEach(row => {
          const item = that.getNewRow()
          that.page.fields.forEach(field => {
            if (!field.from || !field.to) {
              return
            }
            item[field.to] = row[field.from]
          })
          // 1.只适用于电子表单
          // 2.没有处理默认值
          that.dataSource.push(item)

          that.$emit("added", item)
        })
        this.$emit("setDataSource", this.dataSource, true)
      }
    },
    handleAddByForm(button) {
      const buttonConfig = button.buttonConfig ? JSON.parse(button.buttonConfig) : {}
      const formCode = buttonConfig.formCode;
      if (!formCode) {
        this.$message.warning(this.$locale('m.eform.formDesign.label.mei-you-pei-zhi-guan-lian-biao-dan'))
        return
      }
      let values = {};
      if (this.form) {
        values = this.form.getFieldsValue()
      }
      if (this.allDataSource && this.allDataSource.id) {
        values.id = this.allDataSource.id
      }
      const fks = [];
      this.$refs.form.add(formCode, fks, values, buttonConfig.dialogSize)
    },
    handleExt(button) {
      const buttonConfig = (button.buttonConfig && button.buttonConfig !== '') ? JSON.parse(button.buttonConfig) : {}
      if (!buttonConfig.openScript) {
        this.$message.warning(this.$locale('m.eform.formDesign.label.mei-you-pei-zhi-zi-ding-yi-jiao-ben'))
      }
      const openScript = handleCreateFunc(buttonConfig.openScript, this)
      handleExecFunc(openScript, {button, buttonConfig})
    },
    handleEdit(button, record) {
      const formCode = button.formCode
      if (!formCode) {
        this.$message.warning(this.$locale('m.eform.formDesign.label.mei-you-pei-zhi-guan-lian-biao-dan'))
        return
      }
      let id = record.id;
      if (button.beforeScript) {
        const _that = this;
        const func = handleCreateFunc(button.beforeScript, this)
        const func_result = handleExecFunc(func, {button, record, id, formCode}, function () {
          _that.handleEditCallback(button, id, formCode, record)
        })
        if (!func_result) return;
      }
      this.handleEditCallback(button, id, formCode, record)
    },
    handleEditCallback(button, id, formCode, record) {
      this.$refs.form.edit(id, formCode, button.dialogSize, true, record)
      if (button.afterScript) {
        const func = handleCreateFunc(button.afterScript, this)
        handleExecFunc(func, {button, record})
      }
    },
    handleDetail(button, record) {
      const formCode = button.formCode
      if (!formCode) {
        this.$message.warning(this.$locale('m.eform.formDesign.label.mei-you-pei-zhi-guan-lian-biao-dan'))
        return
      }
      let id = record.id;
      if (button.beforeScript) {
        const _that = this;
        const func = handleCreateFunc(button.beforeScript, this)
        const func_result = handleExecFunc(func, {button, record, id, formCode}, function () {
          _that.handleDetailCallback(button, id, formCode, record)
        })
        if (!func_result) return;
      }
      this.handleDetailCallback(button, id, formCode, record)
    },
    handleDetailCallback(button, id, formCode, record) {
      this.$refs.form.detail(id, formCode, button.dialogSize, true, record)
      if (button.afterScript) {
        const func = handleCreateFunc(button.afterScript, this)
        handleExecFunc(func, {button, record})
      }
    },
    modalFormOk(id, tableName, formData) {
      if (this.treeEnable) {
        // 树行表格暂时不支持通过dataSource操作数据
        return;
      }
      // 刷新整个表单
      // this.$emit("refreshAllData")
      // 只在页面存储
      const key = Object.keys(formData)[0];
      const values = formData[key]
      if (id) {
        // 编辑
        const data = this.dataSource.find(vo => vo.id === id);
        Object.assign(data, values)
      } else {
        // 新增
        const record = this.getNewRow()
        Object.assign(record, values)
        this.insertRow(record)
      }
    },
    getRowStyle({row, rowIndex, $rowIndex}) {
      if (this.recordConfig.options && this.recordConfig.options.setRowStyle) {
        const func = handleCreateFunc(this.recordConfig.options.setRowStyle, this)
        const func_result = handleExecFunc(func, {row, rowIndex, $rowIndex})
        return func_result || {};
      }
      return {}
    },
    getCellStyle({row, rowIndex, $rowIndex, column, columnIndex, $columnIndex}) {
      if (this.recordConfig.options && this.recordConfig.options.setCellStyle) {
        const func = handleCreateFunc(this.recordConfig.options.setCellStyle, this)
        const func_result = handleExecFunc(func, {row, rowIndex, $rowIndex, column, columnIndex, $columnIndex})
        return func_result || {};
      }
      return {}
    },
    mergeRowMethod({row, _rowIndex, column, visibleData}) {
      if (this.recordConfig.options && this.recordConfig.options.spanMethod) {
        const func = handleCreateFunc(this.recordConfig.options.spanMethod, this)
        const func_result = handleExecFunc(func, {row, _rowIndex, column, visibleData})
        return func_result || {};
      }
      return {}
    },
    updateBySqlCode(showConfigJson, parameter, key) {
      // 入参
      if (showConfigJson.sqlConfig.sqlParameterConfig && showConfigJson.sqlConfig.sqlParameterConfig.length > 0) {
        showConfigJson.sqlConfig.sqlParameterConfig.forEach(item => {
          let value = null;
          if (item.outKey) {
            if (this.linkageChanged.columnRow && typeof this.linkageChanged.columnRow[item.outKey] !== "undefined") {
              value = this.linkageChanged.columnRow[item.outKey]
            } else if (this.form) {
              value = this.form.getFieldValue(item.outKey)
            }
          }
          if (!value && item.defaultValue) {
            value = item.defaultValue
          }
          if (value) {
            parameter[item.parameterKey] = value
          }
        })
      }

      ajaxGetSqlConfigItems(showConfigJson.sqlConfig.sqlCode, parameter).then((res) => {
        if (res.success) {
          this.updateOptions(res.result, showConfigJson.formatExpr, key)
        }
      })
    },
    updateByHttpCode(showConfigJson, parameter, key) {
      ajaxGetHttpConfigItems(showConfigJson.httpConfig.httpCode, parameter).then((res) => {
        if (res.success) {
          this.updateOptions(res.result, showConfigJson.formatExpr, key)
        }
      })
    },
    updateOptions(result, formatExpr, key) {
      this.linkagesOptions[key] = result
      common.formatOptionsByExpr(formatExpr, this.linkagesOptions[key])
    },
    addLinkageChanged(columnKey, columnRow) {
      // 触发联动控件
      this.linkageChanged = {
        columnKey: columnKey,
        columnRow: columnRow
      }
    },
    linkageValue(linkage, columnRow) {
      const result = {}
      let hasValue = false
      linkage.split(",").forEach(key => {
        result[key] = columnRow[key] !== undefined ? columnRow[key] : this.parentLinkageMap[key]
        if (result[key] !== undefined && result[key] !== null && result[key] !== "") {
          hasValue = true
        }
      })
      return hasValue ? result : null
    },
    linkageKey(linkage, columnRow, property) {
      let result = ""
      linkage.split(",").forEach(key => {
        const value = columnRow[key] !== undefined ? columnRow[key] : this.parentLinkageMap[key]
        result += (key + "_" + property + "_" + (value ? value : 'null') + "_")
      })
      return result
    },
    reloadData() {
      if (this.isPage) {
        this.$nextTick(() => {
          this.$refs.xTable.reloadData(this.currentDataSource)
        })
      } else {
        this.$nextTick(() => {
          this.$refs.xTable.reloadData(this.dataSource)
        })
      }
    },
    resetCurrentDataSource() {
      this.tablePage.totalResult = this.dataSource.length;

      let startIdx = (this.tablePage.currentPage - 1) * this.tablePage.pageSize;
      let endIdx = startIdx + this.tablePage.pageSize;
      endIdx = Math.min(endIdx, this.dataSource.length)

      let currentDataSource = [];
      for (let curIdx = startIdx; curIdx < endIdx; curIdx ++) {
        currentDataSource.push(this.dataSource[curIdx]);
      }

      this.currentDataSource = currentDataSource;
    },
    reCalcDataSourceIdMap() {
      const dataSourceIdMap = {};
      this.dataSource.forEach((item, idx) => {
        dataSourceIdMap[item[this.rowId]] = idx
      })
      this.dataSourceIdMap = dataSourceIdMap;
    },
    seqMethod({ row, rowIndex, column }) {
      if (this.isPage) {
        return `${(this.tablePage.currentPage - 1) * this.tablePage.pageSize + rowIndex + 1}`;
      } else {
        return `${rowIndex + 1}`;
      }
    },
    mergeHeader(columns) {
      //合并表头处理
      let mergeHeaderNameMap = new Map
      let columnIndex = 0
      let mergeCount = 0
      columns.forEach(item => {
          if (item.mergeHeaderName) {
            if (!mergeHeaderNameMap.has(item.mergeHeaderName)) {
              let mergeObj = {
                index: columnIndex + mergeCount,
                title: this.$locale(item.mergeHeaderName),
                children: []
              }
              mergeObj.children.push(item)
              mergeHeaderNameMap.set(item.mergeHeaderName, mergeObj)
              mergeCount++
            } else {
              mergeHeaderNameMap.get(item.mergeHeaderName).children.push(item)
            }
          }
          columnIndex++
        }
      )

      if (mergeHeaderNameMap.size > 0) {
        let newColumns = columns
        mergeHeaderNameMap.forEach(item => {
          newColumns.splice(item.index, 0, item)
        })
        return newColumns.filter(item => !(item.mergeHeaderName && item.mergeHeaderName.length > 0))
      } else {
        return columns
      }
    },
  },
  created() {
    // if (this.isPage) {
    //   this.reCalcDataSourceIdMap();
    //   this.resetCurrentDataSource();
    // }
  },
  mounted() {
    // 树行表格暂时不支持通过dataSource操作数据
    if (this.dragSort && !this.disabled && !this.treeEnable) {
      this.rowDrop()
    }
  },
  beforeDestroy() {
    if (this.sortable) {
      this.sortable.destroy()
      this.sortable = null
    }
  },
  watch: {
    // 解决子表下拉框选项异步加载时不能回显的问题
    reloadDataFlg: {
      handler(value) {
        if (value) {
          this.reloadData()
          this.$emit("update:reloadDataFlg", false)
        }
      },
      immediate: false
    },
    // 动态设置 this.disabled，导致重绘，有报错
    // 允许从不可编辑变为可编辑，不允许从可编辑变为不可编辑
    disabled: {
      handler(value) {
        if (!value) {
          this.initDisabled = value
        }
      },
      immediate: false
    },
    parentLinkageMap: {
      async handler() {
        // 初始化联动选项
        const sqlConfig = []
        const httpConfig = []
        this.dataSource.forEach(columnRow => {
          this.linkages.forEach(item => {
            const showConfigJson = JSON.parse(item.column.showConfig)

            if (item.column.type === "select") {

              const linkageValue = this.linkageValue(item.linkage, columnRow)

              const parameter = {}
              if (linkageValue) {
                const key = this.linkageKey(item.linkage, columnRow, item.column.key);
                if (!this.linkagesOptions[key]) {
                  this.linkagesOptions[key] = []
                  Object.assign(parameter, linkageValue)
                  if (showConfigJson.sqlConfig) {

                    // 入参
                    if (showConfigJson.sqlConfig.sqlParameterConfig && showConfigJson.sqlConfig.sqlParameterConfig.length > 0) {
                      showConfigJson.sqlConfig.sqlParameterConfig.forEach(item => {
                        let value = null;
                        if (item.outKey) {
                          if (columnRow && typeof columnRow[item.outKey] !== "undefined") {
                            value = columnRow[item.outKey]
                          } else if (this.form) {
                            value = this.form.getFieldValue(item.outKey)
                          }
                        }
                        if (!value && item.defaultValue) {
                          value = item.defaultValue
                        }
                        if (value) {
                          parameter[item.parameterKey] = value
                        }
                      })
                    }

                    sqlConfig.push({
                      formatExpr: showConfigJson.formatExpr,
                      sqlCode: showConfigJson.sqlConfig.sqlCode,
                      parameter: parameter,
                      key: key
                    })
                  } else if (showConfigJson.httpConfig) {
                    httpConfig.push({
                      formatExpr: showConfigJson.formatExpr,
                      httpCode: showConfigJson.httpConfig.httpCode,
                      httpConfig: showConfigJson.httpConfig,
                      parameter: parameter,
                      key: key
                    })
                  }
                } else {
                  // 被联动的控件，如果在新选项中存在，则不需要清空，直接返回
                  const cellValue = columnRow[item.column.key]
                  if (cellValue) {
                    const cellOption = this.linkagesOptions[key].find(option => option.value === cellValue)
                    if (cellOption) {
                      return
                    }
                  }
                }
              }
              // 清空当前值 判断是初始化不需要清空
              if(this.getMainFormLoaded()){
                columnRow[item.column.key] = null
              }
            } else if (item.column.type === "user") {
              const linkageValue = columnRow[item.linkage]
              const id = columnRow[this.rowId]
              const key = item.linkage + '_' + id;
              this.linkageMap[key] = linkageValue;
            }
          })
        })

        this.linkageMap = {...this.linkageMap}

        if (sqlConfig.length > 0) {
          const res = await ajaxGetSqlConfigItemsBatch(sqlConfig)
          if (res.success) {
            res.result.forEach(item => {
              this.updateOptions(item.options, item.formatExpr, item.key);
            })
          }
        }

        if (httpConfig.length > 0) {
          const res = await ajaxGetHttpConfigItemsBatch(httpConfig)
          if (res.success) {
            res.result.forEach(item => {
              this.updateOptions(item.options, item.formatExpr, item.key);
            })
          }
        }
        if (sqlConfig.length > 0 || httpConfig.length > 0) {
          this.$refs.xTable.reloadData(this.dataSource)
        }
      }
    },
    // 初始化联动选项
    initLinkageFlg: {
      async handler() {
        // 初始化联动选项
        const sqlConfig = []
        const httpConfig = []
        this.dataSource.forEach(columnRow => {
          this.linkages.forEach(item => {
            const showConfigJson = JSON.parse(item.column.showConfig)

            if (item.column.type === "select") {

              const linkageValue = this.linkageValue(item.linkage, columnRow)

              const parameter = {}
              if (linkageValue) {
                const key = this.linkageKey(item.linkage, columnRow, item.column.key);
                if (!this.linkagesOptions[key]) {
                  this.linkagesOptions[key] = []
                  Object.assign(parameter, linkageValue)
                  if (showConfigJson.sqlConfig) {

                    // 入参
                    if (showConfigJson.sqlConfig.sqlParameterConfig && showConfigJson.sqlConfig.sqlParameterConfig.length > 0) {
                      showConfigJson.sqlConfig.sqlParameterConfig.forEach(item => {
                        let value = null;
                        if (item.outKey) {
                          if (columnRow && typeof columnRow[item.outKey] !== "undefined") {
                            value = columnRow[item.outKey]
                          } else if (this.form) {
                            value = this.form.getFieldValue(item.outKey)
                          }
                        }
                        if (!value && item.defaultValue) {
                          value = item.defaultValue
                        }
                        if (value) {
                          parameter[item.parameterKey] = value
                        }
                      })
                    }

                    sqlConfig.push({
                      formatExpr: showConfigJson.formatExpr,
                      sqlCode: showConfigJson.sqlConfig.sqlCode,
                      parameter: parameter,
                      key: key
                    })
                  } else if (showConfigJson.httpConfig) {
                    httpConfig.push({
                      formatExpr: showConfigJson.formatExpr,
                      httpCode: showConfigJson.httpConfig.httpCode,
                      httpConfig: showConfigJson.httpConfig,
                      parameter: parameter,
                      key: key
                    })
                  }
                }
              }
            } else if (item.column.type === "user") {
              const linkageValue = columnRow[item.linkage]
              const id = columnRow[this.rowId]
              const key = item.linkage + '_' + id;
              this.linkageMap[key] = linkageValue;
            }
          })
        })

        this.linkageMap = {...this.linkageMap}

        if (sqlConfig.length > 0) {
          const res = await ajaxGetSqlConfigItemsBatch(sqlConfig)
          if (res.success) {
            res.result.forEach(item => {
              this.updateOptions(item.options, item.formatExpr, item.key);
            })
          }
        }

        if (httpConfig.length > 0) {
          const res = await ajaxGetHttpConfigItemsBatch(httpConfig)
          if (res.success) {
            res.result.forEach(item => {
              this.updateOptions(item.options, item.formatExpr, item.key);
            })
          }
        }
        if (sqlConfig.length > 0 || httpConfig.length > 0) {
          this.$refs.xTable.reloadData(this.dataSource)
        }
      }
    },
    // 触发联动控件
    linkageChanged: {
      handler() {
        this.linkages.forEach(item => {
          if (item.linkage.split(",").indexOf(this.linkageChanged.columnKey) !== -1) {
            const showConfigJson = JSON.parse(item.column.showConfig)

            if (item.column.type === "select") {

              const linkageValue = this.linkageValue(item.linkage, this.linkageChanged.columnRow)

              const parameter = {}

              // 如果要空值查询，需要改造这里
              if (linkageValue) {
                const key = this.linkageKey(item.linkage, this.linkageChanged.columnRow, item.column.key);
                if (!this.linkagesOptions[key]) {
                  this.linkagesOptions[key] = []
                  Object.assign(parameter, linkageValue)
                  if (showConfigJson.sqlConfig) {
                    this.updateBySqlCode(showConfigJson, parameter, key)
                  } else if (showConfigJson.httpConfig) {
                    parameter.httpConfig = showConfigJson.httpConfig
                    this.updateByHttpCode(showConfigJson, parameter, key)
                  }
                } else {
                  // 被联动的控件，如果在新选项中存在，则不需要清空，直接返回
                  const cellValue = this.linkageChanged.columnRow[item.column.key]
                  if (cellValue) {
                    const cellOption = this.linkagesOptions[key].find(option => option.value === cellValue)
                    if (cellOption) {
                      return
                    }
                  }
                }
              }
              // 清空当前值
              this.linkageChanged.columnRow[item.column.key] = null
              // 触发联动控件
              this.addLinkageChanged(item.column.key, this.linkageChanged.columnRow)
            } else if (item.column.type === "user") {
              const linkageValue = this.linkageChanged.columnRow[item.linkage]
              const id = this.linkageChanged.columnRow[this.rowId]
              const key = item.linkage + '_' + id;
              this.linkageMap = {...this.linkageMap}
              this.linkageMap[key] = linkageValue;
              // 清空当前值
              this.linkageChanged.columnRow[item.column.key] = null
            }
          }
        })
      }
    },
    //主数据变化 更新 当前数据
    dataSource: {
      handler(value) {
        if (this.isPage) {
          this.reCalcDataSourceIdMap();
          this.resetCurrentDataSource();
        }
      },
      immediate: true
    }
  }
};
</script>
<style>
.ych-vxe-table-textarea .vxe-default-textarea {
  height: 200px !important;
  margin: 10px 0;
}
</style>
