<template>
  <a-layout
    style="height: 100%"
    id="graph-main-container"
    :class="isFullScreen == true ? 'fullScreen' : ''"
  >
    <a-layout-header
      style="
        height: 47px;
        border: 1px solid #d1dbe5;
        padding: 5px;
        background: white;
      "
      ref="menu"
      v-if="showMode != 'view'"
    >
      <a-card
        class="box-card"
        style="padding: 0px; height: 37px"
        :body-style="{
          padding: '3px',
          height: '30px',
          'text-align': 'left',
          'border-radius': '0px',
        }"
      >
        <!-- @vue-ignore -->
        <topMenu
          :showSimpleBtn="showSimpleBtn"
          :ifCanBeEdite="ifCanBeEdite"
          :showPeoperty="showPeoperty"
          :showEnable="showEnable"
          :mxgraph="m_graph_show"
          :MaxKeyWord="keyWord"
          :isFullScreen="isFullScreen"
          :showKeyWord="ifCanBeEdite == true"
          @refresh="handleRefresh"
          @delete="handleDel"
          @cut="handleCut"
          @copy="handleCopy"
          @past="handlePast"
          @ScalChange="handleScale"
          @larger="handleLarg"
          @small="handleSmall"
          @unset="handleUnset"
          @save="handleSave"
          @import="handleImport"
          @Insert="handleInsert"
          @print="handlePrint"
          @group="handleGroup"
          @ungroup="handleUnGroup"
          @selectAll="handleSelectAll"
          @selectNone="handleNone"
          @undo="handleUndo"
          @redo="handleRedo"
          @up="handleUp"
          @next="handleNext"
          @entergroup="handleEnterGroup"
          @exitgroup="handleExitGroup"
          @alignLeft="handleAlignLeft"
          @alignRight="handleAlignRight"
          @alignTop="handleAlignTop"
          @alignBottom="handleAlignBottom"
          @alignMiddle="handleMiddle"
          @alignCenter="handleCenter"
          @alignVer="handleAlignVer"
          @alignHor="handleAlignHor"
          @equalWidth="handleEqualWidth"
          @equalHeight="handleEqualHeight"
          @equalAll="handleEqualAll"
          @toFont="handleToFont"
          @toBack="handleToBack"
          @circle="handleCircle"
          @closePorperty="handleClosePerty"
          @showGraphTree="handleShowGraphTree"
          @setEnablePorper="handlesetEnablePorper"
          @changeKeyWord="handleChangeKeyWord"
          @full-screen="handleFullScreen"
        ></topMenu>
      </a-card>
    </a-layout-header>
    <a-layout-content>
      <a-layout style="height: 100%; display: flex">
        <a-layout-sider
          :id="localGuiID + 'left_menu'"
          style="
            width: 30px !important;
            border: 1px solid #d1dbe5;
            padding: 5px;
            border-top-width: 0px;
            border-right-width: 0px;
            background: white;
            min-width: 30px !important;
          "
          v-show="ifCanBeEdite == true"
          class="left_menu"
        >
          <div
            :ref="localGuiID + 'left_menu_formular'"
            style="height: 5px"
          ></div>
        </a-layout-sider>
        <a-layout-content
          :style="{
            height: '100%',
            border: '1px solid #d1dbe5',
            padding: '5px',
            'border-top-width': '0px',
            overflow: showInDlg ? 'revert' : '',
          }"
        >
          <!--tabindex 解决了快捷键设置在界面重启后失灵的问题-->
          <a-layout style="height: 100%; padding: 0px" direction="vertical">
            <!--  -->
            <a-layout-header
              :style="{
                height: setHeader(menuHeight) + 'px',
                padding: 0 + 'px',
                'background-color': 'white',
                'line-height': '35px',
              }"
              v-if="currentSwimArray.length > 0 && showBtn == true"
            >
              <div
                :ref="localGuiID + 'divButton'"
                :id="localGuiID + 'divButton'"
                style="overflow: hidden; display: flex"
              >
                <span
                  v-for="item in currentSwimArray"
                  :key="item.id"
                  :style="{ width: item.showWidth + 'px' }"
                >
                  <a-button
                    class="deviceButtonOne"
                    :id="item.id"
                    v-if="item.id == currentSwimArray[0].id"
                    :style="{
                      width: item.showWidth + 1 + 'px',
                      background: item.RecipeStyleColor,
                      height: item.showHeight + 'px',
                      'font-size': setHeader(16) + 'px',
                    }"
                    @click="handleChooseSwimlane(item)"
                    >{{ item.RecipeStyleName }}</a-button
                  >
                  <a-button
                    class="deviceButtonMidle"
                    :id="item.id"
                    @click="handleChooseSwimlane(item)"
                    v-else
                    :style="{
                      width: item.showWidth + 'px',
                      'margin-left': 1 + 'px',
                      background: item.RecipeStyleColor,
                      height: item.showHeight + 'px',
                      'font-size': setHeader(16) + 'px',
                    }"
                    >{{ item.RecipeStyleName }}</a-button
                  >
                </span>
              </div>
            </a-layout-header>
            <a-layout-content
              :style="{
                height: containerHeight + 'px',
                padding: '0px',
                position: 'relative',
              }"
            >
              <div
                tabindex="-2"
                class="graph_container"
                :id="localGuiID + 'graph_container'"
                :ref="localGuiID + 'graph_container'"
                style="height: 100%; overflow: scroll; z-index: 2"
              ></div>
            </a-layout-content>
          </a-layout>
        </a-layout-content>
      </a-layout>
    </a-layout-content>
    <contextHolder />
  </a-layout>
