<template>
  <div class="node-item" ref="node"
       :class="[(isActive || isSelected) ? 'active' : '']"
       :style="flowNodeContainer"
       v-click-outside="setNotActive"
       @click="setActive"
       @mouseenter="showAnchor"
       @mouseleave="hideAnchor"
       @dblclick.prevent="findDisposition()"
       @contextmenu.prevent="onContextmenu">
    <div class="log-wrap">
      <img :src="node.logImg" alt="">
    </div>
    <div class="nodeName">{{node.nodeName}}</div>
    <!--连线用--//触发连线的区域-->
    <div class="node-anchor anchor-top" v-show="mouseEnter"></div>
    <div class="node-anchor anchor-right" v-show="mouseEnter"></div>
    <div class="node-anchor anchor-bottom" v-show="mouseEnter"></div>
    <div class="node-anchor anchor-left" v-show="mouseEnter"></div>
    <!-- 节点配置-->
    <div align="center">
      <el-dialog :modal="false" title="配置" :visible.sync="disposition.findFlag" width="50%">
        <span>数据库:&nbsp;&nbsp;{{ disposition.formData.dbName }}</span>
        <span>数据表:&nbsp;&nbsp;{{ disposition.formData.table }}</span>
        <span>
          <el-table ref="table" :data="disposition.formData.fields" height="300px">
            <el-table-column :show-overflow-tooltip="true" label="字段名称" prop="columnName" />
            <el-table-column :show-overflow-tooltip="true" label="字段描述" prop="columnComment" />
            <el-table-column :show-overflow-tooltip="true" label="字段类型" prop="columnType" />
          </el-table>
        </span>
    <el-button @click="disposition.findFlag = false">确认</el-button>
    <el-button type="primary" @click="editDisposition">修改配置</el-button>
      </el-dialog>
      <!-- 自定义表单对话框 -->
      <el-drawer
        style="padding-left: 20px; padding-right: 20px;"
        :modal="false"
        :visible.sync="disposition.updFlag"
        direction="rtl"
        title="节点配置"
        append-to-body
        size="60%">
        <el-form ref="queryForm" :inline="true" :model="queryParams" size="small">
          <el-form-item label="数据库名称" prop="dbName">
            <el-select v-model="queryParams.dbName" placeholder="请选择数据库" clearable>
              <el-option v-for="item in dbNameOptions" :key="item" :label="item" :value="item"/>
            </el-select>
          </el-form-item>
          <el-form-item label="表名称" prop="tableName">
            <el-input
              v-model="queryParams.tableName"
              clearable
              placeholder="请输入表名称" />
          </el-form-item>
          <el-form-item label="表描述" prop="tableComment">
            <el-input
              v-model="queryParams.tableComment"
              clearable
              placeholder="请输入表描述" />
          </el-form-item>
          <el-form-item>
            <el-button icon="el-icon-search" size="mini" type="primary" @click="handleQuery">查找</el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
          </el-form-item>
        </el-form>
        <el-table ref="table" :data="tableOptions" height="300px">
          <el-table-column :show-overflow-tooltip="true" label="表名称" prop="tableName" />
          <el-table-column :show-overflow-tooltip="true" label="表描述" prop="tableComment" />
          <el-table-column label="操作">
            <template slot-scope="scope">
              <el-button type="text" @click="selectTable(scope.row)">选择</el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-divider />
        <el-table ref="table" v-show="fieldsOptions" :data="fieldsOptions" height="300px"
                  @row-click="clickRow" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="55" />
          <el-table-column :show-overflow-tooltip="true" label="字段名称" prop="columnName" />
          <el-table-column :show-overflow-tooltip="true" label="字段描述" prop="columnComment" />
          <el-table-column :show-overflow-tooltip="true" label="字段类型" prop="columnType" />
        </el-table>
        <el-divider />
        <div align="center">
          <el-button type="primary" @click="saveDisposition">确 定</el-button>
          <el-button @click="disposition.updFlag = false">取 消</el-button>
        </div>
      </el-drawer>
    </div>
  </div>
</template>

