<!--
 * @Author: zwq
 * @Date: 2022-09-01 15:42:34
 * @LastEditors: zwq
 * @LastEditTime: 2023-01-06 15:29:29
 * @Description: 
-->
<template>
  <el-row :gutter="20">
    <el-col :span="3">
      <el-card class="cardHeader">
        <div slot="header" style="color:#409eff;text-align:center">
          工序列表
        </div>
        <el-collapse v-model="activeName" @change="processTypeClick" accordion>
          <el-collapse-item
            v-for="(item, index) in processTypeArr"
            :key="index"
            :title="item.name"
            :name="index"
          >
            <div
              v-loading="loading"
              element-loading-text="拼命加载中"
              element-loading-spinner="el-icon-loading"
              element-loading-background="rgba(0, 0, 0, 0.8)"
            >
              <div v-if="processArr.length > 0">
                <div
                  v-for="(item, index) in processArr"
                  :key="index"
                  class="btn"
                  :title="item.name"
                  @mousedown="startDrag(item, $event)"
                >
                  {{ item.name }}
                </div>
              </div>
              <el-empty
                v-else
                :image-size="50"
                description="此类型下无工序"
                style="padding:0;"
              ></el-empty>
            </div>
          </el-collapse-item>
        </el-collapse>
      </el-card>
    </el-col>
    <el-col :span="21">
      <div id="containerChart"></div>
      <div v-if="editDrawer" class="edit-main">
        <div class="edit-main-title">
          <h3>{{ editTitle }}</h3>
          <i class="el-icon-close" @click="closeEditForm"></i>
        </div>
        <div v-if="editTitle === '编辑节点'" class="form-main">
          <el-form ref="nodeForm" :model="form" label-width="80px" size="mini">
            <el-form-item label="节点文本">
              <el-input
                v-model="form.labelText"
                size="small"
                readonly
                @input="changeNode('labelText', form.labelText)"
              ></el-input>
            </el-form-item>
            <!-- <el-form-item label="字体大小">
              <el-input
                v-model="form.fontSize"
                size="small"
                @input="changeNode('fontSize', form.fontSize)"
              ></el-input>
            </el-form-item> -->
            <el-form-item label="字体颜色">
              <el-color-picker
                v-model="form.fontFill"
                @change="changeNode('fontFill', form.fontFill)"
              ></el-color-picker>
            </el-form-item>
            <el-form-item label="节点背景">
              <el-color-picker
                v-model="form.fill"
                @change="changeNode('fill', form.fill)"
              ></el-color-picker>
            </el-form-item>
            <!-- <el-form-item label="边框颜色">
              <el-color-picker
                v-model="form.stroke"
                @change="changeNode('stroke', form.stroke)"
              ></el-color-picker>
            </el-form-item> -->
            <div class="see-box">
              <h5>预览</h5>
              <div
                class="see-item"
                :style="{
                  background: form.fill,
                  color: form.fontFill,
                  'border-color': form.stroke,
                  'font-size': form.fontSize + 'px',
                }"
              >
                {{ form.labelText }}
              </div>
            </div>
          </el-form>
        </div>
        <!-- <div v-if="editTitle === '编辑连线'" class="form-main">
          <el-form ref="edgeForm" :model="form" label-width="80px" size="mini">
            <el-form-item label="标签内容">
              <el-input
                v-model="form.label"
                size="small"
                placeholder="标签文字，空则没有"
                @input="
                  changeEdgeLabel(form.label, labelForm.fontColor, labelForm.fill, labelForm.stroke)
                "
              ></el-input>
              <div v-if="form.label" class="label-style">
                <p>
                  字体颜色：<el-color-picker
                    v-model="labelForm.fontColor"
                    size="mini"
                    @change="
                      changeEdgeLabel(
                        form.label,
                        labelForm.fontColor,
                        labelForm.fill,
                        labelForm.stroke
                      )
                    "
                  ></el-color-picker>
                </p>
                <p>
                  背景颜色：<el-color-picker
                    v-model="labelForm.fill"
                    size="mini"
                    @change="
                      changeEdgeLabel(
                        form.label,
                        labelForm.fontColor,
                        labelForm.fill,
                        labelForm.stroke
                      )
                    "
                  ></el-color-picker>
                </p>
                <p>
                  描边颜色：<el-color-picker
                    v-model="labelForm.stroke"
                    size="mini"
                    @change="
                      changeEdgeLabel(
                        form.label,
                        labelForm.fontColor,
                        labelForm.fill,
                        labelForm.stroke
                      )
                    "
                  ></el-color-picker>
                </p>
              </div>
            </el-form-item>
            <el-form-item label="线条颜色">
              <el-color-picker
                v-model="form.stroke"
                size="small"
                @change="changeEdgeStroke"
              ></el-color-picker>
            </el-form-item>
            <el-form-item label="线条宽度">
              <el-input-number
                v-model="form.strokeWidth"
                size="small"
                @change="changeEdgeStrokeWidth"
                :min="2"
                :step="2"
                :max="6"
                label="线条宽度"
              ></el-input-number>
            </el-form-item>
            <el-form-item label="双向箭头">
              <el-switch v-model="form.isArrows" @change="changeEdgeArrows"></el-switch>
            </el-form-item>
            <el-form-item label="流动线条">
              <el-switch v-model="form.isAnit" @change="changeEdgeAnit"></el-switch>
            </el-form-item>
          </el-form>
        </div> -->
        <div class="edit-btn">
          <el-button type="primary" size="medium" @click="saveChange" style="width:100%"
            >保存</el-button
          >
          <el-button type="danger" size="medium" @click="handlerDel" style="width:100%"
            >删除此{{ editTitle === "编辑节点" ? "节点" : "连线" }}</el-button
          >
        </div>
      </div>
    </el-col>
  </el-row>