</template>

<script setup lang="ts">
//加载图形
import topMenu from "./component/top-menu.vue";
import {
  decode,
  accMul,
  GuidID,
} from "./component/commonMethods/commonMethods";
import {
  watch,
  getCurrentInstance,
  onMounted,
  onBeforeUnmount,
  ref,
  nextTick,
  computed,
  onBeforeMount,
  PropType,
} from "vue";
import { useGraphMethods } from "./component/commonMethods/graph-common-methods";
import { events } from "../bus";
import { message, Modal } from "ant-design-vue";
const [modal, contextHolder] = Modal.useModal();
import { registerExtraShape } from "./common/shape";
import { clearMxTooltip } from "./component/commonMethods/commonMethods";

import { mxgraph } from "./common/initGraphVar";
const {
  mxDivResizer,
  mxClient,
  mxUtils,
  mxPerimeter,
  mxCellRenderer,
  mxKeyHandler,
  mxRubberband,
  mxCell,
  mxEvent,
  mxCylinder,
} = mxgraph;

const localGuiID = GuidID();
const isFullScreen = ref(false);
const cardBodyStyle = {
  padding: "3px",
  height: "30px",
};

const emits = defineEmits([
  "ifEditableChange",
  "closeParamForm",
  "showGraphTree",
  "cellClick",
  "hidePorperty",
  "cellDbClick",
  "fullScreenState",
  "show-child",
]);

const props = defineProps({
  ParamNameReplaceRelation: {
    type: Object,
    default() {
      return null;
    },
  },
  showSimpleBtn: Boolean,
  DeviceOption: Array,
  formularColor: Object,
  receipFunction: Object,
  ifCanBeEdite: {
    type: Boolean,
    default: true,
  },
  showPeoperty: {
    type: Boolean,
    default: false,
  },
  data: {
    //配方结构
    type: String,
    default: "",
  },
  SFCcolor: {
    type: Object,
    default() {
      return {
        Channel: {
          ColorKey: "Channel",
          Description: "泳道显示颜色",
          FillColor: "#ffffff",
          GradientColor: "#ffffff",
          Type: "Channel",
        },
        Layer: {
          ColorKey: "Layer",
          Description: "工艺组显示颜色",
          FillColor: "#48C684",
          GradientColor: "#FFFFFF",
          Type: "Layer",
        },
        Common: {
          ColorKey: "Common",
          Description: "标准工艺颜色",
          FillColor: "#41B9F5",
          GradientColor: "#8CCDF5",
          Type: "Common",
        },
        AndLogic: {
          ColorKey: "AndLogic",
          Description: "逻辑与",
          FillColor: "#FFBF28",
          GradientColor: "#FFBF28",
          Type: "Logic",
        },
        Condition: {
          ColorKey: "Condition",
          Description: "条件",
          FillColor: "#FFBF28",
          GradientColor: "#FFBF28",
          Type: "Condition",
        },
        ComplexCondition: {
          ColorKey: "ComplexCondition",
          Description: "复杂条件",
          FillColor: "#FFBF28",
          GradientColor: "#FFBF28",
          Type: "ComplexCondition",
        },
        Sub: {
          ColorKey: "Sub",
          Description: "子过程",
          FillColor: "#FFBF28",
          GradientColor: "#FFBF28",
          Type: "Sub",
        },
        Return: {
          ColorKey: "Return",
          Description: "子过程返回",
          FillColor: "#FFBF28",
          GradientColor: "#FFBF28",
          Type: "Return",
        },
        End: {
          ColorKey: "End",
          Description: "生产结束",
          FillColor: "#FF0000",
          GradientColor: "#FF0000",
          Type: "End",
        },
        OrLogic: {
          ColorKey: "OrLogic",
          Description: "逻辑或",
          FillColor: "#FFBF28",
          GradientColor: "#FFBF28",
          Type: "Logic",
        },
        Qc: {
          ColorKey: "Qc",
          Description: "质检",
          FillColor: "#00FFFF",
          GradientColor: "#00FFFF",
          Type: "Qc",
        },
        Bus: {
          ColorKey: "Bus",
          Description: "总线",
          FillColor: "#FFFFFF",
          GradientColor: "#FFFFFF",
          Type: "Qc",
        },
        NULL: {
          ColorKey: "NULL",
          Description: "空工艺",
          FillColor: "#41B9F5",
          GradientColor: "#8CCDF5",
          Type: "NULL",
        },
        Allot: {
          ColorKey: "Allot",
          Description: "调拨工艺",
          FillColor: "#41B9F5",
          GradientColor: "#8CCDF5",
          Type: "Allot",
        },
      };
    },
  },
  CommonFunRow: {
    type: Number,
    default: 6,
  },
  QCFunRow: {
    type: Number,
    default: 6,
  },
  AllfunOption: {
    //所有工艺
    type: Array,
    default() {
      return [];
    },
  },
  showEnable: {
    type: Boolean,
    default: false,
  },
  moduleType: {
    type: String,
    default: "Formular",
  },
  baseParameterOption: {
    type: Array as PropType<any[]>,
    default() {
      return [];
    },
  },
  planDevice: {
    type: Array,
    default() {
      return [];
    },
  },
  ifUpdate: {
    //是否只更新页面
    type: Boolean,
    default: false,
  },
  showInDlg: {
    type: Boolean,
    default: false,
  },
  matLimitOption: {
    type: Array,
    default() {
      return [];
    },
  },
  outMaxKeyWord: {
    type: Number,
    default: 0,
  },
  titleFontSize: {
    type: Number,
    default: 12,
  },
  isShowStart: {
    type: Boolean,
    default: true,
  },
  isShowStop: {
    type: Boolean,
    default: true,
  },
  isShowCompleted: {
    type: Boolean,
    default: true,
  },
  isShowPause: {
    type: Boolean,
    default: true,
  },
  isShowContinue: {
    type: Boolean,
    default: true,
  },
  isShowCancel: {
    type: Boolean,
    default: true,
  },
  isShowReset: {
    type: Boolean,
    default: true,
  },
  PlanBatch: {
    type: String,
    default: "",
  },
  StartMode: {
    type: Number,
    default: 0,
  },
  IsFormular: {
    type: Boolean,
    default: false,
  },
  DownloadStatus: {
    type: Boolean,
    default: false,
  },
  //是否显示操作btn,暂时使用一个权限控制
  isShowOperateBtn: {
    type: Boolean,
    default: false,
  },
  ReceipID: {
    //单据ID，配方中，传入配方ID,工单中，传入planbatch
    type: String,
    default: "",
  },
  //是否需要显示在图形中
  isShowOperateBtnInGraph: {
    type: Boolean,
    default: true,
  },
  WorkCenterId: {
    type: Number,
    default: 0,
  },
  showMode: {
    type: String,
    default: "",
  },
  showCells: {
    type: Array as PropType<any[]>,
    default: () => {
      return [];
    },
  },
});