<script>
import ClickOutside from 'vue-click-outside'
import {listDbTableAll, selDbNameAll, selectDbTableColumnsByName} from "../../../../api/tool/gen";
export default {
  name: "nodeItem",
  props: {
    node: Object
  },
  directives: {
    ClickOutside
  },
  computed: {
    // 节点容器样式
    flowNodeContainer: {
      get() {
        return {
          top: this.node.top,
          left: this.node.left
        };
      }
    }
  },
  data() {
    return {
      mouseEnter: false,
      isActive: false,
      isSelected: false,
      disposition: {
        findFlag: false,
        updFlag: false,
        formData: {
          nodeId: undefined,
          dbName: undefined,
          table: {},
          fields: []
        }
      },
      total: 0,
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        dbName: undefined,
        tableName: undefined,
        tableComment: undefined
      },
      // 数据库列表
      dbNameOptions: [],
      // 展示数据表列表
      tableOptions: [],
      // 所有数据库列表
      tableList: [],
      // 字段列表
      fieldsOptions: []
    };
  },
  methods: {
    showAnchor() {
      this.mouseEnter = true
    },
    hideAnchor() {
      this.mouseEnter = false
    },
    onContextmenu() {
      this.$contextmenu({
        items: [
          {
            label: '修改名称',
            disabled: false,
            icon: "",
            onClick: () => {
              this.toUpdName();
            }
          },{
            label: '修改配置',
            disabled: false,
            icon: "",
            onClick: () => {
              this.disposition.updFlag = true;
            }
          },{
            label: '删除节点',
            disabled: false,
            icon: "",
            onClick: () => {
              this.deleteNode()
            }
          }
        ],
        event,
        customClass: 'custom-class',
        zIndex: 9999,
        minWidth: 180
      })
    },
    setActive() {
      if (window.event.ctrlKey) {
        this.isSelected = !this.isSelected
        return false
      }
      this.isActive = true
      this.isSelected = false
      setTimeout(() => {
        this.$emit("changeLineState", this.node.id, true)
      }, 0)
    },
    setNotActive() {
      if (!window.event.ctrlKey) {
        this.isSelected = false
      }
      if (!this.isActive) {
        return
      }
      this.$emit("changeLineState", this.node.id, false)
      this.isActive = false
    },
    // 修改名称
    toUpdName() {
      this.$prompt('请输入新名称', '更改名称', {
        confirmButtonText: '确定',
        cancelButtonText: '取消'
      }).then(({ value }) => {
        this.$emit('setNodeName', this.node.id, value)
        this.$message({
          type: 'success',
          message: '修改成功'
        });
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '操作取消'
        });
      });
    },
    // 选择删除节点
    deleteNode() {
      this.$confirm('确认删除该节点吗?', '删除提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$emit("deleteNode", this.node)
        this.$message({
          type: 'success',
          message: '删除成功'
        });
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '操作取消'
        });
      });
    },
    /** jsPlumb节点类型 --> 数据库节点类型 */
    toMysqlNode(node,preLine,nextLine){
      return {
        id: node.authId,
        nodeType: node.type,
        nodeCode: node.id,
        nodeName: node.nodeName,
        nodePositionTop: node.top,
        nodePositionLeft: node.left,
        nodePreCode: preLine,
        nodeNextCode: nextLine,
        state: 'Y'
      }
    },
    /** 数据库节点类型 --> jsPlumb节点类型 */
    toJsPlumbNode(nodeInfo){
      const node = {
        authId: nodeInfo.id,
        id: nodeInfo.nodeCode,
        type: nodeInfo.nodeType,
        nodeName: nodeInfo.nodeName,
        top: nodeInfo.nodePositionTop,
        left: nodeInfo.nodePositionLeft
      }
      const line = []
      // 节点有后继节点
      if (nodeInfo.nodeNextCode){
        const nextLine = {
          from: nodeInfo.nodeCode,
          to: nodeInfo.nodeNextCode
        }
        line.push(nextLine)
      }
      // 节点有前驱节点
      if (nodeInfo.nodePreCode){
        const perLine = {
          from: nodeInfo.nodePreCode,
          to: nodeInfo.nodeCode
        }
        line.push(perLine)
      }
      return {
        node: node,
        line: line
      }
    },
    // 双击触发-查看配置
    findDisposition() {
      // 查询节点配置信息
      this.disposition.formData.nodeId = this.node.id
      this.disposition.findFlag = true
    },
    // 编辑配置
    editDisposition() {
      this.selDbNameList()
      this.getListAll()
      this.disposition.updFlag = true
    },
    // 查询所有数据库名称
    selDbNameList() {
      selDbNameAll().then(res => {
        this.dbNameOptions = res.data
      })
    },
    // 查询表字段
    getFields(dbName, tableName) {
      selectDbTableColumnsByName(dbName, tableName).then(res => {
        this.fieldsOptions = res.data
      })
    },
    // 保存配置按钮
    saveDisposition() {
      console.log(this.disposition.formData)
      const dispositionData = this.disposition.formData
      const addData = []
      /**
       * {
       *   node_info_code: '',
       *   node_type: '',
       *   node_value: ''
       * }
       */
      // 处理数据库信息
      addData.push({
        nodeInfoCode: dispositionData.nodeId,
        nodeType: 'dbName',
        nodeValue: dispositionData.dbName
      })
      // 处理数据表信息
      addData.push({
        nodeInfoCode: dispositionData.nodeId,
        nodeType: 'table',
        nodeValue: dispositionData.table
      })
      // 处理数据字段信息
      addData.push({
        nodeInfoCode: dispositionData.nodeId,
        nodeType: 'fields',
        nodeValue: dispositionData.fields.toString()
      })
      console.log(addData)
      this.disposition.updFlag = false
      this.disposition.findFlag = false
    },
    // 重置配置信息
    resetDisposition() {
      this.disposition.formData = {
        dbName: undefined,
        table: {},
        fields: []
      }
    },
    getListAll() {
      listDbTableAll().then(res => {
        this.tableList = res.data;
        this.tableOptions = res.data;
      });
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.tableOptions = []
      this.tableList.forEach(table => {
        const params = this.queryParams
        if ((table.dbName === params.dbName || !params.dbName) &&
          (table.tableName.includes(params.tableName) || !params.tableName) &&
          (table.tableComment.includes(params.tableComment) || !params.tableComment)){
          this.tableOptions.push(table)
        }
      })
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.resetDisposition()
      this.handleQuery();
    },
    /** 选择表信息*/
    selectTable(row) {
      this.disposition.formData.table = row.tableName
      this.disposition.formData.dbName = row.dbName
      this.getFields(row.dbName, row.tableName)
    },
    clickRow(row) {
      this.$refs.table.toggleRowSelection(row);
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.disposition.formData.fields = selection.map(item => {
        return {
          fieldName: item.columnName,
          fieldType: item.columnType,
          fieldComment: item.columnComment
        };
      });
    },
  }
};
</script>

