<!--
 * @Author: Jason Liu
 * @Date: 2022-06-15 16:39:54
 * @Desc: 设置表的关联关系
-->
<template>
  <a-drawer
    title="设置表的关联关系"
    width="80%"
    :visible="show"
    :loading="loading"
    @close="show = false"
    :destroy-on-close="true"
    class="setTableJoinCard"
  >
    <a-card class="no_border" size="small">
      <template slot="title"> 表关联设置 </template>
      <template slot="extra">
        <a-button type="link" @click="addJoin">
          <a-icon type="deployment-unit" />添加表关联
        </a-button>
      </template>
      <div class="join_list">
        <a-descriptions bordered size="small">
          <template v-for="(table, i) in nodeData.tables">
            <a-descriptions-item label="表名" :key="`table_code_${i}`">
              <a-switch
                checked-children="主"
                un-checked-children="从"
                v-model="table.isMain"
                @change="changeSetMainTable(table)"
              />
              {{ table.tableCode }}
            </a-descriptions-item>
            <a-descriptions-item label="别名" :key="`table_asname_${i}`">
              <a-input
                v-model.lazy="table.asName"
                placeholder="请输入表别名"
                @change="getConditionList"
              />
            </a-descriptions-item>
            <a-descriptions-item label="表描述" :key="`table_name_${i}`">
              {{ table.tableName }}
            </a-descriptions-item>
          </template>
        </a-descriptions>
        <template v-for="(join, i) in nodeData.joins">
          <div class="join_config" :key="i">
            <div class="right_delete" @click="deleteJoin(i)">
              <svg-icon type="icon_right_delete" />
            </div>
            <a-row class="join_table">
              <a-col :span="2" class="a_label">关联方式：</a-col>
              <a-col :span="3">
                <a-select
                  placeholder="请选择关联方式"
                  v-model="join.joinType"
                  :options="joinTypes"
                >
                </a-select>
              </a-col>
              <a-col :span="2" class="a_label">关联表：</a-col>
              <a-col :span="13">
                <a-select
                  placeholder="请选择关联表"
                  v-model="join.right.tableCode"
                  :options="
                    nodeData.tables
                      .filter((table) => {
                        return !table.isMain;
                      })
                      .map((item) => {
                        return {
                          value: item.asName,
                          label: item.asName,
                        };
                      })
                  "
                >
                </a-select>
              </a-col>
              <a-col :span="4" class="a_label">
                <a-button type="link" @click="addCondition(join)">
                  添加关联条件
                </a-button>
              </a-col>
            </a-row>
            <template v-for="(condition, j) in join.conditions">
              <div class="condition_body" :key="j">
                <a-row :gutter="[10, 12]">
                  <a-col :span="10">
                    <a-cascader
                      :options="conditionList"
                      placeholder="请选择关联字段"
                      :show-search="{ filter }"
                      @change="changeCondition(condition, 'leftmap', 'left')"
                      v-model="condition.leftmap"
                    >
                      <template
                        slot="displayRender"
                        slot-scope="{ selectedOptions }"
                      >
                        <template v-if="selectedOptions.length > 0">
                          <span class="table_name">
                            {{ selectedOptions[0].label }}
                          </span>
                          <span class="column_name">
                            .{{ selectedOptions[1].value }}
                          </span>
                        </template>
                      </template>
                    </a-cascader>
                  </a-col>
                  <a-col :span="2">
                    <a-select
                      placeholder="条件"
                      v-model="condition.relation"
                      :options="relationType"
                    >
                    </a-select>
                  </a-col>
                  <a-col :span="10">
                    <a-cascader
                      :options="conditionList"
                      placeholder="请选择关联字段"
                      :show-search="{ filter }"
                      v-model="condition.rightmap"
                      @change="changeCondition(condition, 'rightmap', 'right')"
                    >
                      <template
                        slot="displayRender"
                        slot-scope="{ selectedOptions }"
                      >
                        <template v-if="selectedOptions.length > 0">
                          <span class="table_name">
                            {{ selectedOptions[0].label }}
                          </span>
                          <span class="column_name">
                            .{{ selectedOptions[1].value }}
                          </span>
                        </template>
                      </template>
                    </a-cascader>
                  </a-col>
                  <a-col :span="2" class="a_label">
                    <a-button
                      type="link"
                      class="a_danger"
                      @click="deleteCondition(join, j)"
                    >
                      删除
                    </a-button>
                  </a-col>
                </a-row>
              </div>
            </template>
          </div>
        </template>
        <div class="add_tool" @click="addJoin">
          <a-button type="link">
            <a-icon type="deployment-unit" />添加表关联
          </a-button>
        </div>
      </div>
    </a-card>
    <div class="a_foot_nuttop">
      <a-button @click="show = false"> 关闭 </a-button>
      &nbsp;
      <a-button type="primary" @click="fixed"> 确定 </a-button>
    </div>
  </a-drawer>