interface SwimArrayStruct {
  showWidth: number;
  id: string | number;
  RecipeStyleColor: string;
  showHeight: number;
  RecipeStyleName: string;
}
//@ts-ignore
let m_graph_show = null; //定义一个graph对象用于维护graph对象
let m_toolbar = null; //左侧工具栏
let m_editor = null; //编辑器
//const m_tbContainer = ref(null)  //工具栏容器
//const m_graphContainer = ref(null) //画图主表容器
//const selectCellID = ref(null)
//let cellType = ref(null)
let containerHeight = ref("100%"); //画布高度
let menuHeight = 0;
//let selectSwimlane = ref([]) //当前选中的泳道
let groupLayer = ref(0);
//let ifSwimLane = ref(false)
let selectGroupCell = ref(null); //当前选中的元素
let showDeviceButton = ref(false);
let currentSwimArray = ref([] as SwimArrayStruct[]); //当前页面显示泳道
//let lastPatentID = ref(1)  //当前层级ID
let currentParentID = ref("1"); //前一个层级ID
let keyWord = ref(0); //关键字
let circle = ref(false); //是否循环添加元素
//let defaultParent = ref(null)
//let graphKeyHandle = ref(null)
let showGlobal = ref(false);
let ifEditable = ref(false);
//let dialogs = ref([])
let currentGroupCell = ref(null); //当前选中的组元素
let showBtn = ref(false);
let scalSize = ref(1);

let enterGroupCell = ref(null);
let currentInsertCell = ref(null); //当前插入的图元
let cellsCurrentParent = ref(null); //当前图元的父图元(针对复制图元的时候使用)
let forceEdit = ref(false);
const currentInstance = getCurrentInstance(); //当前上下文实例
/* eslint-disable */
// eslint-disable-next-line vue/no-setup-props-destructure
const QCFunRow = props.QCFunRow;
/* eslint-disable */
// eslint-disable-next-line vue/no-setup-props-destructure
const CommonFunRow = props.CommonFunRow;
/* eslint-disable */
// eslint-disable-next-line vue/no-setup-props-destructure
const ifCanBeEdite = props.ifCanBeEdite;
/* eslint-disable */
// eslint-disable-next-line vue/no-setup-props-destructure
const DeviceOption = props.DeviceOption;
/* eslint-disable */
// eslint-disable-next-line vue/no-setup-props-destructure

const AllfunOption = props.AllfunOption;

/* eslint-disable */
// eslint-disable-next-line vue/no-setup-props-destructure
const ifUpdate = props.ifUpdate;
/* eslint-disable */
// eslint-disable-next-line vue/no-setup-props-destructure
const planDevice = props.planDevice;