<style lang="less" scoped>
@labelColor: #409eff;
@nodeSize: 20px;
@viewSize: 10px;
.v-modal {
  width: 50%;
  display: none !important;
}
.node-item {
  position: absolute;
  display: flex;
  height: 40px;
  width: 120px;
  justify-content: center;
  align-items: center;
  border: 1px solid #b7b6b6;
  border-radius: 4px;
  cursor: move;
  box-sizing: content-box;
  z-index: 1006;
  &:hover {
    z-index: 1007;
    .delete-btn{
      display: block;
    }
  }
  .log-wrap{
    width: 40px;
    height: 40px;
    border-right: 1px solid  #b7b6b6;
  }
  .nodeName {
    flex-grow: 1;
    width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .node-anchor {
    display: flex;
    position: absolute;
    width: @nodeSize;
    height: @nodeSize;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    cursor: crosshair;
    z-index: 1008;
    background: -webkit-radial-gradient(sandybrown 10%, white 30%, #9a54ff 60%);
  }
  .anchor-top{
    top: calc((@nodeSize / 2)*-1);
    left: 50%;
    margin-left: calc((@nodeSize/2)*-1);
  }
  .anchor-right{
    top: 50%;
    right: calc((@nodeSize / 2)*-1);
    margin-top: calc((@nodeSize / 2)*-1);
  }
  .anchor-bottom{
    bottom: calc((@nodeSize / 2)*-1);
    left: 50%;
    margin-left: calc((@nodeSize / 2)*-1);
  }
  .anchor-left{
    top: 50%;
    left: calc((@nodeSize / 2)*-1);
    margin-top: calc((@nodeSize / 2)*-1);
  }
}
.active{
  border: 1px dashed @labelColor;
  box-shadow: 0px 5px 9px 0px rgba(0,0,0,0.5);
}
</style>