</template>

<script>
import { Graph, Shape, FunctionExt } from "@antv/x6";
import { startDragToGraph, configEdgeLabel } from "./flowMethods.js";
export default {
  props: {
    productId: {
      type: String,
    },
  },
  data() {
    return {
      dataList: [],
      processArr: [],
      processTypeArr: [],
      activeName: "",
      processId: "",
      graph: "",
      type: "grid",
      selectCell: "",
      loading: false,
      editDrawer: false,
      editTitle: "",
      form: {},
      labelForm: {
        fontColor: "#333",
        fill: "#FFF",
        stroke: "#555",
      },
      connectEdgeType: {
        //连线方式
        connector: "normal",
        router: {
          name: "",
        },
      },
      grid: {
        // 网格设置
        size: 20, // 网格大小 10px
        visible: true, // 渲染网格背景
        type: "mesh",
        args: {
          color: "#D0D0D0",
          thickness: 1, // 网格线宽度/网格点大小
          factor: 10,
        },
      },
    };
  },
  activated() {
    this.init();
  },
  watch: {
    value: {
      handler: function() {
        if (this.graph) {
          this.selectCell = "";
          this.editDrawer = false;
          this.graph.dispose();
          this.init();
        }
      },
      deep: true,
      immediate: true,
    },
  },
  methods: {
    init() {
      this.getArr();
      this.$nextTick(() => {
        this.processId = "";
        if (this.productId) {
          this.getList();
        } else {
          this.dataList = [];
        }
      });
      this.graph = new Graph({
        container: document.getElementById("containerChart"),
        height: 600,
        selecting: true,
        background: {
          color: "#fffbe6", // 设置画布背景颜色
        },
        snapline: {
          enabled: true,
          sharp: true,
        },
        // scroller: {
        //   enabled: true,
        //   pageVisible: false,
        //   pageBreak: false,
        //   pannable: true,
        // },
        mousewheel: {
          enabled: true,
          modifiers: ["ctrl", "meta"],
        },
        grid: this.grid,
      });
      // // 鼠标移入移出节点
      // this.graph.on(
      //   "node:mouseenter",
      //   FunctionExt.debounce(() => {
      //     const container = document.getElementById("containerChart");
      //     const ports = container.querySelectorAll(".x6-port-body");
      //     this.showPorts(ports, true);
      //   }),
      //   500
      // );
      // this.graph.on("node:mouseleave", (e) => {
      //   const container = document.getElementById("containerChart");
      //   const ports = container.querySelectorAll(".x6-port-body");
      //   this.showPorts(ports, false);
      // });
      //获取放置到画布上节点的位置
      this.graph.on("node:added", ({ node }) => {
        const { x, y } = node.position();
        this.addProcess(node.attrs.label.workingProcedureId, x, y);
      });
      //这是鼠标抬起节点事件
      this.graph.on("node:moved", ({ node }) => {
        const { x, y } = node.position();
        this.updataNode(node.id, x, y);
      });
      // 点击编辑
      this.graph.on("cell:click", ({ cell }) => {
        this.editForm(cell);
      });
      //链接边分离后触发
      // this.graph.on("edge:connected", ({ isNew, edge }) => {
      //   if (isNew) {
      //     const source = edge.getSourceCell();
      //     const target = edge.getTargetCell();
      //   }
      // });
    },
    // 是否展示节点
    // showPorts(ports, show) {
    //   for (let i = 0, len = ports.length; i < len; i = i + 1) {
    //     ports[i].style.visibility = show ? "visible" : "hidden";
    //   }
    // },
    // 拖拽生成正方形或者圆形
    startDrag(data, e) {
      startDragToGraph(this.graph, data, e);
    },
    getArr() {
      this.$http
        .get("/basic/workingProcedureType/page", {
          params: {
            page: 1,
            limit: 500,
          },
        })
        .then(({ data: res }) => {
          if (res.code !== 0) {
            return this.$message.error(res.msg);
          }
          this.processTypeArr = res.data.list;
        })
        .catch(() => {});
    },
    getList() {
      this.$http
        .get(
          `/basic/productWorkingprocedureRelation/getWorkingprocedureByProductId/${this.productId}`
        )
        .then(({ data: res }) => {
          if (res.code !== 0) {
            this.dataList = [];
            return this.$message.error(res.msg);
          }
          this.dataList = res.data;
          this.setNode();
          this.setEdge();
        })
        .catch(() => {});
    },
    //点击工序类型
    processTypeClick(val) {
      this.processArr = [];
      if (val === 0 || val) {
        this.loading = true;
        this.$http
          .post(`/basic/workingProcedure/listByType/${this.processTypeArr[val].id}`)
          .then(({ data: res }) => {
            this.loading = false;
            this.processArr = res;
          })
          .catch(() => {});
      }
    },
    setNode() {
      let nodes = [];
      this.dataList.forEach((item) => {
        let obj = {};
        (obj.id = item.id), (obj.x = item.x);
        obj.y = item.y;
        obj.width = 100;
        obj.height = 60;
        obj.label = "圆角矩形";
        obj.data = {
          type: "defaultYSquare",
        };
        obj.shape = "rect";
        obj.attrs = {
          label: {
            text: item.workingProcedureName,
            fill: item.fontcolor || "#FFFFFF",
            fontSize: 14,
            textWrap: {
              width: -10,
              height: -10,
              ellipsis: true,
            },
          },
          body: {
            stroke: "#000000",
            strokeWidth: 1,
            fill: item.backcolor || "#5bdeff",
            rx: 10,
            ry: 10,
          },
        };
        nodes.push(obj);
      });
      const data = {
        nodes,
      };
      this.graph.fromJSON(data);
    },
    setEdge() {
      let source, target;
      if (this.dataList.length >= 2) {
        this.dataList.forEach((item, index) => {
          if (index % 2 === 0) {
            source = item.id;
          } else {
            target = item.id;
            this.graph.addEdge({
              source: source,
              target: target,
            });
          }
        });
      }
    },
    updataNode(id, x, y) {
      const data = {
        id: id,
        x: x,
        y: y,
      };
      this.$http
        .put("/basic/productWorkingprocedureRelation", data)
        .then(({ data: res }) => {
          if (res.code !== 0) {
            return this.$message.error(res.msg);
          }
          this.$message({
            message: this.$t("prompt.success"),
            type: "success",
            duration: 500,
          });
          this.getList();
        })
        .catch(() => {});
    },
    addProcess(workingProcedureId, x, y) {
      this.$http
        .post("/basic/productWorkingprocedureRelation/save", {
          workingProcedureId: workingProcedureId,
          productId: this.productId,
          x,
          y,
        })
        .then(({ data: res }) => {
          if (res.code !== 0) {
            this.getList();
            return this.$message.error(res.msg);
          }
          this.$message({
            message: this.$t("prompt.success"),
            type: "success",
            duration: 500,
            onClose: () => {
              this.getList();
            },
          });
        })
        .catch(() => {});
    },
    //编辑节点和线
    editForm(cell) {
      this.selectCell = cell;
      console.log(cell);
      // 编辑node节点
      if (cell.isNode() && cell.data.type && cell.data.type.includes("default")) {
        this.editTitle = "编辑节点";
        const body = cell.attrs.body || cell.attrs.rect || cell.attrs.polygon || cell.attrs.circle;
        this.form = {
          labelText: cell.attrs.label.text || "",
          fontSize: cell.attrs.label.fontSize || 14,
          fontFill: cell.attrs.label.fill || "",
          fill: body.fill || "",
          stroke: body.stroke || "",
        };
        return (this.editDrawer = true);
      }
      // // 编辑线
      // if (!cell.isNode() && cell.shape === "edge") {
      //   this.editTitle = "编辑连线";
      //   this.form = {
      //     label: cell.labels && cell.labels[0] ? cell.labels[0].attrs.labelText.text : "",
      //     stroke: cell.attrs.line.stroke || "",
      //     strokeWidth: cell.attrs.line.strokeWidth || "",
      //     isArrows: cell.attrs.line.sourceMarker ? true : false,
      //     isAnit: cell.attrs.line.strokeDasharray ? true : false,
      //   };
      //   // 看是否有label
      //   const edgeCellLabel = (cell.labels && cell.labels[0] && cell.labels[0].attrs) || false;
      //   if (this.form.label && edgeCellLabel) {
      //     this.labelForm = {
      //       fontColor: edgeCellLabel.labelText.fill || "#333",
      //       fill: edgeCellLabel.labelBody.fill || "#fff",
      //       stroke: edgeCellLabel.labelBody.stroke || "#555",
      //     };
      //   } else {
      //     this.labelForm = { fontColor: "#333", fill: "#FFF", stroke: "#555" };
      //   }
      //   return (this.editDrawer = true);
      // }
    },
    closeEditForm() {
      this.editDrawer = false;
    },
    // 修改一般节点
    changeNode(type, value) {
      switch (type) {
        case "labelText":
          this.selectCell.attr("label/text", value);
          break;
        case "fontSize":
          this.selectCell.attr("label/fontSize", value);
          break;
        case "fontFill":
          this.selectCell.attr("label/fill", value);
          break;
        case "fill":
          this.selectCell.attr("body/fill", value);
          break;
        case "stroke":
          this.selectCell.attr("body/stroke", value);
          break;
      }
    },
    // 修改边label属性
    changeEdgeLabel(label, fontColor, fill, stroke) {
      this.selectCell.setLabels([configEdgeLabel(label, fontColor, fill, stroke)]);
      if (!label) this.labelForm = { fontColor: "#333", fill: "#FFF", stroke: "#555" };
    },
    // 修改边的颜色
    changeEdgeStroke(val) {
      this.selectCell.attr("line/stroke", val);
    },
    // 边的宽度
    changeEdgeStrokeWidth(val) {
      if (this.form.isArrows) {
        this.selectCell.attr({
          line: {
            strokeWidth: val,
            sourceMarker: {
              width: 12 * (val / 2) || 12,
              height: 8 * (val / 2) || 8,
            },
            targetMarker: {
              width: 12 * (val / 2) || 12,
              height: 8 * (val / 2) || 8,
            },
          },
        });
      } else {
        this.selectCell.attr({
          line: {
            strokeWidth: val,
            targetMarker: {
              width: 12 * (val / 2) || 12,
              height: 8 * (val / 2) || 8,
            },
          },
        });
      }
    },
    // 边的箭头
    changeEdgeArrows(val) {
      if (val) {
        this.selectCell.attr({
          line: {
            sourceMarker: {
              name: "block",
              width: 12 * (this.form.strokeWidth / 2) || 12,
              height: 8 * (this.form.strokeWidth / 2) || 8,
            },
            targetMarker: {
              name: "block",
              width: 12 * (this.form.strokeWidth / 2) || 12,
              height: 8 * (this.form.strokeWidth / 2) || 8,
            },
          },
        });
      } else {
        this.selectCell.attr({
          line: {
            sourceMarker: "",
            targetMarker: {
              name: "block",
              size: 10 * (this.form.strokeWidth / 2) || 10,
            },
          },
        });
      }
    },
    // 边的添加蚂蚁线
    changeEdgeAnit(val) {
      if (val) {
        this.selectCell.attr({
          line: {
            strokeDasharray: 5,
            style: {
              animation: "ant-line 30s infinite linear",
            },
          },
        });
      } else {
        this.selectCell.attr({
          line: {
            strokeDasharray: 0,
            style: {
              animation: "",
            },
          },
        });
      }
    },
    // 删除节点
    handlerDel() {
      this.$confirm(
        `此操作将永久删除此${this.editTitle === "编辑节点" ? "节点" : "连线"}, 是否继续?`,
        "提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }
      )
        .then(() => {
          const cells = this.graph.getSelectedCells();
          if (cells.length) {
            this.$http
              .delete("/basic/productWorkingprocedureRelation", { data: [cells[0].id] })
              .then(({ data }) => {
                if (data && data.code === 0) {
                  this.graph.removeCells(cells);
                  this.form = {};
                  this.editDrawer = false;
                  this.$message({
                    message: "操作成功",
                    type: "success",
                    duration: 1500,
                    onClose: () => {
                      this.getList();
                    },
                  });
                } else {
                  this.$message.error(data.msg);
                }
              });
          }
        })
        .catch(() => {});
    },
    saveChange() {
      const cells = this.graph.getSelectedCells();
      const data = {
        id: cells[0].id,
        backcolor: cells[0].attrs.body.fill,
        fontcolor: cells[0].attrs.label.fill,
      };
      this.$http
        .put("/basic/productWorkingprocedureRelation", data)
        .then(({ data: res }) => {
          if (res.code !== 0) {
            return this.$message.error(res.msg);
          }
          this.$message({
            message: this.$t("prompt.success"),
            type: "success",
            duration: 500,
          });
          this.getList();
        })
        .catch(() => {});
    },
    //清空画布
    deleteAll() {
      this.graph.clearCells();
    },
    //销毁画布
    GraphDelete() {
      this.graph.dispose();
    },
  },
  beforeDestroy() {
    if (this.graph) {
      this.graph.dispose();
    }
  },
};
</script>