const moduleType = props.moduleType;
/* eslint-disable */
// eslint-disable-next-line vue/no-setup-props-destructure
const SFCcolor = props.SFCcolor;
/* eslint-disable */
// eslint-disable-next-line vue/no-setup-props-destructure
const matLimitOption = props.matLimitOption;
/* eslint-disable */
// eslint-disable-next-line vue/no-setup-props-destructure
const outMaxKeyWord = props.outMaxKeyWord;
/* eslint-disable */
// eslint-disable-next-line vue/no-setup-props-destructure
const titleFontSize = props.titleFontSize;

const ParamNameReplaceRelation = props.ParamNameReplaceRelation;
const baseParameterOption = props.baseParameterOption;

const isShowStart = props.isShowStart;
const isShowStop = props.isShowStop;
const isShowCompleted = props.isShowCompleted;
const isShowPause = props.isShowPause;
const isShowContinue = props.isShowContinue;
const isShowCancel = props.isShowCancel;
const isShowReset = props.isShowReset;

//是否显示与
const isShowAnd = computed(() => {
  let bRet = getIsFunStyleValid(1);
  return bRet;
});

//是否显示或
const isShowOR = computed(() => {
  let bRet = getIsFunStyleValid(2);
  return bRet;
});
//条件
const isShowCondition = computed(() => {
  let bRet = getIsFunStyleValid(3);
  return bRet;
});
const isShowComplexCondition = computed(() => {
  let bRet = getIsFunStyleValid(15);
  return bRet;
});
const isShowSub = computed(() => {
  let bRet = getIsFunStyleValid(5);
  return bRet;
});
const isShowReturn = computed(() => {
  let bRet = getIsFunStyleValid(6);
  return bRet;
});
const isShowQC = computed(() => {
  let bRet = getIsFunStyleValid(9);
  return bRet;
});

const handleClosePerty = function () {
  emits("closeParamForm", 1);
};

const graphMethods = useGraphMethods({
  m_graph_show,
  currentGroupCell,
  groupLayer,
  currentParentID,
  DeviceOption,
  keyWord,
  m_editor,
  enterGroupCell,
  currentSwimArray,
  CommonFunRow,
  QCFunRow,
  scalSize,
  forceEdit,
  ifCanBeEdite,
  currentInstance,
  m_toolbar,
  ifEditable,
  mxClient,
  mxUtils,
  mxPerimeter,
  mxDivResizer,
  SFCcolor,
  mxCell,
  mxKeyHandler,
  mxRubberband,
  showDeviceButton,
  cellsCurrentParent,
  ifUpdate,
  moduleType,
  AllfunOption,
  planDevice,
  matLimitOption,
  localGuiID,
  emits,
  handleClosePerty,
  outMaxKeyWord,
  titleFontSize,
  modal,
  isShowAnd,
  isShowOR,
  isShowCondition,
  isShowComplexCondition,
  isShowSub,
  isShowReturn,
  isShowQC,
  ParamNameReplaceRelation,
  baseParameterOption,
  isShowStart,
  isShowStop,
  isShowCompleted,
  isShowPause,
  isShowContinue,
  isShowCancel,
  isShowReset,
});

const {
  handleRefresh,
  handleScale,
  handleDel,
  handlePast,
  handleCopy,
  handleCut,
  handleLarg,
  handleSmall,
  handleUnset,
  handleSave,
  handleChangeKeyWord,
  handlePrint,
  handleInsert,
  handleGroup,
  handleUnGroup,
  handleSelectAll,
  handleNone,
  handleUndo,
  handleRedo,
  handleUp,
  handleNext,
  handleEnterGroup,
  handleExitGroup,
  handleAlignLeft,
  handleAlignRight,
  handleAlignTop,
  handleAlignBottom,
  handleMiddle,
  handleCenter,
  handleAlignVer,
  handleAlignHor,
  handleEqualWidth,
  handleEqualHeight,
  handleEqualAll,
  handleToFont,
  handleToBack,
  handleChooseSwimlane,
  setCellSize,
  reviseBusLinePosition,
  EnterWorkGroup,
  setSubSwimlane,
  handleEnterNextLevel,
  setSwimlaneToBack,
  drawHubCell,
  _initGraph,
  getCurrentSwimLanePosit,
  checkIfLayerWarning,
  _setNewVertexParam,
  checkSwimPosition,
  changeDeviceByParent,
  checkEdgePosition,
  chechIfCanBeConect,
  setEdgeValue,
  setLinePorperty,
  setEntry,
  setCellPorperty,
  reWritePaste,
  reWriteCreateID,
  checkCellIfLocked,
  chechIfShowBotton,
  setItemPoeperty,
  setSwimeAutoSize,
  setLinePosition,
  checkIfHaveChild,
  showGraphByXML,
  setBusWidth,
  getReceipTotalWeight,
  getCurrentXml,
  getCellsByProperty,
  addOverlays,
  showCellsOnly,
  syncTableCellBounds,
} = graphMethods;