</template>

<script>
export default {
  name: "setTableJoin",
  props: {
    value: {
      type: Boolean,
      default: false,
    },
  },
  inject: ["getNode", "setNodeData"],

  data() {
    return {
      loading: false,
      show: this.value,
      mainTable: {
        tableCode: undefined,
        tableName: undefined,
      },
      //关联类型
      joinTypes: [
        { value: "innerjoin", label: "inner join" },
        { value: "leftjoin", label: "left join" },
        { value: "rightjoin", label: "right join" },
        { value: "fulljoin", label: "full join" },
        { value: "crossjoin", label: "cross join" },
      ],
      relationType: [
        { value: "=", label: "=" },
        { value: ">", label: ">" },
        { value: "<", label: "<" },
        { value: ">=", label: ">=" },
        { value: "<=", label: "<=" },
      ],
      conditionList: [], //关联字段
      nodeData: {
        tables: [],
        joins: [],
      },
    };
  },
  methods: {
    fixed() {
      //整合数据
      this.nodeData.tables.forEach((table) => {
        //遍历所有的表格
        this.nodeData.joins.forEach((join) => {
          // if (table.asName == join.right.tableCode) {
          //   join.right.code = table.tableCode;
          // }
          join.conditions.forEach((condition) => {
            if (
              condition.left.tableCode == table.tableCode &&
              condition.leftmap[0] == table.asName
            ) {
              condition.left.asName = table.asName;
            }
            if (
              condition.right.tableCode == table.tableCode &&
              condition.rightmap[0] == table.asName
            ) {
              condition.right.asName = table.asName;
            }
          });
        });
        this.nodeData.columns.forEach((col) => {
          if (table.tableCode == col.tableCode) {
            col.tableAsName = table.asName;
          }
        });
      });
      debugger
      this.setNodeData(this.nodeData);
      this.show = false;
    },

    /**
     * @Author: Jason Liu
     * @description: 修改设置主表信息
     */
    changeSetMainTable(row) {
      this.nodeData.tables = this.nodeData.tables.map((item) => {
        if (item.asName != row.asName) {
          item.isMain = false;
        }
        return item;
      });
      if (
        !this.nodeData.tables.find((item) => {
          return item.isMain;
        })
      ) {
        this.$message.warning("必须设置一条数据是主表。");
        this.nodeData.tables[0].isMain = true;
      }
      this.nodeData.joins = [];
    },
    /**
     * @Author: Jason Liu
     * @description: 查询关联表信息
     */
    filter(inputValue, path) {
      return path.some(
        (option) =>
          option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1
      );
    },
    /**
     * @Author: Jason Liu
     * @description: 获取配置的node信息
     */
    getSetNode() {
      this.nodeData = this.getNode().data;
      this.mainTable = this.nodeData.tables.find((row) => {
        return row.isMain;
      });
      this.getConditionList();
    },
    /**
     * @Author: Jason Liu
     * @description: 获取关联表信息
     */
    getConditionList() {
      let queue = {};
      this.conditionList = this.nodeData.tables.map((table) => {
        if (queue[table.asName]) {
          //确保别名唯一
          table.asName = `${table.asName}_${queue[table.asName]}`;
          queue[table.asName]++;
        } else {
          queue[table.asName] = 1;
        }
        let value = table.tableCode;
        if (table.asName) {
          value = table.asName;
        }
        return {
          value: value,
          label: table.asName,
          children: table.columns.map((column) => {
            return {
              value: column.columnName,
              label: column.description
                ? `${column.description}(${column.columnName})`
                : column.columnName,
            };
          }),
        };
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 修改关联
     */
    changeCondition(row, map, send) {
      let value = row[map];
      this.nodeData.tables.forEach((condition) => {
        if (condition.asName == value[0]) {
          row[send] = {
            tableCode: condition.tableCode,
            tableName: condition.tableName,
            asName: condition.asName,
            tableId: condition.tableId,
            asName: condition.asName,
            column: condition.columns.find((item) => {
              return item.columnName == value[1];
            }),
          };
        }
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 添加配置条件
     */
    addCondition(join) {
      join.conditions.push({
        type: "def", //通过关系的方式关联
        leftmap: [],
        left: {
          tableCode: undefined,
          tableName: undefined,
          tableId: undefined,
          column: {},
        },
        relation: "=",
        rightmap: [],
        right: {
          tableCode: undefined,
          tableName: undefined,
          tableId: undefined,
          column: {},
        },
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 删除条件
     */
    deleteCondition(join, i) {
      join.conditions.splice(i, 1);
    },
    /**
     * @Author: Jason Liu
     * @description: 添加join
     */
    addJoin() {
      this.nodeData.joins.push({
        joinType: "innerjoin", //关联方式
        right: {
          //关联表
          tableCode: undefined,
          tableName: undefined,
          tableId: undefined,
          asName: undefined,
        },
        conditions: [
          //关联字段
          {
            type: "def", //通过关系的方式关联
            leftmap: [],
            left: {
              tableCode: undefined,
              tableName: undefined,
              tableId: undefined,
              asName: undefined,
              column: {},
            },
            relation: "=",
            rightmap: [],
            right: {
              tableCode: undefined,
              tableName: undefined,
              tableId: undefined,
              asName: undefined,
              column: {},
            },
          },
        ],
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 删除表关联
     */
    deleteJoin(i) {
      this.nodeData.joins.splice(i, 1);
    },
  },
  watch: {
    value(val) {
      this.show = val;
      if (val) {
        this.getSetNode();
      }
    },
    show(val) {
      this.$emit("input", val);
    },
  },
};
</script>

<style lang="less">
.setTableJoinCard {
  .ant-drawer-body {
    padding: 0;
    .join_list {
      height: calc(100vh - 160px);
      padding: 12px;
      overflow: auto;
      .a_label {
        line-height: 32px;
        font-size: 12px;
        font-weight: 500;
        text-align: right;
        color: #000000;
      }
      .join_config {
        position: relative;
        border: 1px solid #dedede;
        border-radius: 8px;
        margin: 8px 0;
        padding: 10px;
        .right_delete {
          &:hover {
            cursor: pointer;
          }
          position: absolute;
          z-index: 1;
          right: 0;
          top: 0;
          color: #ec0000;
          font-size: 18px;
          margin-top: -6px;
        }
        .join_table {
          padding-bottom: 8px;
        }
        .condition_body {
          border-top: 1px solid #dedede;
          padding: 8px;
        }
      }
      .add_tool {
        &:hover {
          opacity: 0.8;
          cursor: pointer;
        }
        text-align: center;
        padding: 10px;
        margin-top: 6px;
        background: rgba(231, 231, 230, 0.2);
        border: 1px dashed #dedede;
        border-radius: 8px;
      }
      .table_name {
        font-weight: bold;
      }

      .column_name {
        color: #05a;
      }
    }
  }
}
</style>
