<template>
  <div class="fullheight join-table-setting">
    <el-form
      v-form="{formItemAlign: 'left'}"
      :model="sqlForm"
      class="sql-form"
      label-width="80px"
    >
      <ht-form-item label="数据源">
        <el-button type="text" @click="generateSql" class="sql-btn"
          >SQL生成</el-button
        >
      </ht-form-item>
      <ht-form-item>
        <template slot="label">
          <el-tooltip
            content="关联表查询不支持使用别名、WHERE、GROUP BY、ORDER BY、HAVING"
          >
            <i class="el-icon-info"></i>
          </el-tooltip>
          <span>sql语句</span>
        </template>
        <el-input
          v-if="sqlForm.leftSql"
          type="textarea"
          :disabled="true"
          v-model="sqlForm.leftSql"
          autosize
          resize="none"
          class="sql-textarea sql-left"
        ></el-input>
        <el-input
          type="textarea"
          v-model="sqlForm.rightSql"
          :autosize="{minRows: 8}"
          resize="none"
          class="sql-textarea"
          @change="sqlValueChange"
        ></el-input>
        <el-button
          type="primary"
          class="verification-sql"
          @click="checkSql"
          :disabled="isCheckSql"
          >验证SQL</el-button
        >
      </ht-form-item>
    </el-form>
    <el-dialog
      title="SQL生成器"
      :visible.sync="sqlDialogVisible"
      append-to-body
      width="70%"
      :before-close="handleClose"
      custom-class="sql-dialog"
      :close-on-click-modal="false"
    >
      <el-button type="primary" icon="el-icon-plus" @click="addSqlList"
        >添加关联表</el-button
      >
      <div class="association-table">
        <div
          class="association-item"
          v-for="(row, index) in joinTableList"
          :key="index"
        >
          <div class="association-item-wrap">
            <div class="left-box">
              <div class="left">
                <span class="label">关联表:</span>
                <span v-if="index === 0" class="value">{{
                  `${formName}(${tableName.toUpperCase()})`
                }}</span>
                <el-select
                  v-else
                  v-model="row.related"
                  filterable
                  placeholder="请选择"
                >
                  <el-option
                    v-for="item in dbTableList.filter(item => item.type == '2')"
                    :key="item.name"
                    :label="item.comment + '(' + item.name + ')'"
                    :value="item.name"
                  >
                    <span>{{ `${item.comment}(${item.name})` }}</span>
                  </el-option>
                </el-select>
              </div>
              <div class="right">
                <span class="label">被关联表:</span>
                <el-select
                  v-model="row.connected"
                  filterable
                  placeholder="请选择"
                  @change="joinTableChange(row)"
                >
                  <el-option
                    v-for="item in dbTableList"
                    :key="item.name"
                    :label="item.comment + '(' + item.name + ')'"
                    :value="item.name"
                  >
                    <span>{{ `${item.comment}(${item.name})` }}</span>
                  </el-option>
                </el-select>
              </div>
            </div>
            <div class="right-box">
              <el-button
                type="text"
                icon="icon-application-delete"
                @click="handleDelete(index)"
                >删除</el-button
              >
            </div>
          </div>
          <div class="incidence-relation" v-if="row.connected">
            <div class="incidence-relation-header">
              <span class="label">关联关系:</span>
              <el-button
                type="text"
                icon="el-icon-circle-plus-outline"
                @click="row.relation.push({})"
                >添加</el-button
              >
            </div>
            <div
              class="incidence-relation-item"
              v-for="(tab, indexRelation) in row.relation"
              :key="indexRelation"
            >
              <div class="relation-item__left">
                <span class="relate">{{ row.related || tableName }}.</span>
                <el-select
                  v-model="tab.relatedBind"
                  filterable
                  clearable
                  placeholder="请选择"
                >
                  <el-option
                    v-for="(option, idx) in fieldsOptionsMap[row.related]"
                    :key="idx"
                    :label="`${option.fieldName}(${option.comment})`"
                    :value="option.fieldName"
                  >
                    <span>{{ `${option.fieldName}(${option.comment})` }}</span>
                  </el-option>
                </el-select>
                <span class="connect"> = {{ row.connected }}.</span>
                <el-select
                  v-model="tab.connectedBind"
                  filterable
                  clearable
                  placeholder="请选择"
                >
                  <el-option
                    v-for="(option, indx) in fieldsOptionsMap[row.connected]"
                    :key="indx"
                    :label="`${option.fieldName}(${option.comment})`"
                    :value="option.fieldName"
                  >
                    <span>{{ `${option.fieldName}(${option.comment})` }}</span>
                  </el-option>
                </el-select>
              </div>
              <el-button
                v-if="row.relation.length > 1"
                type="text"
                icon="icon-application-delete"
                @click="row.relation.remove(tab)"
              ></el-button>
            </div>
          </div>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleClose">取 消</el-button>
        <el-button type="primary" @click="handleSubmitDialog">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import form from '@/api/form.js'