watch(
  () => showDeviceButton.value,
  (value) => {
    let height = $("#graph-main-container")[0].clientHeight - 47;
    if (value == true) {
      menuHeight = 35;
      containerHeight.value = (height - 35).toString();
    } else {
      menuHeight = 0;
      containerHeight.value = height.toString();
    }
  },
);

watch(
  () => props.data,
  (_val) => {
    const flow = decode(_val);
    showGraphByXML(flow);
  },
);

watch(
  () => props.ifCanBeEdite,
  (_val) => {
    ifEditable.value = _val;
  },
);
watch(ifEditable, (_val) => {
  if (_val == false) {
    //@ts-ignore
    m_graph_show.setConnectable(false);
    //@ts-ignore
    m_graph_show.setCellsMovable(false);
    //@ts-ignore
    m_graph_show.setCellsDeletable(false);
    //@ts-ignore
    m_graph_show.clearSelection();
  } else {
    //@ts-ignore
    m_graph_show.setConnectable(true);
    //@ts-ignore
    m_graph_show.setCellsMovable(true);
    //@ts-ignore
    m_graph_show.setCellsDeletable(true);
    //@ts-ignore
    m_graph_show.setEnabled(true);
  }
  emits("ifEditableChange", _val);
});

watch(currentGroupCell, (_val) => {
  //@ts-ignore
  let models = m_graph_show.getModel();
  let cells = models.cells;
  for (const i in cells) {
    if (_val) {
      //@ts-ignore
      if (cells[i].id == _val.id) {
        cells[i].connectable = false;
      } else {
        cells[i].connectable = true;
      }
    }
  }
  //@ts-ignore
  _val.setConnectable(false);
});

watch(groupLayer, (params) => {
  //@ts-ignore
  let cells = m_graph_show.getModel().cells;
  for (let i in cells) {
    if (cells[i].cellType) {
      if (cells[i].cellType == "WorkGroup") {
        if (params == 0) {
          cells[i].connectable = true;
        } else {
          cells[i].connectable = false;
        }
      }
    }
  }
});

watch(
  () => props.outMaxKeyWord,
  (Val) => {
    if (Val > keyWord.value) {
      keyWord.value = Val;
    }
  },
);

const getIsFunStyleValid = function (style: number) {
  let bRet = true;
  let targetFun = props.AllfunOption.filter((item: any) => {
    return item.FuncStyle == style && item.IsValid == true;
  });

  if (targetFun.length < 1) {
    bRet = false;
  } else {
    bRet = true;
  }
  return bRet;
};
const handleFullScreen = function () {
  isFullScreen.value = !isFullScreen.value;
  emits("fullScreenState", isFullScreen.value);
};

const setHeader = function (height: number) {
  //计算显示列高度
  return accMul(height, scalSize.value);
};

const handleImport = function (e: any) {
  //引入文件显示
  const file = e.originalEvent.srcElement.files[0];
  const path = window.URL.createObjectURL(file);
  const fileContent = mxUtils.load(path);
  var xml = fileContent.request.response;
  showGraphByXML(xml, true);
};
const handleCircle = function (value: boolean) {
  circle.value = value;
};

const handleShowGraphTree = function (bRet: boolean) {
  //@ts-ignore
  const model = m_graph_show.getModel();
  //@ts-ignore
  emits("showGraphTree", model, m_graph_show, bRet);
};

const handlesetEnablePorper = function () {
  //@ts-ignore
  m_graph_show.isEnabled();
  //this.ifEditable = !this.ifEditable;
  //this.ifUpdate = !this.ifUpdate; //是否只更新
};

