<template>
  <div
    style="height: 100%"
    :style="{
      minHeight: !tableMaxHeight && '400px',
      maxHeight: customTableMaxHeight && customTableMaxHeight + 'px',
    }"
  >
    <el-container
      v-if="customDialogShowList"
      style="height: 100%"
      :style="{
        minHeight: !tableMaxHeight && '400px',
      }"
      class="custom-container"
    >
      <el-main>
        <ht-table
          ref="htTable"
          :data="dialogData"
          stripe
          border
          style="width: 100%"
          header-cell-class-name="todo-header-row"
          row-class-name="todo-row"
          size="small"
          :show-export="false"
          :selectable="false"
          :nopagination="true"
          :is-data-template-list="true"
          :autofocus="autofocus"
          :is-load-table="false"
          :custom-table-max-height="tableMaxHeight"
          @loading="loadData"
        >
          <template v-slot:toolbar>
            <div class="top_btn_col">
              <el-button type="primary" size="small" icon="" @click="exports()">
                导出
              </el-button>
              <el-button
                v-for="(item, $index) in toolButtons"
                :key="$index"
                size="small"
                :type="item.type"
                @click="toolButtonClick(item.func, item)"
              >
                {{ item.text }}
              </el-button>
            </div>
          </template>
          <template v-slot:search>
            <ht-table-search-panel
              v-if="querysShow"
              ref="searchPanel"
              :divide="6"
              :label-width="100"
              :is-flex-layout="false"
              :style="{
                '--searchPanelWidth': `${middleWidth}px`,
                'margin-top': '15px',
                'margin-bottom': '10px',
              }"
              :tool-buttons="toolButtons"
              :show-export="true"
              @exports="exports"
              @toolButtonClick="toolButtonClick"
              @submit.native.prevent
              @application-search="
                (val) => {
                  search(true, val)
                }
              "
            >
              <ht-table-search-field
                v-for="(item, $index) in conditionBind"
                :key="$index"
                :type="item.type"
                :label="item.comment"
                :value-format="
                  item.dbType == 'date' || item.controllerType == '15'
                    ? 'yyyy-MM-dd HH:mm:ss'
                    : item.controllerType == '16'
                    ? 'yyyy-MM-dd'
                    : ''
                "
                :format="
                  item.dbType == 'date' || item.controllerType == '15'
                    ? 'yyyy-MM-dd HH:mm:ss'
                    : item.controllerType == '16'
                    ? 'yyyy-MM-dd'
                    : ''
                "
                :prop="item.field"
                :config="item.config"
                :operation="getOperation(item.condition)"
              />
            </ht-table-search-panel>
          </template>
          <ht-table-column
            v-if="customDialog.selectNum !== 1"
            type="selection"
            align="center"
            reserve-selection
            width="55"
          ></ht-table-column>
          <ht-table-column
            type="index"
            width="50"
            align="center"
            label="序号"
          ></ht-table-column>
          <ht-table-column
            v-for="field in displayfield"
            :key="field.field"
            :show-overflow-tooltip="true"
            :prop="field.field"
            :label="field.comment"
            :width="field.width"
          ></ht-table-column>
          <ht-table-column v-if="columnButtons.length" label="操作" width="160">
            <template slot-scope="scope">
              <el-button
                v-for="(button, index) in columnButtons"
                :key="index"
                icon="button.icon"
                plain
                @click="columnBtnClick(button.func, scope.row, button)"
              >
                {{ button.text }}
              </el-button>
            </template>
          </ht-table-column>
        </ht-table>
      </el-main>
      <el-footer height="45px">
        <el-row type="flex" justify="end">
          <el-pagination
            v-if="customDialog.needPage"
            background
            :current-page="pagination.page"
            :page-sizes="[10, 20, 30, 50, 100]"
            :page-size="pagination.pageSize"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          ></el-pagination>
        </el-row>
      </el-footer>
    </el-container>
    <el-dialog
      id="exportDialogs"
      title="导出设置"
      :visible.sync="dialogExportVisible"
      width="750px"
      :before-close="exportCancel"
    >
      <el-form
        ref="exportData"
        :model="exportData"
        status-icon
        label-width="100px"
      >
        <el-row
          type="flex"
          class="row-bg"
          justify="start"
          style="height: 48px; border: 1px solid #eee; text-align: center"
        >
          <el-col :span="4" style="padding: 15px 0px 0px 15px">导出类型</el-col>
          <el-col
            :span="20"
            style="border-left: 1px solid #eee; padding: 15px 0px 0px 15px"
          >
            查询结果
          </el-col>
        </el-row>
        <el-row
          type="flex"
          class="row-bg"
          justify="start"
          style="border: 1px solid #eee; text-align: center"
        >
          <el-col :span="4" style="padding: 15px 0px 0px 15px">导出字段</el-col>
          <el-col
            :span="20"
            style="
              border-left: 1px solid #eee;
              padding: 5px 0px 0px 5px;
              max-height: 420px;
              overflow: auto;
            "
          >
            <ht-table
              ref="multipleExportTable"
              :data="displayfield"
              style="width: 100%"
              tooltip-effect="dark"
              :custom-table-height="370"
              :nopagination="true"
              :autofocus="false"
            >
              <ht-table-column
                prop="field"
                label="字段名称"
                width="130"
              ></ht-table-column>
              <ht-table-column
                prop="comment"
                label="字段描述"
                width="180"
              ></ht-table-column>
              <ht-table-column label="操作" width="160">
                <template slot-scope="scope">
                  <el-button
                    icon="el-icon-arrow-down"
                    plain
                    @click="sortExport(scope.index, 'down')"
                  ></el-button>
                  <el-button
                    icon="el-icon-arrow-up"
                    plain
                    @click="sortExport(scope.index, 'up')"
                  ></el-button>
                </template>
              </ht-table-column>
            </ht-table>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="exportCancel()">取 消</el-button>
        <el-button type="primary" @click="submitExport()">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
  import $ from 'jquery'
  import utils from '@/utils.js'
  import locale from '@/mixins/locale.js'
  import permission from '@/mixins/permission.js'
  import inputName from '@/mixins/inputName.js'
  import form from '@/mixins/form.js'
  import dialog from './customDialog.js'
  import CustomQuery from '@/services/CustomQuery'
  const { Base64 } = require('js-base64')
  import _ from 'lodash'
  export default {
    name: 'CustomDialog',
    components: {},
    mixins: [dialog, locale, inputName, permission, form],
    props: {
      custdialog: {
        type: Object,
        default: () => {
          return {}
        },
      },
      value: String,
      subIndex: Number,
      sunIndex: Number,
      subPath: String,
      currentSubData: Array,
      modelName: String,
      //唯一标识字段
      primaryField: {
        type: String,
        default: '',
      },
      isSubtableBackfill: {
        type: Boolean,
        default: false,
      },
      isPreview: {
        type: Boolean,
        default: false,
      },
      toolButtons: {
        type: Array,
        default: () => [],
      },
      columnButtons: {
        type: Array,
        default: () => [],
      },
      queryBindOptions: {
        type: Object,
        default: null,
      },

      tableMaxHeight: {
        type: [Number, String],
        default: '',
      },
    },
    data() {
      return {
        dialogVisible: false, //打开树形输入动态参数值的对话框
        data: {
          qxdd: {},
        },
        quickSearch: '', //填写提示
        conditionBind: [], //参数查询字段
        nodeKey: 'ID_', //树形数据父Id
        customDialogShowList: false,
        style: '', //对话框宽高
        selectOrgs: [],
        displayfield: [], //显示字段
        customDialog: {},
        queryParam: '', //查询条件输入的值
        showData: [],
        checkBoxDataAll: [], //选中对象的集合
        propsData: [],
        querysShow: false, //是否显示搜索框
        tableRadioVal: '',
        param: [], //绑定的表单字段
        displayField: {},
        queryParams: [],
        placeholders: [],
        combinationTreeQuerys: [],
        combinationRule: {},
        transtionWidth: 300,
        writeable: true,
        fixedParams: {}, // 传过来的固定值
        executeScriptResult: null,
        selects: [],
        fromKey: '',
        fixedQuerys: [],
        dialogExportVisible: false,
        exportData: { getType: 'all', expField: [] },
        conditionValueMap: {},
      }
    },
    computed: {
      //默认展开的节点的 key 的数组
      defaultExpandedKeys: function () {
        return []
      },
      middleWidth() {
        if (this.customDialog.style == 2 && this.isSetPk == '') {
          return this.customDialog.width - 300 - 25
        } else if (this.isSetPk !== '' && this.customDialog.style != 2) {
          return this.customDialog.width - this.transtionWidth - 25
        } else if (this.customDialog.style == 2 && this.isSetPk !== '') {
          return this.customDialog.width - 300 - this.transtionWidth - 25
        } else {
          return this.customDialog.width - 45
        }
      },
      isSetPk() {
        let returnStrArray = JSON.parse(this.customDialog.resultfield)
        if (returnStrArray && returnStrArray.length > 0) {
          let result = returnStrArray.filter((item) => item.isPK)
          return (result && result.length && result[0].field) || ''
        } else {
          return ''
        }
      },
      primaryFieldProp: function () {
        return this.isSetPk == this.fromKey || this.fromKey == ''
          ? this.isSetPk
          : this.fromKey
      },
      selectsCount() {
        return this.selects && this.selects.length > 0 ? this.selects.length : 0
      },
      checkStrictly() {
        if (
          this.customDialog.treeDataMode &&
          this.customDialog.treeDataMode > 0
        ) {
          return true
        } else {
          return false
        }
      },
    },
    watch: {
      dialogData: {
        handler(val) {
          if (this.value && val.length > 0) {
            let modelName =
              this.modelName.split('.')[this.modelName.split('.').length - 1]
            const currentBindInfo = this.custdialog.custDialog.mappingConf.find(
              (it) => {
                return it['target'][0].endsWith(modelName)
              }
            )
            const from = currentBindInfo && currentBindInfo.from.toLowerCase()
            let returnStr = JSON.parse(this.customDialog.resultfield)
            let currentObj = returnStr.find((item) => {
              if (this.customDialog.dsType == 'selectedApi') {
                return item.comment === from
              } else {
                return item.comment.toLowerCase() === from
              }
            })
            this.fromKey = currentObj ? currentObj.field : ''
          }
        },
        immediate: true,
        deep: true,
      },
    },
    mounted() {
      if (this.value) {
        this.showDialog(true)
      }
    },
    methods: {
      showDialog(isMounted = false) {
        this.selectOrgs = []
        this.selects = []
        const this_ = this
        this.fixedParams = {}
        var alias = this.custdialog.custDialog.alias
        this.$requestConfig
          .getCustomDialogByAlias(alias)
          .then((customDialog) => {
            if (!customDialog || !customDialog.alias) {
              this.$message.error('对话框别名【' + alias + '】不存在！')
              return
            }
            if (customDialog.style == 1) {
              var displaylist = JSON.parse(customDialog.displayfield)
              this_.nodeKey = displaylist.id
            }
            if (customDialog.needPage && customDialog.requestType === 'POST') {
              let obj = {}
              this.getLastKeyByPath(obj, customDialog.pageKey, 1)
              this.getLastKeyByPath(obj, customDialog.pageSizeKey, 10)
              this.getLastKeyByPath(obj, customDialog.totalKey, true)
              const exp = utils.parseExp(customDialog.dataParam, obj, true)
              if (exp) {
                const params = JSON.parse(exp)
                if (params.pageBean) {
                  this.pagination = {
                    ...params.pageBean,
                  }
                }
              }
            }
            //对话框按表单字段查询（参数传入的）
            let bindList = this_.custdialog.custDialog.conditions
            this_.param = [] //绑定的表单字段
            if (bindList.length > 0) {
              bindList.forEach((ele) => {
                //绑定表单字段
                if (
                  ele.bind &&
                  (ele.defaultType == '3' ||
                    ele.bind.startsWith('data.searchForm'))
                ) {
                  let obj = {}
                  obj.field = ele.field
                  obj.bind = ele.bind
                  obj.bindType = ele.bindType
                  this_.param.push(obj)
                }
                //取值对象为脚本时获取value
                if (ele.bindType === 3) {
                  this_.$requestConfig.executeScript(ele.bind).then((res) => {
                    this_.executeScriptResult = res && res.value
                  })
                }
              })
            }
            //判断对话框查询是否有条件
            let userInputList = JSON.parse(customDialog.conditionfield)
            this_.quickSearch = '' //填写提示 placeholder
            this_.conditionBind = []
            let queryParams = []
            let placeholders = []
            if (userInputList.length > 0) {
              userInputList.forEach((ele) => {
                var obj = {}
                //条件查询参数（用户输入的） 文本框输入 defaultType 1 用户输入 2固定值 3参数传入 5脚本
                if (ele.defaultType == '1') {
                  obj[ele.field] = ''
                  queryParams.push(obj)
                  // queryParams[ele.field] = "";
                  this_.conditionBind.push(ele)
                  placeholders.push('请输入' + ele.comment)
                }
                if (ele.defaultType == '2' && ele.defaultValue) {
                  this_.fixedParams[ele.field] = ele.defaultValue
                  this_.fixedQuerys.push({
                    property: ele.field,
                    value: ele.defaultValue,
                    operation: this_.getOperation(ele.condition),
                    group: 'main',
                    relation: 'AND',
                  })
                }
              })
              this.$set(this, 'queryParams', queryParams)
              this.$set(this, 'placeholders', placeholders)
            }
            //判断是否显示条件查询输入框
            if (this_.quickSearch != '') {
              this_.querysShow = true
            } else {
              this_.querysShow = true
            }
            this_.quickSearch = '请输入' + this.quickSearch + '查询'
            this_.style = 'height:' + customDialog.height - 154 + 'px'
            if (window.screen.height && window.screen.height <= 900) {
              this.style = 'height:440px'
            }
            if (customDialog.style == 0 || customDialog.style == 2) {
              //列表
              setTimeout(() => {
                this_.customDialogShow(
                  {
                    alias: alias,
                    customDialog: customDialog,
                  },
                  isMounted
                )
              }, 100)
            } else if (customDialog.style == 1) {
              //树形
              return
            }
            let modelName =
              this.modelName.split('.')[this.modelName.split('.').length - 1]
            const currentBindInfo = this.custdialog.custDialog.mappingConf.find(
              (it) => {
                return it['target'][0].endsWith(modelName)
              }
            )
            const from = currentBindInfo && currentBindInfo.from.toLowerCase()
            let returnStr =
              customDialog && customDialog.resultfield
                ? JSON.parse(customDialog.resultfield)
                : []
            let currentObj = returnStr.find((item) => {
              if (customDialog.dsType == 'selectedApi') {
                return item.comment === from
              } else {
                return item.comment.toLowerCase() === from
              }
            })
            this.fromKey = currentObj ? currentObj.field : ''
            if (this.fromKey && this.isSetPk !== '') {
              let valueData = this.value ? this.value.split(',') : []
              for (var i = 0; i < valueData.length; i++) {
                let obj = {}
                obj[this.fromKey] = valueData[i]
                this.selects.push({ ...obj })
              }
              this.selectOrgs = [...this.selects]
            }
          })
      },
      async customDialogShow(pageParam, isMounted = false) {
        if (!isMounted) {
          this.customDialogShowList = true
        }
        this.customDialog = pageParam.customDialog
        let queryUrl = this.customDialog.url
        //如果自定义对话框列表查询数据不是数据源则请求方法为restful配置的请求方式
        let requestType = this.customDialog.requestType
        if (this.customDialog.dsType == 'selectedApi') {
          let queryParams = []
          if (this.param) {
            for (let i = 0; i < this.param.length; i++) {
              let item = this.param[i]
              let val = item.bind
              if (item.bindType == '1') {
                val = this.getCurrentValue(item.bind)
              } else if (item.bindType == '3') {
                await this.$requestConfig
                  .executeScript(item.bind)
                  .then((res) => {
                    val = res && res.value
                  })
              }
              if (val != null && !utils.isEmpty(val)) {
                queryParams.push({ key: item.field, value: val })
              }
            }
          }
          queryUrl =
            '${portal}/portal/portalInterfaceManager/v1/doQuery?alias=' +
            this.customDialog.apiAlias +
            '&paramData=' +
            encodeURIComponent(Base64.encode(`${JSON.stringify(queryParams)}`))
          requestType = 'GET'
        } else if (this.customDialog.dsType == 'dataSource') {
          queryUrl =
            '${form}/form/customDialog/v1/getListData?alias=' +
            this.customDialog.alias +
            '&mapParam=' +
            (this.customDialog.mapParam ? this.customDialog.mapParam : '')
          requestType = 'POST'
        }
        this.customDialog.queryUrl = queryUrl
        this.customDialog.requestType = requestType
        if (this.dialogData.length < 1) {
          this.search(true)
          this.displayfield = JSON.parse(pageParam.customDialog.displayfield)
          if (this.customDialog.dsType == 'dataSource') {
            for (var i = 0; i < this.displayfield.length; i++) {
              this.displayfield[i].field =
                this.displayfield[i].field.toLowerCase()
            }
          }
        } else if (this.dialogData.length >= 1) {
          this.search(true)
        }
        if (this.dialogData.length > 0 && this.displayfield.length == 0) {
          this.search(true)
          this.displayfield = JSON.parse(pageParam.customDialog.displayfield)
          if (this.customDialog.dsType == 'dataSource') {
            for (var j = 0; i < this.displayfield.length; j++) {
              this.displayfield[j].field =
                this.displayfield[j].field.toLowerCase()
            }
          }
        }
      },
      // 将以comment为key的数组改造为以field为key的数组
      convertComment2Field(ary, fields) {
        const result = []
        if (!ary || ary.length == 0) {
          return result
        }
        ary.forEach((s) => {
          const r = {}
          Object.entries(s).forEach((kv, index) => {
            const f = fields[index]
            if (f) {
              r[f] = kv[1]
            }
          })
          result.push(r)
        })
        return result
      },
      //查询
      search(resetPagintion, data) {
        this.resetParam()
        let querys = [] //查询条件
        let queryFilter = {}
        if (JSON.stringify(this.pagination) === '{}') {
          this.pagination = { page: 1, pageSize: 20, showTotal: true }
        }
        let pageBean = { pageBean: this.pagination }
        if (resetPagintion) {
          pageBean.pageBean = { page: 1, pageSize: 20, showTotal: true }
        }
        //用户输入的
        if (this.queryParams.length !== 0 && this.queryParams[0] !== '') {
          this.conditionBind.forEach((item, index) => {
            if (this.queryParams[index][item.field]) {
              querys.push({
                property: item.field,
                value: this.queryParams[index][item.field],
                group: 'main',
                operation: 'LIKE',
                relation: 'AND',
              })
            }
          })
        }
        //查询条件
        data &&
          data.forEach((d) => {
            const shouldPush = d.value != null && true && d.value != ''
            // 高级搜索中支持一个搜索框中关联多个属性进行搜索
            if (d.prop.indexOf(',') > 0) {
              const propAry = utils['a' /* default */].stringSplit(d.prop, ',')
              if (propAry && propAry.length > 0) {
                const groupName = `group_${propAry[0]}`
                this.clearQueryByGroupName(groupName)
                shouldPush &&
                  propAry.forEach((p) => {
                    querys.push({
                      property: p,
                      value: d.value,
                      group: groupName,
                      relation: 'OR',
                      operation: d.operation,
                    })
                  })
              }
            } else {
              shouldPush &&
                querys.push({
                  property: d.prop,
                  value: d.value,
                  group: 'advance',
                  relation: d.relation,
                  operation: d.operation,
                })
            }
          })
        //参数传入的查询拼接
        if (this.param) {
          this.param.forEach((item) => {
            querys.push({
              property: item.field,
              value:
                item.bindType === 2
                  ? item.bind
                  : item.bindType === 3
                  ? this.executeScriptResult
                  : this.getCurrentValue(item.bind),
              group: 'main',
              operation: item.operation ? item.operation : 'LIKE',
              relation: 'AND',
            })
          })
        }
        //来自组合对话框的
        if (
          this.combinationTreeQuerys &&
          this.combinationTreeQuerys.length !== 0
        ) {
          for (let i = 0; i < this.combinationTreeQuerys.length; i++) {
            querys.push(this.combinationTreeQuerys[i])
          }
        }
        // post restful接口，并且配置了post参数。则以post参数作为请求参数
        if (
          this.customDialog.dsType !== 'dataSource' &&
          this.customDialog.requestType === 'POST' &&
          this.customDialog.dataParam &&
          this.customDialog.dataParam.constructor === String
        ) {
          let param = this.param
          // 构建上下文数据对象
          let ctx = {}
          //根据路径构建想要的分页属性
          let obj = {}
          this.getLastKeyByPath(
            obj,
            this.customDialog.pageKey,
            pageBean.pageBean.page
          )
          this.getLastKeyByPath(
            obj,
            this.customDialog.pageSizeKey,
            pageBean.pageBean.pageSize
          )
          this.getLastKeyByPath(
            obj,
            this.customDialog.totalKey,
            pageBean.pageBean.total
          )
          querys &&
            querys.length &&
            querys.forEach((element) => {
              ctx[element.property] = element.value
            })
          const queryParamMap = this.getSearchValueByKey()
          queryParamMap.pageSize = pageBean.pageBean.pageSize
          queryParamMap.page = pageBean.pageBean.page
          queryParamMap.total = pageBean.pageBean.total
          // 添加用户id 岗位id 组织id
          try {
            if (this.$requestConfig.getUserId()) {
              ctx.userId = this.$requestConfig.getUserId()
            }
            if (this.$requestConfig.getOrgId()) {
              ctx.orgId = this.$requestConfig.getOrgId()
            }
            if (this.$requestConfig.getPostId()) {
              ctx.postId = this.$requestConfig.getPostId()
            }
          } catch (e) {}

          if (queryParamMap) {
            queryParamMap.form
          }
          const exp = utils.parseExp(this.customDialog.dataParam, {
            ...utils.validObject(ctx),
            ...utils.validObject(queryParamMap),
            ...utils.validObject(this.fixedParams),
          })
          try {
            param = JSON.parse(exp)
            const dataParam = JSON.parse(this.customDialog.dataParam)
            const queryList =
              dataParam &&
              dataParam.querys &&
              dataParam.querys.map((item) => {
                const bindKey =
                  item.value && item.value.replace('${', '').replace('}', '')
                const isFixedValue = item.value && !item.value.startsWith('${')
                const currentFixedVal = this.fixedParams[bindKey]
                  ? this.fixedParams[bindKey]
                  : isFixedValue
                  ? item.value
                  : ''
                return {
                  ...item,
                  value:
                    currentFixedVal ||
                    queryParamMap[bindKey] ||
                    ctx[bindKey] ||
                    '',
                }
              })
            param.querys = queryList
            if (this.customDialog.needPage) {
              param.pageBean = obj
            } else {
              param.pageBean.pageSize = -1
            }
            //构造请求的参数
            let requestParam = {
              pageBean: param,
              queryUrl: this.customDialog.queryUrl,
              requestType: this.customDialog.requestType,
              dsType: this.customDialog.dsType,
              listKey: this.customDialog.listKey,
              pageKey: this.customDialog.pageKey,
              pageSizeKey: this.customDialog.pageSizeKey,
              totalKey: this.customDialog.totalKey,
            }
            this.getDialoglistJson(requestParam).then(() => {
              this.checkList()
            })
          } catch (e) {
            this.$message.error(`POST参数不是有效的JSON格式${param}`)
          }
        } else {
          if (this.fixedQuerys.length) {
            this.fixedQuerys.forEach((query) => {
              querys.push(query)
            })
          }
          if (querys.length > 0) {
            queryFilter = this.handlePostData({
              pageBean: pageBean.pageBean,
              querys,
            })
            this.customDialog.pageBean = queryFilter
            this.getDialoglistJson(this.customDialog).then(() => {
              this.checkList()
            })
          } else {
            this.customDialog.pageBean = pageBean
            this.getDialoglistJson(this.customDialog).then(() => {
              this.checkList()
            })
          }
        }
        this.tableRadioVal = ''
      },
      getSearchValueByKey() {
        let queryParamsObj = {}
        if (this.queryParams.length > 0) {
          queryParamsObj = this.conditionBind.reduce((pre, cur, index) => {
            pre[cur.field] = this.queryParams[index][cur.field]
            return pre
          }, {})
        }
        return queryParamsObj
      },
      getLastKeyByPath(obj, path, value) {
        if (!obj || !path || path.constructor != String) {
          return
        }
        if (!/^\w?.*[\w|\]]$/.test(path)) {
          return
        }
        let pathAry = path.split('.')
        if (pathAry.length == 1) {
          obj[path] = value
        } else {
          let length = pathAry.length
          obj[pathAry[length - 1]] = value
        }
      },
      //重置
      reset() {
        this.queryParams.forEach((paramObj, index) => {
          for (let key in paramObj) {
            this.queryParams[index][key] = ''
          }
        })
        //组合树重置
        let nodes = {}
        if (this.$refs.combinationTree) {
          nodes = this.$refs.combinationTree.store.nodesMap
        }
        for (let key in nodes) {
          nodes[key].expanded = false
        }
        this.combinationTreeQuerys.splice(0)
        this.search(true)
      },
      getCurrentValue(bind) {
        let value = null
        const pInst = utils.getOnlineFormInstance(this)
        const bindPath = bind.replace(`${this.subPath}.`, '')
        if (this.sunIndex || this.sunIndex === 0) {
          value = utils.getValueByPath(
            this.currentSubData[this.subIndex],
            bindPath,
            this.sunIndex || this.sunIndex === 0 ? this.sunIndex : null
          )
        } else {
          value = utils.getValueByPath(
            pInst,
            bind,
            this.subIndex || this.subIndex === 0 ? this.subIndex : null
          )
        }
        return value
      },
      checkList() {
        if (this.isSetPk !== '') {
          this.checkBoxDataAll = this.selects
          if (this.customDialog.selectNum === 1) {
            let resData = this.dialogData.findIndex(
              (item) =>
                item.hasOwnProperty(this.isSetPk) &&
                item[this.isSetPk] == this.checkBoxDataAll[0][this.isSetPk]
            )
            this.tableRadioVal = resData
          } else {
            let selectedMarkList = []
            this.checkBoxDataAll.map((item) => {
              if (item.hasOwnProperty(this.isSetPk)) {
                selectedMarkList.push(item[this.isSetPk])
              }
            })
            this.dialogData.forEach((row) => {
              if (selectedMarkList.includes(row[this.isSetPk])) {
                this.$nextTick(() => {
                  this.$refs.htTable.$refs.htTable.toggleRowSelection(row, true)
                })
              } else {
                this.$nextTick(() => {
                  this.$refs.htTable.$refs.htTable.toggleRowSelection(
                    row,
                    false
                  )
                })
              }
            })
          }
        }
      },
      //回车查询
      searchEnterFun: function (e) {
        var keyCode = window.event ? e.keyCode : e.which
        if (keyCode == 13) {
          this.search()
        }
      },
      handleSizeChange: function (size) {
        //每页下拉显示数据
        this.pagination.pageSize = size
        let queryValue =
          (this.$refs.searchPanel && this.$refs.searchPanel.fieldArray) || null
        this.search(false, queryValue)
      },
      handleCurrentChange: function (currentPage) {
        //点击第几页
        let queryValue =
          (this.$refs.searchPanel && this.$refs.searchPanel.fieldArray) || null
        this.pagination.page = currentPage
        this.search(false, queryValue)
      },
      dialogCancel() {
        const this_ = this
        this_.queryParam = ''
        this.setDialogData([])
        this_.customDialogShowList = false
        //判断是否是点击了确认再点击取消的  inputVal没有值则表示直接点击的取消
        if (!this_.inputVal) {
          this_.selectOrgs = []
          this_.selects = []
        } else {
          this_.selectOrgs = this_.showData ? [...this_.showData] : ''
          this_.selects = [...this_.selectOrgs]
          this.checkBoxDataAll = [...this_.selectOrgs]
        }
      },
      // 同步选择结果
      syncInputValue() {
        let thisIndex = null //当前数据所在下标
        let parentIndex = null //父节点所在下标
        if (this.$parent.$el) {
          thisIndex = utils.getSubScopeElAndIndex(this.$parent.$el).index
          let subScopeEl = utils.getParentElementByClassNamePrefix(
            this.$parent.$parent.$el,
            'data-index'
          )
          if (subScopeEl) {
            const className = Array.prototype.find.call(
              subScopeEl.classList,
              (item) => item.startsWith('data-index__')
            )
            if (className) {
              parentIndex = className.split('__')[1]
            }
          }
          if (null == parentIndex) {
            subScopeEl = utils.getParentElementByAttribute(
              this.$parent.$parent.$el,
              'data-index'
            )
            if (subScopeEl && subScopeEl.attributes['data-index']) {
              parentIndex = subScopeEl.attributes['data-index'].value
            }
          }
        }
        var returnStr = JSON.parse(this.customDialog.resultfield)
        //拿到返回的字段
        var field = new Array([returnStr.length])
        var comment = new Array([returnStr.length])
        var str = []
        for (var i = 0; i < returnStr.length; i++) {
          field[i] =
            this.customDialog.dsType == 'selectedApi'
              ? returnStr[i].field
              : returnStr[i].field.toLowerCase()
          comment[i] =
            this.customDialog.dsType == 'selectedApi'
              ? returnStr[i].comment
              : returnStr[i].comment.toLowerCase()
        }
        var s = this.selectOrgs
        if (this.selectOrgs) {
          this.showData = [...this.selectOrgs]
          this.checkBoxDataAll = [...this.selectOrgs]
        } else {
          this.showData = []
          this.checkBoxDataAll = []
        }
        if (this.customDialog.selectNum === 1) {
          s = this.selectOrgs
        }
        if (this.customDialog.selectNum === 1) {
          var temp = ''
          // 当 s 存在或 s 的长度不为0时
          if (s && s.length) {
            for (var k = 0; k < comment.length; k++) {
              let sField = !utils.isEmpty(s[0][field[k]]) ? s[0][field[k]] : ''
              let encodeStr = encodeURIComponent(sField)
              temp += '"' + comment[k] + '":"' + encodeStr + '",'
            }
          }
          if (temp != '') {
            temp = '{' + temp.substring(0, temp.length - 1) + '}'
          }
          str.push(utils.parseToJson(temp))
        } else {
          if (s && s.length > 0) {
            for (var m = 0; m < s.length; m++) {
              var temp1 = ''
              for (var j = 0; j < comment.length; j++) {
                const _m = s[m]
                const _n = field[j]
                const _ov = _m[_n] //原始值
                const _uv = _m[_n.toUpperCase()] //field转大写后取到的值
                const _lv = _m[_n.toLowerCase()] //field转小写后取到的值
                const _fv =
                  _ov == null || _ov == undefined
                    ? _uv == null || _uv == undefined
                      ? _lv
                      : _uv
                    : _ov
                const encodeStr = encodeURIComponent(_fv)
                temp1 += '"' + comment[j] + '":"' + encodeStr + '",'
              }
              if (temp1 != '') {
                temp1 = '{' + temp1.substring(0, temp1.length - 1) + '}'
              }
              str.push(utils.parseToJson(temp1))
            }
          }
        }
        const pInst = utils.getOnlineFormInstance(this)
        this.custdialog.custDialog.mappingConf.forEach((con) => {
          this.custdialog.resultField.forEach((fillitem) => {
            if (fillitem.field == con.from || fillitem.comment == con.from) {
              var val = ''
              var from = con.from.toLowerCase()
              str.forEach((item) => {
                if (item) {
                  val +=
                    decodeURIComponent(item[from]) == 'undefined'
                      ? ''
                      : decodeURIComponent(item[from]) + ','
                }
              })
              if (this.modelName == 'data.' + con['target'][0]) {
                val = val.substring(0, val.length - 1)
                let bindValue = utils.getValueByPath(
                  pInst,
                  'data.' + con['target'][0],
                  thisIndex || thisIndex === 0 ? thisIndex : null
                )
                if (fillitem && fillitem.fillBackType == 2 && bindValue) {
                  return
                } else {
                  utils.setValueByPath(
                    pInst,
                    'data.' + con['target'][0],
                    val,
                    thisIndex
                  )
                }
              } else if (
                this.modelName &&
                this.modelName.startsWith('searchForm.')
              ) {
                let prePath = pInst['searchForm'] ? '' : 'data.'
                let bindValue = utils.getValueByPath(
                  pInst,
                  prePath + 'searchForm.' + con['target'][0],
                  thisIndex || thisIndex === 0 ? thisIndex : null
                )
                if (fillitem && fillitem.fillBackType == 2 && bindValue) {
                  return
                } else {
                  utils.setValueByPath(
                    pInst,
                    prePath + 'searchForm.' + con['target'][0],
                    val.substring(0, val.length - 1),
                    thisIndex
                  )
                }
              } else if (this.modelName && this.modelName == 'customDialog') {
                const _val = val.substring(0, val.length - 1)
                //自定义对话框往model中写入selectorConfig
                let bindValue = utils.getValueByPath(
                  pInst,
                  'selectorConfig.' + con['target'][0],
                  thisIndex || thisIndex === 0 ? thisIndex : null
                )
                if (fillitem && fillitem.fillBackType == 2 && bindValue) {
                  return
                } else {
                  utils.setValueByPath(
                    pInst,
                    'selectorConfig.' + con['target'][0],
                    _val,
                    thisIndex
                  )
                }

                //最后一个配置项显示在对话框搜索栏中
                this.$emit('updateInput', _val)
              } else {
                let configAttr = con['target'][0].split('.')
                let path = con['target'][0]
                if (configAttr.length == 4 && parentIndex >= 0) {
                  //孙表数据赋值
                  path =
                    configAttr[0] +
                    '.' +
                    configAttr[1] +
                    '[' +
                    parentIndex +
                    '].' +
                    configAttr[2] +
                    '.' +
                    configAttr[3]
                }
                const _val = val.substring(0, val.length - 1)
                if (path) {
                  if (this.modelName && this.modelName.endsWith(path)) {
                    // this.$emit('input', _val)
                    this.$emit('updateInput', _val)
                  }
                  let bindPath = `${pInst.data ? 'data.' : 'model.'}${path}`
                  let bindValue = utils.getValueByPath(
                    pInst,
                    bindPath,
                    thisIndex || thisIndex === 0 ? thisIndex : null
                  )
                  if (fillitem && fillitem.fillBackType == 2 && bindValue) {
                    return
                  } else {
                    utils.setValueByPath(pInst, bindPath, _val, thisIndex)
                    //强制刷新
                    this.$forceUpdate()
                  }
                }
              }
            }
          })
        })
        //判断对话框是否绑定了关联查询
        let custQueryJson = this.custdialog.custDialog.custQueryJson
        if (custQueryJson.length > 0) {
          for (let i = 0; i < custQueryJson.length; i++) {
            if (custQueryJson[i].conditionfield.length > 0) {
              this.doQuery(custQueryJson[i])
            } else {
              console.error(
                '[' +
                  custQueryJson[i].comment +
                  ']关联查询取值参数未绑定表单字段'
              )
            }
          }
        }
      },
      //判断数据是否包含某个对象，并返回数据包含对象的下标
      indexArray(array, item) {
        if (array.length == 0) {
          return -1
        }
        for (let i = 0; i < array.length; i++) {
          if (JSON.stringify(array[i]) == JSON.stringify(item)) {
            return i
          }
        }
        return -1
      },
      // 处理POST请求时的参数
      handlePostData(queryFilter) {
        if (
          !this.customDialog.dataParam ||
          this.customDialog.dataParam.constructor != String
        ) {
          return queryFilter
        }
        // 构建上下文数据对象
        let ctx = {}
        queryFilter &&
          queryFilter.querys.forEach((element) => {
            ctx[element.property] = element.value
          })
        const exp = utils.parseExp(this.customDialog.dataParam, ctx)
        try {
          return JSON.parse(exp)
        } catch (e) {
          CustomQuery._throwException(
            'POST参数不是有效的JSON格式：' + this.customDialog.dataParam
          )
        }
      },
      //加载树的信息
      toTreeData(data, id, pid, name, pvalue) {
        // 建立个树形结构,需要定义个最顶层的父节点，pvalue是0
        return this.translateDataToTree(data, pid, id, name, pvalue)
      },
      translateDataToTree(data, pid, id) {
        //把树数据有子节点的数据全部过滤掉（只留父节点的数据）
        let tile2nest = utils.tile2nest(data, id, pid)
        return tile2nest || []
      },
      combiTreeClick(paramObj) {
        //组合对话框点击左树
        //清空旧的
        this.combinationTreeQuerys.splice(0)
        let combinationRule = JSON.parse(this.customDialog.combinationRule)
        if (!combinationRule.rules || combinationRule.rules.length == 0) {
          return
        }
        let rules = combinationRule.rules
        for (let i = 0; i < rules.length; i++) {
          let value = paramObj[rules[i].treeField]
          let property = rules[i].listField
          this.combinationTreeQuerys.push({
            property: property,
            value: value,
            group: 'treeGroup',
            operation: this.getOperation(rules[i].condition),
            relation: 'AND',
          })
        }
        this.search(true)
      },
      //获取运算符号
      getOperation(old) {
        if (!old) {
          return ''
        }
        if (old == 'EQ') {
          return 'EQUAL'
        }
        if (old == 'LK') {
          return 'LIKE'
        }
        if (old == 'LFK') {
          return 'LIKE'
        }
        if (old == 'IN') {
          return 'IN'
        }
        if (old == 'BETWEEN') {
          return 'BETWEEN'
        }
      },
      //关闭树形动态参数输入值的对话框
      handleClose() {
        this.dialogVisible = false
      },
      //显示字段排序
      sort(select, type) {
        this.selects = utils.arrayMove(this.selects, select, type)
      },
      exports() {
        this.dialogExportVisible = true
      },
      //排序
      sortExport(index, type) {
        if ('up' == type) {
          if (index === 0) {
            this.$message({
              message: '已经是列表中第一位',
              type: 'warning',
            })
          } else {
            let temp = this.displayfield[index - 1]
            this.$set(this.displayfield, index - 1, this.displayfield[index])
            this.$set(this.displayfield, index, temp)
          }
        } else {
          if (index === this.displayfield.length - 1) {
            this.$message({
              message: '已经是列表中最后一位',
              type: 'warning',
            })
          } else {
            this.isTransition = true
            let i = this.displayfield[index + 1]
            this.$set(this.displayfield, index + 1, this.displayfield[index])
            this.$set(this.displayfield, index, i)
          }
        }
      },
      submitExport() {
        this.$emit('exports', this)
      },
      //取消导出
      exportCancel() {
        this.dialogExportVisible = false
        // this.exportData.expField = []
      },
      toolButtonClick(func, button) {
        if (button && button.triggerType === 'href') {
          window.open(button.urlPath)
        } else {
          this.$emit('toolButtonClick', func, this)
        }
      },
      columnBtnClick(func, row, button) {
        if (button && button.triggerType === 'href') {
          window.open(button.urlPath)
        } else {
          this.$emit('columnBtnClick', func, this, row)
        }
      },
      setQueryBindOptions(queryBindOptions) {
        let conditionValueMap = {}
        if (queryBindOptions) {
          queryBindOptions.selectList.forEach((e) => {
            conditionValueMap[e.bindSelectd] = e.selectValue
          })
        }
        this.conditionValueMap = conditionValueMap
      },
      resetParam() {
        if (this.customDialog.conditionfield) {
          let tempParam = []
          let conditioniFields = JSON.parse(this.customDialog.conditionfield)
          conditioniFields.forEach((e) => {
            if (
              e.defaultType &&
              e.defaultType === '3' &&
              this.conditionValueMap[e.field]
            ) {
              tempParam.push({
                field: e.field,
                bindType: 2,
                bind: this.conditionValueMap[e.field],
                operation: this.getOperation(e.condition),
              })
            }
          })
          this.param = tempParam
        }
      },
      loadData() {
        this.$refs.searchPanel.search(true)
      },
    },
  }