import {validArray} from '@/utils'

import {format} from 'sql-formatter'

export default {
  props: {
    dsName: {
      type: String,
      default: 'LOCAL'
    },
    tableName: {
      type: String,
      default: ''
    },
    joinTablesStr: {
      type: String,
      default: ''
    },
    formName: {
      type: String,
      default: ''
    },
    joinTablesSql: {
      type: String,
      default: ''
    },
    formAlias: {
      type: String,
      default: ''
    },
    data: Object
  },
  data() {
    return {
      assignedTable: '',
      joinTableList: [],
      dbTableList: [],
      fieldsOptionsMap: {},
      // tabList: [],
      // pathArr: [],
      // branchArr: [],
      svgHtml: '',
      //branchList: [],
      svgHeight: '400px',
      Mleft: 50, //初始左边距50
      Mtop: 20, //初始上边距40
      XIncase: 100, //x轴递增数值70
      YIncase: 50, //y轴递增数据50
      conditionObj: {},
      defaultCondition: {
        property: '',
        operator: '1',
        dataType: '',
        value: '',
        compType: '1',
        main: '',
        ref: ''
      },
      varTree: [],
      sqlForm: {
        leftSql: '',
        rightSql: ''
      },
      dataSources: [],
      sqlDialogVisible: false,
      assignedTableOptions: [],
      associationTableList: [],
      isCheckSql: false,
      oldRightSql:''
    }
  },
  computed: {
    dataSourceAlias: function(va) {
      return this.dsName || 'LOCAL'
    },
    sql() {
      return `${this.sqlForm.leftSql} ${this.sqlForm.rightSql}`
    }
  },
  mounted() {
    this.initData()
    this.conditionObj = {junction: 'and', condition: []}
    //this.buildConditionTree(this.conditionObj)
    //this.createSvgHtml(this.pathArr)

    this.joinTableList.forEach((item, index) => {
      this.buildConditionTree(item, index)
    })
    this.joinTablesSqlMap()
  },
  methods: {
    sqlValueChange(val) {
      this.sqlForm.rightSql = format(val)
      if (val) {
        const valList = validArray(val.split('left join '))
        const associationTable = Array.from(
          new Set(valList.map(item => `${item.split(' on ')[0]}.*`))
        ).join(',')
        this.sqlForm.leftSql = format(
          `select ${this.tableName}.*,${associationTable} from ${this.tableName}`
        )
      } else {
        this.sqlForm.leftSql = format(`select * from ${this.tableName}`)
      }
      if (this.isCheckSql) {
        this.isCheckSql = false
      }
      if(this.sqlForm.rightSql == this.oldRightSql){
        this.isCheckSql = true
      }
    },
    joinTablesSqlMap() {
      if (this.joinTablesSql) {
        const list = validArray(this.joinTablesSql.split(' left join '))
        if (list.length === 1) {
          this.sqlForm.leftSql = format(list[0])
        } else if (list.length > 1) {
          this.sqlForm.leftSql = format(list[0])
          this.sqlForm.rightSql = format(
            ` left join ${list
              .filter((item, index) => index !== 0)
              .join(' left join ')}`
          )
        this.oldRightSql = format(
            ` left join ${list
              .filter((item, index) => index !== 0)
              .join(' left join ')}`
          )
        }
      }
    },
    handleDelete(index) {
      if (index !== this.joinTableList.length - 1) {
        this.$confirm('确认删除?', '点击删除会清空下面所有关联信息', {
          cancelButtonText: '取消',
          confirmButtonText: '确定',
          type: 'warning',
          closeOnClickModal: false
        }).then(() => {
          this.joinTableList = []
        })
      } else {
        this.joinTableList.splice(index, 1)
      }
    },
    generateSql() {
      this.sqlDialogVisible = true
      this.joinTableList = []
    },
    handleClose() {
      this.sqlDialogVisible = false
    },
    handleSubmitDialog() {
      if (this.joinTableList.length == 1) {
        for (let i = 0; i < this.joinTableList.length; i++) {
          if (this.joinTableList[i].connected) {
            if (this.joinTableList[i].relation.length > 0) {
              for (let j = 0; j < this.joinTableList[i].relation.length; j++) {
                //判断有没有添加关联关系
                if (
                  !this.joinTableList[i].relation[j].relatedBind ||
                  !this.joinTableList[i].relation[j].connectedBind
                ) {
                  Message.warning('请先添加关联关系')
                  return
                }
              }
            }
          } else if (!this.joinTableList[i].related) {
            Message.warning('请先添加被关联表')
            return
          }
        }
      }
      if (this.joinTableList.length > 1) {
        for (let i = 0; i < this.joinTableList.length; i++) {
          if (this.joinTableList[i].relation.length > 0) {
            for (let j = 0; j < this.joinTableList[i].relation.length; j++) {
              //判断有没有添加关联关系
              if (
                !this.joinTableList[i].relation[j].relatedBind ||
                !this.joinTableList[i].relation[j].connectedBind
              ) {
                Message.warning('请先添加关联关系')
                return
              }
            }
          }
        }
      }
      const leftSqlList = this.joinTableList.map(item => item.connected)
      if (validArray(leftSqlList).length > 0) {
        this.sqlForm.leftSql = format(
          `select ${this.tableName}.*,${leftSqlList.join('.*,')}.* from ${
            this.tableName
          }`
        )
      } else {
        this.sqlForm.leftSql = format(`select * from ${this.tableName}`)
      }

      let rightSql = ''
      for (let i = 0; i < this.joinTableList.length; i++) {
        if (i == 0) {
          if (this.joinTableList[i].connected) {
            rightSql =
              rightSql + ` left join ${this.joinTableList[i].connected} on `
          }
        } else {
          rightSql =
            rightSql + ` left join ${this.joinTableList[i].connected} on `
        }
        for (let j = 0; j < this.joinTableList[i].relation.length; j++) {
          const relatedBind = `${this.joinTableList[i].related}.${this.joinTableList[i].relation[j].relatedBind}`
          const connectedBind = `${this.joinTableList[i].connected}.${this.joinTableList[i].relation[j].connectedBind}`
          if (
            this.joinTableList[i].relation[j].relatedBind &&
            this.joinTableList[i].relation[j].connectedBind
          ) {
            if (j == 0) {
              rightSql = rightSql + `${relatedBind} = ${connectedBind}`
            } else {
              rightSql = rightSql + ` and ${relatedBind} = ${connectedBind}`
            }
          }
        }
      }
      this.sqlForm.rightSql = format(rightSql || '')
      this.isCheckSql = false
      this.sqlDialogVisible = false
    },
    getCurrentSql() {
      return this.sql
    },
    getSubmitData() {
      let submitData = []
      if (this.sqlForm.rightSql) {
        const rightSql = ` ${this.sqlForm.rightSql}`.replaceAll('\n', ' ')
        const rightSqlList = rightSql.split(' left join ')
        if (validArray(rightSqlList).length > 0) {
          submitData = validArray(rightSqlList).map(item => {
            const itemList = item.split(' on ')
            return {
              join: itemList[0],
              junction: 'and',
              condition: this.getAssociationItem(itemList)
            }
          })
        }
      }
      return {
        joinTables: JSON.stringify(submitData),
        isCheckSql: this.isCheckSql
      }
    },
    getAssociationItem(item) {
      let condition = []
      if (item && item.length > 1 && item[1].includes(' and ')) {
        condition = item[1].split(' and ').map(it => {
          return {
            ...this.getConditionList(it),
            property: '',
            operator: '1',
            dataType: '',
            value: '',
            compType: '1'
          }
        })
      } else {
        condition.push({
          ...this.getConditionList(item[1]),
          property: '',
          operator: '1',
          dataType: '',
          value: '',
          compType: '1'
        })
      }
      return condition
    },
    getConditionList(row) {
      const list = row && row.split(' = ')
      if (list && list.length) {
        const mainList = list && list[0] && list[0].split('.')
        const refList = list[1] && list[1].split('.')
        return {
          main:
            mainList[0] === this.tableName.toUpperCase()
              ? `t.${mainList[1]}`
              : list[0],
          ref: refList && refList[1]
        }
      } else {
        return {}
      }
    },
    checkSql() {
      if (!this.sql) {
        this.$message({type: 'warning', message: '请输入sql语句'})
        return
      }
      this.$message.warning(
        '当前关联表已经发生变化，相关关联表配置将全部失效，请重新手动修改配置项。'
      )
      let param = {
        sql: this.sql,
        dsName: this.dsName,
        formKey: this.data.bpmDataTemplate.formKey,
        instKey: !!this.data.bpmDataTemplate.defId
      }
      form.joinCheckSql(param).then(({data}) => {
        if (data.state) {
          this.$message({type: 'success', message: data.message})
          this.isCheckSql = true
          localStorage.setItem(this.formAlias, true)
          // 更新下拉选项信息
          if (data.value && data.value.length) {
            this.$store.commit('form/setFormListCommonVar', data.value)
          }
        }
      })
    },
    //添加一个联合条件条件
    addUnionCondition(indexStr, rowIndex) {
      var data = this.joinTableList[rowIndex].condition
      if (indexStr == 'root') {
        data.push({junction: 'or', condition: []})
      } else {
        var indexArr = []
        if (indexStr) indexArr = indexStr.split(',')
        for (var i = 0; i < data.length; i++) {
          if (indexArr.length > 0 && i == indexArr[0]) {
            if (indexArr.length > 1) {
              for (var j = 0; j < data[i].condition.length; j++) {
                if (j == indexArr[1]) {
                  data[i].condition[j].condition.push({
                    junction: 'or',
                    condition: []
                  })
                  break
                }
              }
            } else {
              data[i].condition.push({junction: 'or', condition: []})
            }
            break
          }
        }
      }
      this.joinTableList[rowIndex].condition = data
      this.buildConditionTree(this.joinTableList[rowIndex], rowIndex)
    },
    removeCondition(indexStr, rowIndex) {
      var indexArr = []
      if (indexStr) indexArr = indexStr.split(',')
      if (indexArr.length > 0) {
        var data = this.joinTableList[rowIndex].condition
        for (var i = 0; i < data.length; i++) {
          if (i == indexArr[0]) {
            if (indexArr.length > 1) {
              for (var j = 0; j < data[i].condition.length; j++) {
                if (j == indexArr[1]) {
                  if (indexArr.length > 2) {
                    for (
                      var z = 0;
                      z < data[i].condition[j].condition.length;
                      z++
                    ) {
                      if (z == indexArr[2]) {
                        data[i].condition[j].condition.splice(z, 1)
                        break
                      }
                    }
                  } else {
                    data[i].condition.splice(j, 1)
                  }
                  break
                }
              }
            } else {
              data.splice(i, 1)
            }
            break
          }
        }
        this.joinTableList[rowIndex].condition = data
        this.buildConditionTree(this.joinTableList[rowIndex], rowIndex)
      }
    },
    //添加一个联合
    addCondition(indexStr, rowIndex) {
      var data = this.joinTableList[rowIndex].condition
      if (indexStr == 'root') {
        data.push(JSON.parse(JSON.stringify(this.defaultCondition)))
      } else {
        var indexArr = []
        if (indexStr) indexArr = indexStr.split(',')
        for (var i = 0; i < data.length; i++) {
          if (indexArr.length > 0 && i == indexArr[0]) {
            if (indexArr.length > 1) {
              for (var j = 0; j < data[i].condition.length; j++) {
                if (j == indexArr[1]) {
                  data[i].condition[j].condition.push(
                    JSON.parse(JSON.stringify(this.defaultCondition))
                  )
                  break
                }
              }
            } else {
              data[i].condition.push(
                JSON.parse(JSON.stringify(this.defaultCondition))
              )
            }
            break
          }
        }
      }
      this.joinTableList[rowIndex].condition = data
      this.buildConditionTree(this.joinTableList[rowIndex], rowIndex)
    },
    changecondition(index, rowIndex) {
      let branchList = this.joinTableList[rowIndex].branchList
      var newVal = branchList[index].newjunction
      const row = this.joinTableList[rowIndex]
      // and, or, 3(添加条件), 4(添加联合条件), 5(删除)
      if (newVal == '3' || newVal == '4' || newVal == '5') {
        branchList[index].newjunction = branchList[index].oldjunction
        var indexStr = branchList[index].indexStr
        if (newVal == '3') {
          this.addCondition(indexStr, rowIndex)
        } else if (newVal == '4') {
          this.addUnionCondition(indexStr, rowIndex)
        } else {
          this.$confirm(
            '确定要删除此联合条件及其下属的所有子条件吗？',
            '提示',
            {
              cancelButtonText: '取消',
              confirmButtonText: '确定',
              type: 'warning',
              closeOnClickModal: false
            }
          ).then(() => {
            this.removeCondition(indexStr, rowIndex)
          })
        }
      } else {
        branchList[index].oldjunction = branchList[index].newjunction
        var indexStr = branchList[index].indexStr
        var indexArr = indexStr.split(',')
        if (indexStr == 'root') {
          row.junction = newVal
        } else if (indexArr.length == 1) {
          row.condition[indexStr].junction = newVal
        } else if (indexArr.length == 2) {
          row.condition[indexArr[0]].condition[indexArr[1]].junction = newVal
        }
      }
    },
    //获取条件总数
    getyIncaseNum(data) {
      var sum = 0
      for (var i = 0; i < data.length; i++) {
        if (data[i].condition && data[i].condition.length > 0) {
          for (var j = 0; j < data[i].condition.length; j++) {
            if (
              data[i].condition[j].condition &&
              data[i].condition[j].condition.length > 0
            ) {
              for (var z = 0; z < data[i].condition[j].condition.length; z++) {
                sum++
              }
            } else {
              sum++
            }
          }
        } else {
          sum++
        }
      }
      return sum
    },
    buildData(conditionData, pathArr, tableArr, branchArr) {
      let curYIndex = 0
      let data = conditionData.condition
      //算三级节点总共分支个数
      let yIncaseNum =
        this.getyIncaseNum(conditionData.condition) > 1
          ? this.getyIncaseNum(conditionData.condition)
          : 1
      //第一个节点 this.Mtop 最后一个节点Mtop+this.YIncase*（yIncaseNum-1）
      let startY1 = (this.Mtop * 2 + this.YIncase * (yIncaseNum - 1)) / 2

      branchArr.push({
        newjunction: conditionData.junction,
        oldjunction: conditionData.junction,
        style: 'left:' + (this.Mleft - 35) + 'px; top:' + (startY1 - 15) + 'px',
        indexStr: 'root',
        condition: 'noDel'
      })
      for (var i = 0; i < data.length; i++) {
        if (data[i].condition) {
          var curchildNum = this.getyIncaseNum(data[i].condition)
          //如果该节点，没有分支条件，则保留节点
          var isEmpty0 = false
          if (curchildNum < 1) {
            curchildNum = 1
            isEmpty0 = true
          }
          //计算一级节点和该节点的连线
          var startY2 =
            (this.Mtop * 2 + this.YIncase * (2 * curYIndex + curchildNum - 1)) /
            2
          var path =
            'M' +
            this.Mleft +
            ',' +
            startY1 +
            'C' +
            this.Mleft +
            ',' +
            startY2 +
            ',' +
            this.Mleft +
            ',' +
            startY2 +
            ',' +
            (this.Mleft + this.XIncase) +
            ',' +
            startY2
          pathArr.push(path)
          branchArr.push({
            newjunction: data[i].junction,
            oldjunction: data[i].junction,
            style:
              'left:' +
              (this.Mleft + this.XIncase - 35) +
              'px; top:' +
              (startY2 - 15) +
              'px',
            indexStr: '' + i
          })
          if (isEmpty0) curYIndex++

          for (var j = 0; j < data[i].condition.length; j++) {
            //如果第三级节点有分支，则计算分支
            if (data[i].condition[j].condition) {
              //计算改节点分支个数
              let curchildNum2 = this.getyIncaseNum(
                data[i].condition[j].condition
              )
              //如果该节点，没有分支条件，则保留节点,默认其占一行
              let isEmpty = false
              if (curchildNum2 < 1) {
                curchildNum2 = 1
                isEmpty = true
              }
              // 改分支第一个节点纵坐标= this.Mtop+this.YIncase*curYIndex  上一个节点纵坐标加上递增值
              // 改分支最后节点纵坐标=改分支第一个节点纵坐标 +计算改节点分支个数*y递增值 this.Mtop+this.YIncase*curYIndex+this.YIncase*(curchildNum2-1)
              // 计算改节点的纵坐标。（改分支第一个节点纵坐标+该分支的最后一个纵坐标）/2
              // 该节点起始点纵坐标=  this.Mtop+this.YIncase*curYIndex+ this.Mtop+this.YIncase*curYIndex+this.YIncase*(curchildNum2-1)
              let startY3 =
                (this.Mtop * 2 +
                  this.YIncase * (2 * curYIndex + curchildNum2 - 1)) /
                2
              //改分支指引线的终点的纵坐标等于startY2
              let path =
                'M' +
                (this.Mleft + this.XIncase) +
                ',' +
                startY2 +
                'C' +
                (this.Mleft + this.XIncase) +
                ',' +
                startY3 +
                ',' +
                (this.Mleft + this.XIncase) +
                ',' +
                startY3 +
                ',' +
                (this.Mleft + this.XIncase * 2) +
                ',' +
                startY3
              pathArr.push(path)
              branchArr.push({
                newjunction: data[i].condition[j].junction,
                oldjunction: data[i].condition[j].junction,
                style:
                  'left:' +
                  (this.Mleft + this.XIncase * 2 - 35) +
                  'px; top:' +
                  (startY3 - 15) +
                  'px',
                indexStr: i + ',' + j,
                condition: 'noAdd'
              })
              if (isEmpty) {
                curYIndex++
              }
              for (let z = 0; z < data[i].condition[j].condition.length; z++) {
                let obj = data[i].condition[j].condition[z]
                obj.style =
                  'left:' +
                  (this.Mleft + this.XIncase * 3) +
                  'px; top:' +
                  (this.Mtop + this.YIncase * curYIndex - 19) +
                  'px'
                obj.indexStr = i + ',' + j + ',' + z
                tableArr.push(obj)
                //改分支下所有节点的起始纵坐标为startY3，终点纵坐标根据该节点位置决定
                let path =
                  'M' +
                  (this.Mleft + this.XIncase * 2) +
                  ',' +
                  startY3 +
                  'C' +
                  (this.Mleft + this.XIncase * 2) +
                  ',' +
                  (this.Mtop + this.YIncase * curYIndex) +
                  ',' +
                  (this.Mleft + this.XIncase * 2) +
                  ',' +
                  (this.Mtop + this.YIncase * curYIndex) +
                  ',' +
                  (this.Mleft + this.XIncase * 3) +
                  ',' +
                  (this.Mtop + this.YIncase * curYIndex)
                pathArr.push(path)
                curYIndex++
              }
            } else {
              //第二级节点没有分支
              let obj = data[i].condition[j]
              obj.style =
                'left:' +
                (this.Mleft + this.XIncase * 2) +
                'px; top:' +
                (this.Mtop + this.YIncase * curYIndex - 19) +
                'px'
              obj.indexStr = i + ',' + j
              tableArr.push(obj)
              //计算改分支的路径。因为是第二节点。startY2
              let path =
                'M' +
                (this.Mleft + this.XIncase) +
                ',' +
                startY2 +
                'C' +
                (this.Mleft + this.XIncase) +
                ',' +
                (this.Mtop + this.YIncase * curYIndex) +
                ',' +
                (this.Mleft + this.XIncase) +
                ',' +
                (this.Mtop + this.YIncase * curYIndex) +
                ',' +
                (this.Mleft + this.XIncase * 2) +
                ',' +
                (this.Mtop + this.YIncase * curYIndex)
              pathArr.push(path)
              curYIndex++
            }
          }
        } else {
          let obj = data[i]
          obj.style =
            'left:' +
            (this.Mleft + this.XIncase) +
            'px; top:' +
            (this.Mtop + this.YIncase * curYIndex - 19) +
            'px'
          obj.indexStr = '' + i
          tableArr.push(obj)
          let path =
            'M' +
            this.Mleft +
            ',' +
            startY1 +
            'C' +
            this.Mleft +
            ',' +
            (this.Mtop + this.YIncase * curYIndex) +
            ',' +
            this.Mleft +
            ',' +
            (this.Mtop + this.YIncase * curYIndex) +
            ',' +
            (this.Mleft + this.XIncase) +
            ',' +
            (this.Mtop + this.YIncase * curYIndex)
          pathArr.push(path)
          curYIndex++
        }
      }
    },
    //根据条件数组构建条件分支界面
    buildConditionTree(data, rowIndex) {
      let pathArr = []
      let tableArr = []
      let branchArr = []
      this.buildData(data, pathArr, tableArr, branchArr)
      const row = this.joinTableList[rowIndex]
      this.$set(row, 'pathList', pathArr)
      this.$set(row, 'branchList', branchArr)
      this.$set(row, 'tabList', tableArr)
      //取路径最后一条数据，因为该条数据的高度距离顶部最大
      let lastPath = pathArr[pathArr.length - 1]
      let lastIndexArr = []
      if (lastPath) lastIndexArr = lastPath.split(',')
      //取最后一个坐标点。终点纵坐标为整个svg中最大的纵坐标
      let lastYIndex = lastIndexArr[lastIndexArr.length - 1]
      //设置svg的高度为最大纵坐标+100，从而实现svg页面高度自适应
      if (lastYIndex) {
        this.svgHeight = parseInt(lastYIndex) + 50 + 'px'
      }
      this.createSvgHtml(pathArr, rowIndex)
    },
    //构建svg图形页面
    createSvgHtml(pathArr, rowIndex) {
      const row = this.joinTableList[rowIndex]
      row.svgHtml = ''
      var html =
        '<svg height="' +
        this.svgHeight +
        '" version="1.1" width="692" xmlns="http://www.w3.org/2000/svg" style="overflow: hidden; position: absolute; left: 0">'
      for (var i = 0; i < pathArr.length; i++) {
        html +=
          '<path fill="none" stroke="#787878"' +
          'd="' +
          row.pathList[i] +
          '" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>'
      }
      html += '</svg>'
      this.$set(row, 'svgHtml', html)
    },
    getSaveData() {
      const errorCb = this.$message.warning.bind(null, '请将关联表配置完整！')
      // const _validateFn = function(element) {
      //   if (
      //     (!element.main || !element.ref) &&
      //     (!element.condition || !element.junction)
      //   ) {
      //     return false
      //   }
      //   if (element.condition && element.condition.length) {
      //     for (let i = 0; i < element.condition.length; i++) {
      //       let result = _validateFn.call(null, element.condition[i])
      //       if (result === false) {
      //         return false
      //       }
      //     }
      //   }
      //   return true
      // }
      // for (let index = 0; index < this.joinTableList.length; index++) {
      //   const element = this.joinTableList[index]
      //   if (!element.join || !element.condition) {
      //     errorCb()
      //     return 'false'
      //   }
      //   for (let j = 0; j < element.condition.length; j++) {
      //     const ons = element.condition[j]
      //     if (!_validateFn.call(null, ons)) {
      //       errorCb()
      //       return 'false'
      //     }
      //   }
      // }
      let saveDatas = JSON.parse(JSON.stringify(this.joinTableList))
      saveDatas.forEach(saveData => {
        delete saveData.tabList
        delete saveData.svgHtml
        delete saveData.pathList
        delete saveData.branchList
      })
      return JSON.stringify(saveDatas)
    },
    initData() {
      this.joinTableList = JSON.parse(this.joinTablesStr || '[]')
      // if (localStorage.getItem(this.formAlias)) {
      //   this.isCheckSql = JSON.parse(localStorage.getItem(this.formAlias))
      // } else {
      this.isCheckSql = !this.sqlForm.rightSql ? true : false
      // }
      this.getDbTable()
      //获取主表的字段
      this.getFields(this.tableName.toUpperCase())
      //获取关联表字段
      // this.joinTableList &&
      //   this.joinTableList.forEach(ele => {
      //     this.getFields(ele.connected)
      //   })
    },
    joinTableChange(row) {
      row.condition = []
      this.getFields(row.connected, row)
    },
    getDbTable() {
      form
        .getTableList({dsalias: this.dataSourceAlias, isTable: 1})
        .then(resp => {
          this.dbTableList = resp.data
          //删除主表记录，再添加第一条关联表
          if (this.dbTableList && this.dbTableList.length > 0) {
            let index = this.dbTableList.findIndex(item => {
              if (item.name.toUpperCase() == this.tableName.toUpperCase()) {
                return true
              }
            })
            this.dbTableList.splice(index, 1)
          }
          //添加第一条关联表
          this.dbTableList.push({
            comment: this.formName,
            name: this.tableName.toUpperCase()
          })
        })
    },
    getFields(tableName) {
      if (this.fieldsOptionsMap[tableName]) {
        return
      }
      let params = {
        dsalias: this.dataSourceAlias,
        isTable: 1,
        objName: tableName
      }
      form.getTableFields(params).then(resp => {
        if (resp.data && resp.data.table) {
          this.$set(
            this.fieldsOptionsMap,
            tableName,
            resp.data.table.columnList
          )
        }
      })
    },
    addJoin() {
      let conditionData = JSON.parse(JSON.stringify(this.conditionObj))
      //算三级节点总共分支个数
      let yIncaseNum =
        this.getyIncaseNum(conditionData.condition) > 1
          ? this.getyIncaseNum(conditionData.condition)
          : 1
      //第一个节点 this.Mtop 最后一个节点Mtop+this.YIncase*（yIncaseNum-1）
      let startY1 = (this.Mtop * 2 + this.YIncase * (yIncaseNum - 1)) / 2
      let branchList = []
      branchList.push({
        newjunction: conditionData.junction,
        oldjunction: conditionData.junction,
        style: 'left:' + (this.Mleft - 35) + 'px; top:' + (startY1 - 15) + 'px',
        indexStr: 'root',
        condition: 'noDel'
      })
      this.joinTableList.push({
        join: '',
        condition: [],
        branchList,
        junction: 'and',
        fieldRelatedList: [],
        relation: [{}]
      })
      if (this.joinTableList.length > 1) {
        this.joinTableList.map(item => {
          return {
            ...item,
            fieldRelatedList: [{tableName: this.tableName}, {}]
          }
        })
      }
    },
    //添加sql关联表
    addSqlList() {
      //没添加被关联表不允许添加第二组数据
      if (this.joinTableList.length === 1 && !this.joinTableList[0].connected) {
        return this.$message.warning('请先添加被关联表')
      }
      let tables = [] //从第二组开始只能选择的数据库表
      //添加了被关联表
      if (this.joinTableList.length > 0) {
        for (let i = 0; i < this.joinTableList.length; i++) {
          if (this.joinTableList[i].relation.length > 0) {
            for (let j = 0; j < this.joinTableList[i].relation.length; j++) {
              //判断有没有添加关联关系
              if (
                !this.joinTableList[i].relation[j].relatedBind ||
                !this.joinTableList[i].relation[j].connectedBind
              ) {
                return this.$message.warning('请先添加关联关系')
              }
            }
          }
          if (this.joinTableList[i].related) {
            tables.push(this.joinTableList[i].related)
          }
          if (this.joinTableList[i].connected) {
            tables.push(this.joinTableList[i].connected)
          }
        }
      }
      //先把所有数据库表type修改为1
      for (let j = 0; j < this.dbTableList.length; j++) {
        this.dbTableList[j].type = '1'
        if (this.dbTableList[j].name == this.tableName) {
          this.dbTableList[j].type = '2'
        }
      }
      //根据上面的关联关系修改数据库表type为2给下一组选择
      if (tables.length > 0) {
        for (let i = 0; i < this.dbTableList.length; i++) {
          if (tables.indexOf(this.dbTableList[i].name) != -1) {
            this.dbTableList[i].type = '2' //标记再次添加一组关联表的时候默认只能选择type为2的数据库表
          }
        }
      }
      //满足以上条件后
      this.joinTableList.push({
        related: this.tableName.toUpperCase(),
        connected: '',
        relation: [{}]
      })
    }
  }
}
</script>
<style lang="scss" scoped>
::v-deep {
  .el-dialog {
    min-width: 1200px;
  }
  .sql-dialog {
    .association-item-wrap {
      .el-select {
        width: 388px;
        .el-input__inner {
          border-radius: 2px;
        }
      }
    }
    .incidence-relation-item {
      .el-select {
        width: 248px;
        .el-input__inner {
          border-radius: 2px;
        }
      }
    }
  }
}
.join-table-setting {
  border: 1px solid #e6e6e6;
  box-sizing: border-box;
  .sql-form {
    padding: 40px;

    .sql-btn {
      height: 32px;
      line-height: 32px;
      padding: 0 15px;
      border: 1px solid $--color-primary;
      color: $--color-primary;
    }
    .verification-sql {
      margin-top: 10px;
    }
    .sql-textarea {
      ::v-deep {
        .el-textarea__inner {
          padding-left: 10px;
          border: none;
          background: rgba(243, 243, 243, 0.39);
          border-radius: 0 0 2px 2px;
          color: #51b43a;
        }
      }
    }
    .sql-left {
      border-bottom: 1px solid #eee;
      border-radius: 2px 2px 0 0;
      ::v-deep {
        .el-textarea__inner {
          color: #cccccc;
        }
      }
    }
    ::v-deep {
      .CodeMirror-wrap,
      .CodeMirror-gutters {
        background: rgba(243, 243, 243, 0.39);
      }
    }
  }
}
.association-table {
  margin-top: 24px;
  .association-item {
    border: 1px solid #ebebeb;
    border-top: none;
    &:first-child {
      border-top: 1px solid #ebebeb;
    }
  }
  .label {
    margin-right: 12px;
    color: #888;
  }
  .association-item-wrap {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;

    .left-box {
      display: flex;
      align-items: center;
      justify-content: space-between;
      flex: 1;
      .left {
        height: 32px;
        line-height: 32px;
      }
      .label {
        margin-right: 12px;
      }
      .value {
        padding-left: 10px;
        display: inline-block;
        width: 348px;
        background: #ececec;
        border-radius: 2px;
        color: #999;
      }
      ::v-deep {
        .right {
          .inputs.ht-form-inputs__inline {
            width: 348px;
          }
        }
      }
    }
    .right-box {
      width: 140px;
      text-align: right;
      padding-right: 20px;
    }
  }
  .incidence-relation {
    padding: 16px;
    border-top: 1px solid #ebebeb;
    .incidence-relation-item {
      padding: 12px;
      background: rgba(248, 248, 248, 0.39);
      border-radius: 2px;
      display: flex;
      justify-content: space-between;
      .relate {
        padding-right: 8px;
      }
      .connect {
        padding-left: 16px;
        padding-right: 8px;
      }
    }
  }
}
.form-table > tbody > tr > th {
  padding: 5px;
}
.custom_condition_tab {
  width: 700px;
  position: absolute;
}
div >>> .labelrag > .selected_search {
  width: 60px;
  border: none;
  outline: none;
  height: 22px;
}
div >>> .labelrag > .el-select > .el-input > .el-input__inner {
  padding: 0px;
  border: none;
  height: 26px;
}
div >>> .labelrag > .selected_search {
  width: 60px;
  border: none;
  outline: none;
  height: 22px;
}
.labelrag {
  padding: 0.2em 0.2em 0.3em;
  font-size: 75%;
  font-weight: 700;
  line-height: 1;
  background-color: #fff;
  text-align: center;
  white-space: nowrap;
  vertical-align: baseline;
  border-radius: 12px;
  width: 70px;
  line-height: 20px;
  border: solid 1px;
  position: absolute;
  z-index: 3;
}
.table > thead > tr > th,
.table > thead > th,
.table > tbody > tr > th,
.table > tfoot > tr > th,
.table > thead > tr > td,
.table > tbody > tr > td,
.table > tfoot > tr > td {
  border-top: 1px solid #e7eaec;
  border-left: 1px solid #e7eaec;
  line-height: 1.42857;
  vertical-align: middle;
  padding: 4px;
}

.table > tbody > tr > td {
  text-align: center;
}
.table {
  border-bottom: 1px solid #e7eaec;
  border-right: 1px solid #e7eaec;
  border-spacing: 0;
}
.table >>> .el-button {
  padding: 6px 8px;
}
.field_select {
  display: flex;
  flex-direction: row;
  justify-content: space-evenly;
}
</style>