const handleDbClick = function () {
  //@ts-ignore
  m_graph_show.addListener(mxEvent.DOUBLE_CLICK, function (sender, evt) {
    //元素双击事件
    if (props.showMode == "view") {
      return;
    }
    //@ts-ignore
    const cell = evt.properties.cell; //获取当前选择的元素的所有信息
    if (typeof cell == "undefined") {
      return;
    }
    selectGroupCell.value = cell; //当前选中的group元素
    //@ts-ignore
    emits("cellDbClick", selectGroupCell.value, m_graph_show);
    if (cell.isEdge() != true) {
      handleEnterNextLevel(cell);
    }
  });
};
const handleClick = function () {
  const refreshCellAfterOverlayReady = (targetCell: any) => {
    if (!targetCell) return;
    if (props.showMode == "view") {
      return;
    }
    const doRefresh = () => {
      //@ts-ignore
      m_graph_show.refresh();
      //@ts-ignore
      if (m_graph_show.isCellSelected(targetCell)) {
        //@ts-ignore
        m_graph_show.setSelectionCells([targetCell]);
      }
    };
    // In qiankun container, overlay icon image decode can be delayed.
    // Defer refresh to the next paint(s) so value/label layout is recalculated.
    requestAnimationFrame(() => {
      requestAnimationFrame(() => {
        doRefresh();
      });
    });
    nextTick(() => {
      doRefresh();
    });
  };
  //@ts-ignore
  m_graph_show.addListener(mxEvent.CLICK, function (sender, evt) {
    //元素单击事件
    nextTick(() => {
      const rawCell = evt.properties.cell; //获取当前选择的元素的所有信息
      const cell =
        rawCell?.cellType == "keyWords" && rawCell?.parent?.cellType == "Table"
          ? rawCell.parent
          : rawCell;
      if (typeof cell == "undefined") {
        emits("closeParamForm", 1);
        return;
      }
      if (cell) {
        //@ts-ignore 在生成图标之前，先清除页面上所有的图标
        m_graph_show.clearCellOverlays();
        if (cell.cellType) {
          //专注于生成操作按钮
          if (
            cell.cellType != "End" &&
            cell.cellType != "Channel" &&
            cell.edge != true &&
            cell.cellType != "Bus" &&
            cell.cellType != "Table"
          ) {
            //@ts-ignore
            if (
              props.DownloadStatus == true &&
              props.PlanBatch != "" &&
              props.isShowOperateBtn == true &&
              props.isShowOperateBtnInGraph == true
            ) {
              //是工单，并且是下载状态，才能显示操作按钮
              addOverlays(
                m_graph_show,
                cell,
                props.StartMode,
                props.PlanBatch,
                props.IsFormular,
                props.WorkCenterId,
              ); //如果选中当前图元，则生成对应图标
              refreshCellAfterOverlayReady(cell);
            }
          }
          currentGroupCell.value = cell;
        }
      }
      //@ts-ignore
      m_graph_show.setSelectionCells([cell]);
      if (cell.cellType == "Table") {
        requestAnimationFrame(() => {
          //@ts-ignore
          if (!m_graph_show.isCellSelected(cell)) {
            //@ts-ignore
            m_graph_show.setSelectionCells([cell]);
          }
        });
      }
      if (cell.cellType == "Layer") {
        currentInsertCell.value = cell;
      }
      if (cell) {
        //获取当前复制单元需要插入的图元信息
        if (cell.cellType == "Channel") {
          cellsCurrentParent.value = cell;
        } else {
          cellsCurrentParent.value = cell.parent;
        }
      }

      if (
        cell.cellType == "Qc" &&
        (cell.QCItems == undefined || cell.QCItems.length == 0)
      ) {
        if (props.ifCanBeEdite == true) {
          if (props.matLimitOption.length > 0) {
            //在调整的模式下，不管是什么生产状态，当前是非调整工艺的话，则不允许调整
            if (!cell.IsAdjust || typeof cell.IsAdjust == "undefined") {
              emits("closeParamForm", 1);
              return;
            }
          }
          setItemPoeperty(cell);
        }
        return;
      } else {
        if (props.matLimitOption.length > 0) {
          //在调整的模式下，不管是什么生产状态，当前是非调整工艺的话，则不允许调整
          if (!cell.IsAdjust || typeof cell.IsAdjust == "undefined") {
            emits("closeParamForm", 1);
            return;
          }
        }
        setItemPoeperty(cell);
      }
      if (props.ifCanBeEdite == true) {
        //在可编辑的情况下，才可以修改
        if (cell.cellType == "Channel" && cell.Status == 1) {
          return;
        }
        if (cell.Status != 2) {
          //已生产的数据，不允许编辑
          setItemPoeperty(cell);
        }
      } else {
        setItemPoeperty(cell);
      }
      if (cell.cellType == "HubCell") {
        //如果选择的是hubcell,则需要把父组件选中，方便用户操作
        //@ts-ignore
        m_graph_show.setSelectionCells([cell.parent]);
      }
      nextTick(() => {
        emits("cellClick", cell);
      });
    });
  });
};

const handelResizeCell = function () {
  //@ts-ignore
  m_graph_show.addListener(mxEvent.RESIZE_CELLS, function (sender, evt) {
    //元素大小改变事件
    //@ts-ignore
    const cell = m_graph_show.getSelectionModel(); //获取当前选择的元素的所有信息
    if (cell.cells.length < 1) {
      return;
    }

    const selectCell = cell.cells[0];
    if (selectCell.cellType == "Bus") {
      getCurrentSwimLanePosit(selectCell);
    }
    if (selectCell.cellType == "Channel") {
      reviseBusLinePosition();
    }

    if (selectCell.cellType == "HubIn" || selectCell.cellType == "HubOut") {
      selectCell.geometry.height = 16; //高度不允许改变
      let num = Math.ceil(selectCell.geometry.width / 8); //向上取整
      selectCell.geometry.width = num * 8;
      selectCell.defaultWidth = selectCell.geometry.width;
      //@ts-ignore
      m_graph_show.removeCells(selectCell.children); //先删除图元
      drawHubCell(selectCell, num - 1);
    }
    setCellSize(selectCell); //设置图元大小
    chechIfShowBotton();
    //@ts-ignore
    m_graph_show.refresh();
  });
};