</script>
<style lang="scss" scoped>
  ::v-deep {
    .el-button--mini {
      padding: 0px 15px;
      font-size: 12px;
      border-radius: 3px;
      height: 100%;
      border-top-left-radius: 0;
      border-bottom-left-radius: 0;
    }

    .el-button--info {
      background-color: #f5f7fa;
      border-color: #e4e7ed;
      color: #c0c4cc;
    }

    .el-input__suffix {
      position: absolute;
      height: 100%;
      right: 0px !important;
      top: 0;
      text-align: center;
      color: #c0c4cc;
      -webkit-transition: all 0.3s;
      transition: all 0.3s;
      pointer-events: none;
      z-index: 8;
    }

    .el-dialog__body {
      padding: 0;
      height: calc(100% - 154px);
      margin-bottom: 24px;
      overflow-y: auto;
      @include base-scrollbar;
    }

    @media (max-width: 1280px) {
      .el-dialog {
        width: 96% !important;
        margin-top: 2vh !important;
      }
    }

    .el-dialog__wrapper {
      overflow: unset !important;

      &::-webkit-scrollbar {
        width: 0;
        background-color: transparent;
      }
    }

    // .el-dialog {
    //   height: 90%;
    //   min-height: 400px;
    // }
    @media (max-height: 960px) {
      .el-dialog__body .el-container {
        height: 100% !important;
      }
    }

    .el-divider--vertical {
      height: 100%;
    }
  }

  .el-input__inner[aria-invalid='true'] {
    border-color: #f56c6c;
  }

  .el-select__tags {
    background: #fff;
    margin-left: 1px;
  }

  .left-aside {
    border-right: 1px solid #eee;
    padding: 10px;
  }

  .org-tree {
    height: 440px;
    margin-top: 10px;
  }

  .middle-header {
    height: unset !important;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    margin-bottom: 16px;

    .search-item {
      display: flex;
      // width: 33.33%;
      margin-right: 12px;
      align-items: center;
    }

    .btn-wrap {
      line-height: 50px;
    }

    ::v-deep.search-panel__container {
      width: calc(var(--searchPanelWidth) - 48px - 40px);

      .search-field__container {
        margin-right: 0px !important;
        padding-right: 24px;
        min-height: 32px;
        height: 100%;

        .inputs.ht-form-inputs__inline {
          width: 100% !important;
          position: relative;
        }

        .inputs .el-input__inner {
          border-radius: 0;
          height: 32px !important;
          line-height: 32px !important;
        }
      }

      .search-btn__wrap {
        text-align: left;
      }
    }
  }

  .org-table {
    width: 100%;
  }

  .right-aside {
    border-left: 1px solid #eee;
  }

  .select-aside {
    border-left: 1px solid #eee;
  }

  .select-header {
    border-bottom: 1px solid #eee;
    height: 52px !important;
  }

  .select-header > span {
    padding: 10px 0;
    line-height: 53px;
  }

  .select-tree-div {
    height: calc(100% - 60px);
    overflow-y: auto;
    @include base-scrollbar;
    min-height: unset;
  }

  > .el-card__header {
    padding: 10px;
    height: 48px;
    background: #ebebeb;
    text-align: left;
    font-size: 16px;
  }

  > .el-card__body {
    padding: 10px 0;
  }

  .org-find-card > .el-card__header {
    background: #f5f7fa;
  }

  > .el-main {
    padding: 0 24px !important;
  }

  .button-group {
    width: 70px;
    height: 170px;
    margin: 0px auto;
    position: relative;
    top: 50%;
    -webkit-transform: translateY(-50%);
    -moz-transform: translateY(-50%);
    -ms-transform: translateY(-50%);
    -o-transform: translateY(-50%);
    transform: translateY(-50%);
  }

  .button-group > button {
    display: block;
    margin: 8px 0;
  }

  .custom-dialog_main {
    min-height: 350px;
    @include base-scrollbar;
  }

  ::v-deep .search-field__container {
    margin-right: 50px !important;
  }

  ::v-deep {
    .custom-class-dialog {
      height: 100% !important;
      width: 100% !important;
      margin: 0 !important;
    }
  }

  .custom-container {
    overflow: auto;
    @include base-scrollbar;
  }

  .list-selector__selected {
    height: 100%;

    .selector-selected__wrap {
      list-style: none;
      width: calc(100% - 24px);
      padding: 10px;

      li {
        line-height: 20px;
      }

      li + li {
        margin-top: 10px;
      }

      .selector-selected__item {
        height: 36px;
        padding: 0 6px;
        display: flex;
        align-items: center;
        justify-content: space-between;

        &:hover {
          background-color: #f8f8f8;
        }

        .selector-selected__remove {
          color: #bfbfbf;

          &:hover {
            color: #409eff;
          }
        }

        .selector-selected__up {
          &:hover {
            color: #409eff;
          }
        }

        .selector-selected__down {
          &:hover {
            color: #409eff;
          }
        }

        .selector-selected__item-left {
          display: flex;
          align-items: center;
          width: 155px;

          .selector-text {
            width: 120px;
            text-align: left;
            text-overflow: ellipsis;
            overflow: hidden;
            white-space: nowrap;
          }

          .list-selector__handle {
            cursor: move;
          }

          div {
            margin-left: 10px;
          }
        }

        i {
          font-size: 16px;
        }
      }
    }

    .el-tree__empty-block {
      height: 80px;
    }

    .is-disabled {
      color: #c0c4cc;
      cursor: not-allowed;
    }
  }
</style>
<style lang="scss">
  .hontent-custom-dialog {
    #container {
      display: flex; /*中间弹性盒布局*/
      flex-wrap: nowrap; /*排列不下时不换行*/
      text-align: center;
      padding-left: 24px;
      padding-right: 24px;
    }

    #center {
      order: 1;
      flex: 1;
      width: var(--middleWidth);

      .el-header {
        border-bottom: none !important;
      }
    }

    #left {
      order: 0;
      width: calc(var(--leftWidth) - 24px);
      padding-right: 24px;
    }

    #right {
      order: 2;
      width: 250px;
      padding-left: 24px;
    }
  }
</style>