<style lang="scss">
@keyframes ant-line {
  to {
    stroke-dashoffset: -1000;
  }
}
</style>
<style>
.btn {
  background-color: #5bdeff;
  text-align: center;
  padding: 10px;
  color: white;
  cursor: move;
  margin-bottom: 10px;
}
</style>

<style lang="scss" scoped="scoped">
.edit-main {
  position: absolute;
  right: 0;
  top: 0;
  height: 100%;
  width: 280px;
  border-left: 1px solid #f2f2f2;
  box-shadow: 0 -10px 10px rgba($color: #000000, $alpha: 0.3);
  padding: 20px;
  background: #fff;
  box-sizing: border-box;
  .edit-main-title {
    display: flex;
    justify-content: space-between;
    align-items: center;
    h3 {
      flex: 1;
    }
    i {
      cursor: pointer;
      font-size: 20px;
      opacity: 0.7;
      &:hover {
        opacity: 1;
      }
    }
  }
  .form-main {
    padding: 10px 0;
    .label-style {
      background: #f2f2f2;
      padding: 0 10px;
      p {
        display: flex;
        align-items: center;
        font-size: 12px;
      }
    }
  }
  .edit-btn {
    display: flex;
    align-items: center;
  }
  .see-box {
    padding: 10px;
    background: #f2f2f2;
    h5 {
    }
    .see-item {
      line-height: 60px;
      text-align: center;
      width: 100px;
      height: 60px;
      border-radius: 5px;
      margin: auto;
      border: 2px solid #333;
    }
  }
}
.el-card ::v-deep .el-card__header {
  height: 60px;
}
</style>