const handelMove = function () {
  //@ts-ignore
  m_graph_show.addListener(mxEvent.CELLS_MOVED, function (sender, evt) {
    //移动事件
    changeDeviceByParent();

    //@ts-ignore
    var cell = evt.properties; //获取当前选择的元素的所有信息
    var selectCell = cell.cells[0];
    if (selectCell == undefined) return;
    if (selectCell.cellType == "Channel") {
      selectCell.geometry.x = selectCell.defaultX;
      selectCell.geometry.y = selectCell.defaultY;
    }
    nextTick(() => {
      //@ts-ignore
      // let cell = m_graph_show.getSelectionModel(); //获取当前选择的元素的所有信息
      // let selectCell = cell.cells[0];
      //移动的时候，自动设置泳道的宽和高
      setSwimeAutoSize(selectCell);
    });
    if (selectCell.cellType == "Bus") {
      getCurrentSwimLanePosit(selectCell);
    }
    if (selectCell.cellType != "Channel") {
      //如果不是用到，则每次移动的时候，都记录默认位置
      selectCell.defaultX = selectCell.geometry.x;
      selectCell.defaultY = selectCell.geometry.y;
    }
    if (selectCell.edge == false) {
      setLinePosition(selectCell);
    }
    checkEdgePosition();
    setEntry();
    setSwimlaneToBack();
    //@ts-ignore
    m_graph_show.refresh();
  });
};
const handleAddVertex = function () {
  //@ts-ignore
  m_graph_show.addListener(mxEvent.CELLS_ADDED, function (sender, evt) {
    if (evt.properties.cells) {
      //记录原始父节点
      for (let i = 0; i < evt.properties.cells.length; i++) {
        evt.properties.cells[i].localParentID =
          evt.properties.cells[i].parent.id;
      }
    }
    chechIfShowBotton();
    _setNewVertexParam(sender, evt);
    nextTick(() => {
      //检查是否有报警信息，目前只针对组做了报警信息
      checkIfLayerWarning();
    });
  });
};

const handleRemove = function () {
  //@ts-ignore
  m_graph_show.addListener(mxEvent.REMOVE_CELLS, function () {
    //删除事件的拦截，应该还是需要重写remove函数，因为很多事件操作里面用到了这个，单独拦截的话，可能会不全面
    checkSwimPosition(); //检查泳道的位置
    chechIfShowBotton();
    setBusWidth();
    //@ts-ignore
    m_graph_show.refresh();
  });
};
const handleConect = function () {
  //@ts-ignore
  m_graph_show.addListener(mxEvent.CELL_CONNECTED, function (sender, evt) {
    const edgeInfo = evt.properties.edge;
    edgeInfo.groupLayer = groupLayer.value;
    const graph = m_graph_show;
    //@ts-ignore
    var model = graph.getModel();
    if (edgeInfo.target) {
      setEdgeValue(edgeInfo, edgeInfo.source, edgeInfo.target);
      if (!edgeInfo.getId()) {
        if (!model.cells[edgeInfo.id]) {
          // 重新分配ID并添加到cells
          var newId = model.createId(edgeInfo);
          model.cells[newId] = edgeInfo;
          edgeInfo.id = newId;
        }
      }
      //console.log('修复边ID:', edgeInfo.getId());
      chechIfCanBeConect(evt);
      checkEdgePosition();
      setEntry();
      setLinePorperty();
      setSwimlaneToBack(); //连线的时候，强制将swimlane置为下层
      //@ts-ignore

      // 检查是否在模型中注册
      //   //强制设置连接线和目标图元在同一父节点下
      //   if (edgeInfo.target.cellType == "Bus") {
      //     edgeInfo.parent = edgeInfo.target.parent
      //   } else {
      //     edgeInfo.parent = edgeInfo.source.parent
      //   }
      //   edgeInfo.groupLayer = groupLayer.value
    }

    //@ts-ignore
    m_graph_show.refresh();
  });
};

const handleGraphScale = function () {
  //画面缩放事件
  //@ts-ignore
  m_graph_show.addListener(mxEvent.SIZE, function (sender) {
    scalSize.value = sender.view.scale; //缩放倍数

    nextTick(() => chechIfShowBotton());
  });
};

const bindEvent = function () {
  //给编辑器绑定事件
  checkIfCanHandleByKey();
  reWritePaste();
  reWriteCreateID;
  handleDbClick();
  handleClick();
  handelResizeCell();
  handelMove();
  handleRemove();
  handleConect();
  handleAddVertex();
  handleGraphScale();
  checkCellIfLocked();
};

const checkIfCanHandleByKey = function () {
  //检查当前元素是否可以被删除
  //重写键盘事件
  //@ts-ignore
  mxKeyHandler.prototype.getFunction = function (evt: any) {
    //@ts-ignore
    var control =
      //@ts-ignore
      mxEvent.isControlDown(evt) || (mxClient.IS_MAC && evt.metaKey)
        ? this.controlKeys[evt.keyCode]
        : this.normalKeys[evt.keyCode];
    if (evt.key === "Delete") {
      return () => handleDel();
    } else if (
      evt.ctrlKey == true &&
      (evt.key == "c" || evt.key == "x" || evt.key == "s")
    ) {
      if (getCellsByProperty("cellType", "Channel")) {
        return null;
      } else {
        return control;
      }
    } else {
      return control;
    }
  };
};

const handleScroll = function () {
  $("#" + localGuiID + "graph_container").on("scroll", function () {
    //.scroll(function() {
    const left = this.scrollLeft;

    if (this.scrollTop <= 35) {
      showBtn.value = false;
    } else {
      showBtn.value = true;
    }
    //@ts-ignore
    var divButton = currentInstance.refs[localGuiID + "divButton"];
    if (!divButton || typeof divButton == "undefined") {
      return;
    }
    //@ts-ignore
    divButton.style.marginLeft = -left + "px";
    currentSwimArray.value = [];
    chechIfShowBotton();
  });
};

const setSiderStyle = function () {
  //设置左侧工具栏显示宽度
  let targetSider = $("#" + localGuiID + "left_menu");
  if (targetSider.length > 0) {
    targetSider[0].style.width = "30px !important";
    targetSider[0].style.maxWidth = "30px !important";
    targetSider[0].style.minWidth = "30px !important";
    targetSider[0].style.flex = "0 0 30px!important";
    const children = targetSider.find(".ant-layout-sider-children");
    if (children.length > 0) {
      children[0].style.width = "30px !important";
    }
  }
  let targetGraph = $("#" + localGuiID + "graph_container");
  if (targetGraph.length > 0) {
    targetGraph[0].style.background =
      'url("../../assets/mxgraph-source/images/images/grid.jpg")';
    targetGraph[0].style.backgroundColor = "white";
  }
};

events.on("porpertyChange", (formData) => {
  //从事件总线接收事件
  setCellPorperty(formData);
});
//20260317调整成显示时候，不响应导入组事件
// events.on("importGroup", (xmlData) => {
//   nextTick(() => {
//     if (currentInsertCell.value) {
//       setSubSwimlane(currentInsertCell.value);
//       //@ts-ignore
//       const flow = decode(xmlData);
//       handleInsert(flow);
//     }
//   });
// });

onMounted(() => {
  //@ts-ignore
  if (!mxClient.isBrowserSupported()) {
    //验证浏览器是否支持绘图
    mxUtils.error("当前浏览器不支持", 200, false);
  } else {
    //setSiderStyle()
    m_graph_show = _initGraph();
    bindEvent(); //事件绑定函数
    handleScroll();
    registerExtraShape(mxCellRenderer, mxCylinder, mxUtils);
    var temp = $("#" + localGuiID + "graph_container")[0].clientHeight - 47;
    if (temp) {
      containerHeight.value = temp.toString();
    }
    //containerHeight.value = $("#" + localGuiID + "graph_container")[0].clientHeight - 47; // $("#main-graph")[0].clientHeight; //

    if (props.data != "" && props.data != null) {
      const flow = decode(props.data);
      showGraphByXML(flow);
    } else {
      //将图元显示到当前画布中
      if (props.showCells.length > 0 && props.showMode == "view") {
        showCellsOnly(props.showCells);
      }
    }
  }
});

onBeforeMount(() => {
  clearMxTooltip();
});

onBeforeUnmount(() => {
  //组件销毁的时候，清掉相关实例
  showGlobal.value = false;

  //@ts-ignore
  if (m_graph_show) {
    //@ts-ignore
    m_graph_show.destroy();
  }
  if (m_editor) {
    //@ts-ignore
    m_editor.destroy();
  }
  if (m_toolbar) {
    //@ts-ignore
    m_toolbar.destroy();
  }
  $("#" + localGuiID + "graph_container").off("scroll", function () {});
  clearMxTooltip();
});

defineExpose({ getReceipTotalWeight, getCurrentXml });
</script>

<style>
.graph_container {
  background: url("../../assets/mxgraph-source/images/images/grid.jpg");
  background-color: white;
}

.deviceButtonOne {
  margin-left: 0px;
  height: 36px;
  border-radius: 0px;
  font-weight: bold;
  font-size: 16px;
  color: black;
  border-color: black;
  border-bottom-width: 1px;
}

.deviceButtonMidle {
  margin-left: 0px;
  height: 36px;
  border-radius: 0px;
  font-weight: bold;
  font-size: 16px;
  color: black;
  border-color: black;
  border-left-width: 0px;
  border-bottom-width: 1px;
}

.fullScreen {
  position: fixed;
  top: 0px;
  left: 0px;
  width: 100%;
  background-color: white;
  background: url("../../assets/mxgraph-source/images/images/grid.gif");
}

.mxToolbarMode:hover {
  background-color: lightgreen;
}

.graph-main-container
  :deep(
    .ant-tabs.ant-tabs-top.ant-tabs-card.ant-tabs-editable-card.ant-tabs-editable.base-frame
  ) {
  height: 100%;
}

.left_menu {
  width: 30px !important;
  min-width: 30px !important;
  max-width: 30px !important;
  flex: 0 0 30px !important;
}

.left_menu > .ant-layout-sider-children {
  width: 30px !important;
}

.ant-form-item {
  margin-bottom: 0px !important;
}
</style>
