<template>
  <div class="addDialogChunk">
    <base-right-dialog
      @handleClose="examineHandleClose"
      :dialogVisible="examineOperateDialog"
      size="100%"
      :appendBody="true"
      :loading="sceneLoading"
      :footerShow="true"
      :submitShow="true"
      @handleConfirmClick="handleConfirmClick"
      :submitTitle="'发布'"
      :submitIcon="'el-icon-upload2'"
      :title="sceneName"
    >
      <template #operateTitle>
        <img
          style="width: 15px; height: 15px; margin-left: 10px; cursor: pointer"
          src="../images/edit.svg"
          @click="editSceneName"
        />
      </template>
      <div
        class="rightDialogClass_main drawContent"
        v-if="drawShowList.length > 0"
        style="background: #fff"
      >
        <!-- 步骤画布 -->
        <div class="drawCanvas" v-show="!representation">
          <div
            class="drawItem"
            v-for="(ele, index) in drawShowList"
            :key="ele.value"
          >
            <div class="title">{{ ele.title }}</div>
            <div
              @click="selectDrawItem(index)"
              class="drawBox"
              :class="{ active: index == drawSelectIndex }"
            >
              <template v-if="index == 0">
                <div class="img">
                  <img src="../images/pingtai.svg" v-if="triggerMode == 2" />
                  <img
                    src="../images/naozhong.svg"
                    v-else-if="triggerMode == 1"
                  />
                  <img src="../images/api.svg" v-else-if="triggerMode == 4" />
                  <img src="../images/point.svg" v-else-if="triggerMode == 3" />
                </div>
                <div style="width: calc(100% - 60px)">
                  <div class="actionName">
                    {{ index + 1 + "." + ele.actionName }}
                  </div>
                  <div
                    class="content DescribeContent"
                    v-if="!ele.options.taskType"
                  >
                    {{ ele.content }}
                  </div>
                  <div class="content" v-else>
                    {{ getTimeDivide(ele.options.taskType) }}
                  </div>
                </div>
              </template>
              <template v-else>
                <div
                  :class="
                    ele.options && ele.options.iconUrl ? 'iconStyle' : 'img'
                  "
                >
                  <img
                    v-if="ele.options && ele.options.iconUrl"
                    :src="
                      ele.options.iconUrl
                        ? ele.options.iconUrl.split('/wwwroot')[1]
                        : ''
                    "
                  />
                  <img v-else src="../images/huaO.svg" />
                </div>
                <div style="width: calc(100% - 60px)">
                  <div class="actionName" v-if="!ele.options.appName">
                    {{ index + 1 + "." + ele.actionName }}
                  </div>
                  <div
                    class="actionName"
                    style="display: flex; align-items: center"
                    v-else
                  >
                    {{ index + 1 + "." + ele.options.appName }}
                  </div>

                  <div
                    class="content DescribeContent"
                    v-if="ele.options.stepDescribe"
                  >
                    {{ ele.options.stepDescribe }}
                  </div>
                  <div class="content" v-else>{{ ele.content }}</div>
                </div>
              </template>

              <div
                @click.stop="delDrawItem(ele, index)"
                v-if="index != 0"
                class="del"
              >
                <img src="../images/close.svg" />
              </div>
            </div>
            <div class="line-wrapper" v-if="index != drawShowList.length - 1">
              <div class="line"></div>
              <img
                src="../images/addBtn.svg"
                @click.stop="insertDrawItem(ele, index)"
              />
            </div>
          </div>

          <div @click="addDrwaItem" class="drawItem drawItemBtn">
            添加新步骤
          </div>
        </div>
        <!-- 动态内容及其表达式 -->
        <div
          class="drawCanvas"
          style="align-items: flex-start; padding: 0"
          v-show="representation"
        >
          <div class="repContainer">
            <el-tabs v-model="representationActiveName">
              <el-tab-pane label="动态内容" name="first"></el-tab-pane>
              <el-tab-pane label="表达式" name="second"></el-tab-pane>
            </el-tabs>
            <div class="closeRepContainer" @click="closeRepContainer">
              <i class="el-icon-close"></i> 关闭
            </div>
            <div class="treeNodeBox" v-if="representationActiveName == 'first'">
              <tree-node
                v-for="(value, key) in treeData"
                :key="key"
                :node-key="key"
                :node-value="value"
                :path="key"
                :selected-node="selectedNode"
                @node-selected="handleNodeSelected"
              />
            </div>
            <div
              class="treeNodeBox"
              v-if="representationActiveName == 'second'"
            >
              <el-tabs tab-position="left" style="height: 100%">
                <el-tab-pane
                  v-for="(item, index) in representationData"
                  :label="item.label"
                >
                  <template v-for="(row, rowIndex) in item.children">
                    <div class="repItem" @click="handleTagSelected(row.label)">
                      <el-tag size="small">
                        {{ row.label }}
                      </el-tag>
                      <span class="repItemValue">{{ row.value }}</span>
                    </div>
                  </template>
                </el-tab-pane>
              </el-tabs>
            </div>
          </div>
        </div>
        <!-- 操作区 -->
        <!-- 第一步的时候单独处理 -->
        <div class="drawAction" v-if="drawSelectIndex == 0">
          <el-tabs v-model="activeTabName">
            <el-tab-pane label="1. 选择操作" name="选择操作">
              <div
                class="currentDrawBox"
                style="padding: 10px"
                v-if="drawShowList.length > 0"
              >
                <div class="drawimg">
                  <img src="../images/pingtai.svg" v-if="triggerMode == 2" />
                  <img
                    src="../images/naozhong.svg"
                    v-else-if="triggerMode == 1"
                  />
                  <img src="../images/api.svg" v-else-if="triggerMode == 4" />
                  <img src="../images/point.svg" v-else-if="triggerMode == 3" />
                </div>
                <div style="width: calc(100% - 60px)">
                  <div class="actionName">
                    {{ 1 + "." + drawShowList[0].actionName }}
                  </div>
                  <div class="content" v-if="!drawShowList[0].options.taskType">
                    {{ drawShowList[0].content }}
                  </div>
                  <div class="content" v-else>
                    {{ getTimeDivide(drawShowList[0].options.taskType) }}
                  </div>
                </div>
              </div>
              <div class="timeWrap">
                <template v-for="(item, index) in timeDivide">
                  <div
                    @click="handleTimeItem(item, index)"
                    :class="{ activTimeItem: activTimeIndex == item.id }"
                    class="timeItem"
                  >
                    <div class="imgBox">
                      <img src="../images/shandian.svg" />
                    </div>
                    <div>
                      <div class="title">{{ item.title }}</div>
                      <div class="content">{{ item.content }}</div>
                    </div>
                  </div>
                </template>
              </div>
            </el-tab-pane>
            <el-tab-pane
              label="2. 配置"
              name="配置"
              :disabled="!this.activTimeIndex"
            >
              <div
                class="currentDrawBox"
                style="padding: 10px"
                v-if="drawShowList.length > 0"
              >
                <div class="drawimg">
                  <img src="../images/pingtai.svg" v-if="triggerMode == 2" />
                  <img
                    src="../images/naozhong.svg"
                    v-else-if="triggerMode == 1"
                  />
                  <img src="../images/api.svg" v-else-if="triggerMode == 4" />
                  <img src="../images/point.svg" v-else-if="triggerMode == 3" />
                </div>
                <div style="width: calc(100% - 60px)">
                  <div class="actionName">
                    {{ 1 + "." + drawShowList[0].actionName }}
                  </div>
                  <div class="content" v-if="!drawShowList[0].options.taskType">
                    {{ drawShowList[0].content }}
                  </div>
                  <div class="content" v-else>
                    {{ getTimeDivide(drawShowList[0].options.taskType) }}
                  </div>
                </div>
              </div>
              <div class="crontabBox">
                <div class="crontabBoxTitle">cron表达式</div>
                <FishCrontab
                  ref="fishCrontab"
                  class="crontab"
                  @fill="crontabFill"
                  :expression="expression"
                  :fiveTimes="false"
                ></FishCrontab>
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
        <!-- 其他步骤 -->
        <div class="drawAction" v-else v-loading="drawMask">
          <el-tabs
            v-model="activeOtherTabName"
            @tab-click="handleOtherTabClick"
          >
            <el-tab-pane label="1. 选择应用" name="选择应用">
              <!-- 选中的操作步骤 -->
              <div class="drawItemBox">
                <div class="currentDrawBox" style="width: 100%">
                  <div class="img">
                    <img class="appIcon" src="../images/applicotion.svg" />
                  </div>
                  <div style="width: calc(100% - 64px)">
                    <!-- 应用名称 -->
                    <div class="actionName" v-if="CurrentAppRow.appName">
                      {{ CurrentAppRow.appName }}
                    </div>
                    <!-- 步骤描述 -->
                    <div class="content" v-if="CurrentAppRow.description">
                      {{ CurrentAppRow.description }}
                    </div>
                  </div>
                </div>
              </div>
              <div class="search">
                <el-input
                  class="input"
                  v-model="appCodeOrName"
                  placeholder="请输入"
                  clearable
                  style="width: 210px"
                  @keydown.enter.native="searchApp"
                ></el-input>
                <el-button
                  type="primary"
                  style="margin-right: 5px"
                  size="small"
                  @click="searchApp"
                  >查询</el-button
                >
              </div>
              <div
                class="app"
                style="max-height: calc(-345px + 100vh); overflow: auto"
              >
                <div class="applist">
                  <div
                    v-for="(app, index) in appList"
                    class="appItem"
                    @click="hangleAppItem(app, index)"
                    :class="{ active: appActivIndex == app.id }"
                  >
                    <img class="appIcon" src="../images/applicotion.svg" />
                    <div class="name">{{ app.name }}</div>
                  </div>
                </div>
              </div>
              <div class="DescribeDataBox">
                <span style="font-size: 14px">步骤描述</span>
                <el-input
                  class="input"
                  v-model="description"
                  placeholder="请输入步骤描述"
                  clearable
                  @blur="changeDescription"
                  type="textarea"
                ></el-input>
              </div>
            </el-tab-pane>
            <el-tab-pane
              label="2. 选择操作"
              name="选择操作"
              :disabled="!this.appActivIndex"
            >
              <!-- 选中的操作步骤 -->
              <div class="drawItemBox">
                <div class="currentDrawBox" style="width: 100%">
                  <div class="img">
                    <img class="appIcon" src="../images/applicotion.svg" />
                  </div>
                  <div style="width: calc(100% - 64px)">
                    <!-- 应用名称 -->
                    <div class="actionName" v-if="CurrentAppRow.appName">
                      {{ CurrentAppRow.appName }}
                    </div>
                    <!-- 步骤描述 -->
                    <div class="content" v-if="CurrentAppRow.description">
                      {{ CurrentAppRow.description }}
                    </div>
                  </div>
                </div>
              </div>
              <div class="search">
                <el-input
                  class="input"
                  v-model="operateCodeOrName"
                  placeholder="请输入"
                  style="width: 210px"
                  clearable
                  @keydown.enter.native="searchApiPlugin"
                ></el-input>
                <el-button type="primary" size="small" @click="searchApiPlugin"
                  >查询</el-button
                >
              </div>

              <el-radio-group
                v-model="activeApiPliginTabName"
                @change="ApiPliginTabChangeEvent"
              >
                <el-radio-button label="API接口">API接口</el-radio-button>
                <el-radio-button label="插件">插件</el-radio-button>
              </el-radio-group>
              <div class="ApiPliginBox app">
                <div
                  class="applist"
                  v-show="activeApiPliginTabName == 'API接口'"
                >
                  <div
                    v-for="(item, index) in apiList"
                    class="appItem"
                    @click="hangleApiClickEvent(item, index)"
                    :class="{ active: apiIdActiv == item.id }"
                  >
                    <div class="imgBox">
                      <img src="../images/shandian.svg" />
                    </div>
                    <div>
                      <div class="name">{{ item.apiName }}</div>
                      <div class="name">{{ item.apiPath }}</div>
                    </div>
                  </div>
                </div>

                <div class="applist" v-show="activeApiPliginTabName == '插件'">
                  <div
                    v-for="(item, index) in pluginList"
                    class="appItem"
                    @click="hanglePluginClickEvent(item, index)"
                    :class="{ active: pluginActiv == item.id }"
                  >
                    <div class="imgBox">
                      <img src="../images/shandian.svg" />
                    </div>
                    <div>
                      <div class="name">{{ item.plugName }}</div>
                      <div class="name">{{ item.plugDescribe }}</div>
                    </div>
                  </div>
                </div>
              </div>
            </el-tab-pane>
            <el-tab-pane
              label="3. 选择账号"
              name="选择账号"
              :disabled="
                !this.appActivIndex || !(this.apiIdActiv || this.pluginActiv)
              "
            >
              <!-- 选中的操作步骤 -->
              <div class="drawItemBox">
                <div class="currentDrawBox" style="width: 100%">
                  <div class="img">
                    <img class="appIcon" src="../images/applicotion.svg" />
                  </div>
                  <div style="width: calc(100% - 64px)">
                    <!-- 应用名称 -->
                    <div class="actionName" v-if="CurrentAppRow.appName">
                      {{ CurrentAppRow.appName }}
                    </div>
                    <!-- 步骤描述 -->
                    <div class="content" v-if="CurrentAppRow.description">
                      {{ CurrentAppRow.description }}
                    </div>
                  </div>
                </div>
              </div>
              <div class="userList">
                <div @click="addAccount" class="userItem userBtn">
                  <i
                    class="el-icon-plus"
                    style="font-size: 12px; margin-right: 5px"
                  ></i>
                  添加账户
                </div>
                <div class="userContentBox">
                  <div
                    v-for="(item, index) in userList"
                    class="userItem"
                    style="justify-content: flex-start"
                    @click="handleUserClickEvent(item, index)"
                    :class="{ active: userActivId == item.id }"
                  >
                    <div class="status">
                      <i
                        class="el-icon-success"
                        style="color: #7ec050"
                        v-if="item.status == 1"
                      ></i>
                      <i
                        class="el-icon-error"
                        style="color: #f56c6c"
                        v-else-if="item.status == 0"
                      ></i>
                      <i
                        class="el-icon-remove"
                        style="color: #919398"
                        v-else
                      ></i>
                    </div>
                    <div>
                      <div class="userName">{{ item.name }}</div>
                      <div class="content" style="margin-top: 5px">
                        最新编辑时间：{{ item.modify_time }}
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </el-tab-pane>
            <el-tab-pane
              label="4. 配置"
              name="配置应用"
              :disabled="
                !this.appActivIndex ||
                !(this.apiIdActiv || this.pluginActiv) ||
                !this.userActivId
              "
            >
              <!-- 选中的操作步骤 -->
              <div class="drawItemBox">
                <div class="currentDrawBox" style="width: 100%">
                  <div class="img">
                    <img class="appIcon" src="../images/applicotion.svg" />
                  </div>
                  <div style="width: calc(100% - 64px)">
                    <!-- 应用名称 -->
                    <div class="actionName" v-if="CurrentAppRow.appName">
                      {{ CurrentAppRow.appName }}
                    </div>
                    <!-- 步骤描述 -->
                    <div class="content" v-if="CurrentAppRow.description">
                      {{ CurrentAppRow.description }}
                    </div>
                  </div>
                </div>
              </div>
              <div class="outsideContent">
                <!-- 选择表 -->
                <el-form
                  ref="outsideForm"
                  :model="outsideFormData"
                  :rules="outsideRules"
                  label-width="80px"
                  label-position="top"
                  style="margin-bottom: 10px"
                >
                  <el-form-item label="选择表">
                    <el-select
                      v-model="outsideFormData.tableName"
                      placeholder="请选择表"
                      @change="outsideSelectChange"
                      style="width: 100%"
                    >
                      <el-option
                        v-for="(el, index) in outsideOptions"
                        :key="index"
                        :label="el.table_name"
                        :value="el.table_name"
                      ></el-option>
                    </el-select>
                  </el-form-item>
                </el-form>

                <!-- 表字段 -->
                <el-collapse
                  v-model="activeNames"
                  v-if="outsideColumns.length > 0"
                >
                  <el-collapse-item title="查询条件配置" name="1">
                    <el-form
                      ref="ColumnsForm"
                      :model="ColumnsFormData"
                      :rules="ColumnsRules"
                      label-width="80px"
                      label-position="top"
                      style="margin: 0 10px"
                    >
                      <div ref="editorContainer">
                        <div
                          v-for="(row, rowIndex) in outsideColumns"
                          :key="rowIndex"
                        >
                          <el-form-item :label="row.column_name">
                            <div class="editor-container">
                              <div
                                class="content-editor"
                                :ref="
                                  'contentEditor' + row.column_name + rowIndex
                                "
                                contenteditable="true"
                                @keydown="
                                  handleKeyDown(
                                    $event,
                                    row.column_name,
                                    rowIndex
                                  )
                                "
                                @input="
                                  handleInput($event, row.column_name, rowIndex)
                                "
                                @click="
                                  handleEditorClick(
                                    $event,
                                    row.column_name,
                                    rowIndex
                                  )
                                "
                                @paste="
                                  handlePaste($event, row.column_name, rowIndex)
                                "
                                @focus="
                                  handleEditorFocus(
                                    $event,
                                    row.column_name,
                                    rowIndex
                                  )
                                "
                                @blur="
                                  handleEditorBlur(
                                    $event,
                                    row.column_name,
                                    rowIndex
                                  )
                                "
                              ></div>
                              <div
                                class="editorIcon"
                                @click.stop="
                                  handleAddNodeToEditor(
                                    row.column_name,
                                    rowIndex
                                  )
                                "
                              >
                                <i class="el-icon-circle-plus"></i>
                              </div>
                              <div
                                class="clearIcon"
                                @click.stop="
                                  handleClearNodeToEditor(
                                    row.column_name,
                                    rowIndex
                                  )
                                "
                              >
                                <i class="el-icon-circle-close"></i>
                              </div>
                            </div>
                          </el-form-item>
                        </div>
                      </div>
                    </el-form>
                  </el-collapse-item>
                </el-collapse>
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
      </div>
    </base-right-dialog>
    <editSence ref="editSence" @handleConfirmClick="updateTitle"></editSence>
    <addAccount
      ref="addAccount"
      @handleConfirmClick="addAccountConfirmClick"
    ></addAccount>
  </div>
</template>

<script>
// 导入编辑场景组件
import baseRightDialog from "@/components/base/baseRightDialog/index.vue";
import editSence from "./editSence.vue";
import { authApi } from "@/api/apis/auth";
// 导入步骤添加和使用的常量
import { stepAdd, stepUse, timeDivide, representationData } from "./constant";
// 导入 cron 表达式组件
import FishCrontab from "fish-crontab";
// 导入添加账号组件
import addAccount from "./addAccount.vue";
import baseForm from "@/components/base/baseNewForm";
import treeNode from "./TreeNode";
import IconsDialog from "../../tool/build/IconsDialog.vue";
export default {
  components: {
    editSence,
    baseRightDialog,
    FishCrontab,
    addAccount,
    baseForm,
    treeNode,
    IconsDialog,
  },
  data() {
    return {
      examineOperateDialog: false, //判断是都打开弹窗
      sceneLoading: false, //遮照
      sceneName: "", //场景名称
      sceneID: "", //场景ID
      // 画布列表，对应右侧操作区域
      drawShowList: [],
      drawSelectIndex: 0, // 当前选中的画布索引

      //当步骤为1时
      timeDivide: timeDivide,
      activeTabName: "选择操作", // 显示的操作栏
      activTimeIndex: "", // 当前选择操作的类型
      expression: "", //cron表达式
      // 其他步骤
      activeOtherTabName: "",
      CurrentAppRow: {}, // 当前选择的应用数据
      appCodeOrName: "", //应用搜索条件
      drawMask: false,

      // 应用列表
      appList: [],
      appCodeOrName: "", // 应用搜索关键字
      appActivIndex: "", // 当前选中的应用 ID
      description: "", //应用描述
      operateCodeOrName: "", //api 或者 插件的搜索
      activeApiPliginTabName: "API接口", // 当前操作是 API 还是插件
      // API 插件列表
      pluginList: [],
      // API 接口列表
      apiList: [],
      apiIdActiv: "", // 选择的 API ID
      pluginActiv: "", // 选择的插件 ID
      // 用户列表
      userList: [],
      userActivId: "", // 选择的用户 ID
      outsideFormRow: [
        {
          elCol: [
            {
              label: "选择表",
              prop: "tableName",
              tag: "elSelect",
              span: 24,
            },
          ],
        },
      ],
      outsideRules: {
        tableName: [
          {
            required: true,
            message: "请选择表",
            trigger: "change, blur",
          },
        ],
      },
      outsideFormData: {
        tableName: "",
      },
      outsideOptions: [],
      outsideColumns: [], //表字段
      activeNames: "1", //展开
      ColumnsFormData: {},
      ColumnsRules: {},

      representation: false,
      selectedNode: "",
      representationActiveName: "first",
      treeData: {
        user: {
          id: 1001,
          profile: {
            name: "李四",
            email: "lisi@example.com",
            settings: {
              theme: "dark",
              notifications: {
                email: true,
                sms: false,
                push: true,
              },
            },
          },
          permissions: ["read", "write", "admin"],
          metadata: {
            created_at: "2023-01-15T10:30:00Z",
            updated_at: "2024-03-20T15:45:30Z",
            version: 2.1,
          },
        },
        config: {
          database: {
            host: "localhost",
            port: 5432,
            ssl: false,
          },
          features: {
            experimental: ["ai_assist", "real_time_sync"],
            stable: ["user_management", "data_export"],
          },
        },
      },
      currenrActiveNodeRef: "",
      lastSelectedTokenIndex: -1,
      tokenCounter: 0,
      representationData: representationData,
    };
  },
  methods: {
    /**
     * 打开弹窗
     * @param {string} sceneID 场景 ID
     * @param {string} sceneName 场景名称
     * @param {string} type 操作类型
     * @param {number} triggerMode 触发模式
     */
    openDialog(sceneID, sceneName, type, triggerMode) {
      // 更新场景 ID
      this.sceneID = sceneID;
      // 更新场景类型
      this.sceneType = type;
      // 更新场景名称
      this.sceneName = sceneName;
      // 更新触发模式
      this.triggerMode = triggerMode;
      // 显示审核操作弹窗
      this.examineOperateDialog = true;
      // 显示场景加载状态
      this.sceneLoading = true;
      // 5 秒后隐藏场景加载状态
      setTimeout(() => {
        this.sceneLoading = false;
      }, 5000);

      if (type === "add") {
        // 新增时生成第一步
        let params = {
          flowId: this.sceneID,
          step: 1,
          stepType: 2,
        };
        this.SaveSceneStepData(params, "first");
      }

      if (type === "edit") {
        // 编辑时获取场景步骤列表
        this.GetSceneStepList();
      }
    },
    /**
     * 获取场景步骤列表
     */
    async GetSceneStepList() {
      // 清空画布列表
      this.drawShowList = [];
      // 获取场景步骤列表的参数
      let params = {
        flowId: this.sceneID,
      };
      let res = await authApi(
        "sysFlowStepService",
        "",
        "queryList",
        "",
        params
      );
      // 隐藏场景加载状态
      this.sceneLoading = false;
      if (res.status == "200") {
        if (res.attribute.length > 0) {
          res.attribute.forEach((item, index) => {
            if (index === 0) {
              let obj = {
                ...stepAdd,
                options: {
                  ...item,
                  stepID: item.id,
                  taskType: item.apiId,
                },
              };
              if (this.triggerMode === 2) {
                obj.actionName = "定时触发";
              } else if (this.triggerMode === 1) {
                obj.actionName = "应用程序触发";
              } else if (this.triggerMode === 4) {
                obj.actionName = "Webhook触发";
              } else if (this.triggerMode === 3) {
                obj.actionName = "手动触发";
              }
              // 将第一个步骤添加到画布列表
              this.drawShowList.push(obj);
            } else {
              // 将其他步骤添加到画布列表
              this.drawShowList.push({
                ...stepUse,
                options: {
                  ...item,
                  stepID: item.id,
                  stepDescribe: item.apiName || item.plugName,
                },
              });
            }
          });
          // 在下一个 DOM 更新周期后执行操作
          this.$nextTick(() => {
            // 选中第一个步骤
            this.drawSelectIndex = 0;
            this.selectDrawItem(this.drawSelectIndex);
          });
        } else {
          // 新增时生成第一步
          let params = {
            flowId: this.sceneID,
            step: 1,
            stepType: 2,
          };
          this.SaveSceneStepData(params, "first");
        }
      }
    },
    /**
     * 新增、实时修改场景步骤基本信息
     * @param {Object} params 请求参数
     * @param {string} type 操作类型
     * @param {string} insertIndex 用于插入
     */
    async SaveSceneStepData(params, type, insertIndex) {
      let res = await authApi(
        "sysFlowStepService",
        "",
        "saveOrUpdateFlowStep",
        "",
        params
      );
      // 隐藏场景加载状态
      this.sceneLoading = false;
      if (res.status == "200") {
        // 第一次打开弹窗
        if (type === "first") {
          let obj = [
            {
              ...stepAdd,
              options: {
                // 步骤 id
                stepID: res.attribute.id,
                step: 1,
                stepType: 2, // 步骤类型（1、触发方式 2、应用 3、 数据集 4、条件
              },
            },
          ];
          if (this.triggerMode === 2) {
            obj[0].actionName = "定时触发";
          } else if (this.triggerMode === 1) {
            obj[0].actionName = "应用程序触发";
          } else if (this.triggerMode === 4) {
            obj[0].actionName = "Webhook触发";
          } else if (this.triggerMode === 3) {
            obj[0].actionName = "手动触发";
          }
          // 更新画布列表
          this.drawShowList = obj;
          // 在下一个 DOM 更新周期后执行操作
          this.$nextTick(() => {
            // 选中第一个步骤
            this.drawSelectIndex = 0;
            this.selectDrawItem(this.drawSelectIndex);
            // 获取应用列表
            this.getAppList();
          });
        }
        // 手动新增时
        if (type === "add") {
          // 将新步骤添加到画布列表
          this.drawShowList.push({
            ...stepUse,
            options: {
              // 步骤 id
              stepID: res.attribute.id,
            },
          });
          // 在下一个 DOM 更新周期后执行操作
          this.$nextTick(() => {
            // 选中当前新增的步骤
            this.drawSelectIndex = this.drawShowList.length - 1;
            this.selectDrawItem(this.drawSelectIndex);
          });
        }
        // 插入时
        if (type == "insert") {
          this.drawShowList.splice(insertIndex + 1, 0, {
            ...stepUse,
            options: {
              // 步骤 id
              stepID: res.attribute.id,
            },
          });
          // 在下一个 DOM 更新周期后执行操作
          this.$nextTick(() => {
            // 选中当前新增的步骤
            this.drawSelectIndex = insertIndex + 1;
            this.selectDrawItem(this.drawSelectIndex);
          });
        }
        if (type === "time") {
          this.activeTabName = "配置";
        }
        // cron表达式保存后
        if (type === "expression") {
          if (this.drawShowList.length === 1) {
            // 自动添加一个步骤
            this.addDrwaItem();
          } else {
            // 在下一个 DOM 更新周期后执行操作
            this.$nextTick(() => {
              // 选中第二个步骤
              this.drawSelectIndex = 1;
              this.selectDrawItem(this.drawSelectIndex);
            });
          }
        }
      }
    },
    /**
     * 手动新增场景步骤
     */
    addDrwaItem() {
      // 新增步骤的参数
      let params = {
        flowId: this.sceneID,
        step: this.drawShowList.length + 1,
        stepType: 2,
      };
      // 保存场景步骤数据
      this.SaveSceneStepData(params, "add");
    },
    /**
     * 切换步骤时
     * @param {number} index 步骤索引
     */
    async selectDrawItem(index) {
      // 更新当前选中的步骤索引
      this.drawSelectIndex = index;
      // 先清空
      this.pluginActiv = "";
      this.apiIDActiv = "";
      this.userActivId = "";
      this.CurrentAppRow = {};
      if (index === 0) {
        this.activeTabName = "选择操作";
      } else {
        this.activeOtherTabName = "选择应用";
        // 清空应用搜索关键字
        this.appCodeOrName = "";
        // 获取应用列表
        await this.getAppList();
        // 获取场景步骤数据
        await this.GetSceneStepData();
      }
    },
    /**
     * 获取场景步骤数据
     */
    async GetSceneStepData() {
      // 获取场景步骤数据的参数
      let params = {
        id: this.drawShowList[this.drawSelectIndex].options.stepID,
      };
      let res = await authApi(
        "sysFlowStepService",
        "",
        "getFlowStep",
        "",
        params
      );
      if (res.status == "200") {
        let obj = {
          ...this.drawShowList[this.drawSelectIndex].options,
          ...res.attribute,
        };
        // 更新当前步骤的选项
        obj.stepDescribe = obj.apiName || obj.plugName;
        this.drawShowList[this.drawSelectIndex].options = obj;
        // 更新当前选择的应用步骤描述
        this.CurrentAppRow.description = obj.stepDescribe;
        if (this.drawSelectIndex == 0) {
          this.expression = obj.taskCorn;
          this.activTimeIndex = obj.apiId;
        } else {
          this.activeApiPliginTabName = obj.actionType || "API接口";

          // 清空 API 或插件搜索关键字
          this.operateCodeOrName = "";
          // 清空 API 列表
          this.apiList = [];
          // 清空插件列表
          this.pluginList = [];
          // 清空用户列表
          this.userList = [];
          if (this.drawShowList[this.drawSelectIndex].options.appId) {
            // 更新当前选中的应用 ID
            this.appActivIndex =
              this.drawShowList[this.drawSelectIndex].options.appId;
            // 更新当前选择的应用名称
            this.CurrentAppRow.appName =
              this.drawShowList[this.drawSelectIndex].options.appName;
            // 获取当前步骤的 api、插件、账号
            await this.GetApiList(this.appActivIndex);
            // this.getPluginList(this.appActivIndex);
            await this.GetAccountListAPI(this.appActivIndex);
          } else {
            // 重置当前选中的应用 ID
            this.appActivIndex = "";
            // 重置当前选择的应用数据
            this.CurrentAppRow = {};
          }
          this.$nextTick(() => {
            if (this.drawShowList[this.drawSelectIndex].options.description) {
              // 更新步骤描述
              this.description =
                this.drawShowList[this.drawSelectIndex].options.description;
            } else {
              // 重置步骤描述
              this.description = "";
            }

            if (this.drawShowList[this.drawSelectIndex].options.apiId) {
              // 更新选择的 API ID
              this.apiIdActiv =
                this.drawShowList[this.drawSelectIndex].options.apiId;
            } else {
              // 重置选择的 API ID
              this.apiIdActiv = "";
            }
            // 插件
            if (this.drawShowList[this.drawSelectIndex].options.plugId) {
              // 更新选择的插件 ID
              this.pluginActiv =
                this.drawShowList[this.drawSelectIndex].options.plugId;
            } else {
              // 重置选择的插件 ID
              this.pluginActiv = "";
            }
            // 账号
            if (this.drawShowList[this.drawSelectIndex].options.step_acc_id) {
              // 更新选择的用户 ID
              this.userActivId =
                this.drawShowList[this.drawSelectIndex].options.step_acc_id;
              // 更新当前选择的应用账号名称
              this.CurrentAppRow.step_acc_name =
                this.drawShowList[this.drawSelectIndex].options.step_acc_name;
            } else {
              // 重置选择的用户 ID
              this.userActivId = "";
              // 重置当前选择的应用账号名称
              this.CurrentAppRow.step_acc_name = "";
            }
          });
        }
      }
    },
    /**
     * 删除场景步骤
     * @param {Object} ele 步骤数据
     * @param {number} index 步骤索引
     */
    delDrawItem(ele, index) {
      // 获取步骤 ID
      let stepID = ele.options.stepID || null;
      if (!stepID) {
        this.$vmNews("删除失败！步骤ID丢失，请联系管理员处理");
        return;
      }
      // 弹出确认删除对话框
      this.$confirm("确认删除吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(async () => {
          if (stepID) {
            let res = await authApi(
              "sysFlowStepService",
              "",
              "saveFlowStep",
              "",
              {
                id: stepID,
              }
            );
            if (res.status == "200") {
              // 提示删除成功
              this.$vmNews("删除成功", "success");
              // 从画布列表中删除该步骤
              this.drawShowList.splice(index, 1);
              if (this.drawSelectIndex === index) {
                // 选中第一个步骤
                this.drawSelectIndex = 0;
                this.selectDrawItem(this.drawSelectIndex);
              } else if (this.drawSelectIndex >= this.drawShowList.length) {
                // 选中最后一个步骤
                this.drawSelectIndex = this.drawShowList.length - 1;
                this.selectDrawItem(this.drawSelectIndex);
              }
            }
          } else {
            // 提示删除成功
            this.$vmNews("删除成功", "success");
            // 从画布列表中删除该步骤
            this.drawShowList.splice(index, 1);
            if (this.drawSelectIndex === index) {
              // 选中第一个步骤
              this.drawSelectIndex = 0;
              this.selectDrawItem(this.drawSelectIndex);
            } else if (this.drawSelectIndex >= this.drawShowList.length) {
              // 选中最后一个步骤
              this.drawSelectIndex = this.drawShowList.length - 1;
              this.selectDrawItem(this.drawSelectIndex);
            }
          }
        })
        .catch(() => {});
    },
    /**
     * 插入场景步骤
     * @param {any} value 标签页值
     */

    insertDrawItem(ele, index) {
      let params = {
        flowId: this.sceneID,
        step: index + 1,
        stepType: 2,
      };
      // 保存场景步骤数据
      this.SaveSceneStepData(params, "insert", index);
    },
    // ----------------------------------------------步骤一相关操作
    /**
     * 处理时间项点击事件
     * @param {Object} item 时间项数据
     * @param {number} index 时间项索引
     */
    handleTimeItem(item, index) {
      // 更新当前选择操作的类型
      this.activTimeIndex = item.id;
      // 更新当前步骤的任务类型
      this.drawShowList[this.drawSelectIndex].options.taskType = item.id;
      let params = {
        flowId: this.sceneID,
        id: this.drawShowList[this.drawSelectIndex].options.stepID,
        apiId: item.id,
        apiName: this.getTimeDivide(item.id),
      };
      // 保存场景步骤数据
      this.SaveSceneStepData(params, "time");
    },
    /**
     * cron 表达式点击确定时时间插件回调
     * @param {string} value cron 表达式的值
     */
    crontabFill(value) {
      // 更新 cron 表达式
      this.expression = value;
      // 更新当前步骤的任务值
      this.drawShowList[this.drawSelectIndex].options.taskValue = value;
      let params = {
        flowId: this.sceneID,
        id: this.drawShowList[this.drawSelectIndex].options.stepID,
        taskCorn: value,
      };
      // 保存场景步骤数据
      this.SaveSceneStepData(params, "expression");
    },
    // ----------------------------------------------其他步骤--相关操作
    /**
     * 处理 其他步骤的tab点击事件
     * @param {any} value 标签页值
     */
    handleOtherTabClick(value) {},
    /**
     * 应用搜索
     */
    searchApp() {
      // 显示搜索遮罩
      this.drawMask = true;
      // 5 秒后隐藏搜索遮罩
      setTimeout(() => {
        this.drawMask = false;
      }, 5000);
      // 获取应用列表
      this.getAppList();
    },
    /**
     * 获取应用列表
     */
    async getAppList() {
      // 获取应用列表的参数
      let params = {
        name: this.appCodeOrName,
      };
      // 调用获取应用列表的 API
      let res = await authApi(
        "sysApplicationService",
        "",
        "queryEntity",
        "",
        params
      );
      // 隐藏搜索遮罩
      this.drawMask = false;
      if (res.status == "200") {
        // 更新应用列表
        this.appList = res.attribute;
      }
    },
    /**
     * 步骤描述变化时保存数据
     */
    changeDescription() {
      // 更新当前步骤的步骤描述
      this.drawShowList[this.drawSelectIndex].options.description =
        this.description;
      let params = {
        flowId: this.sceneID,
        id: this.drawShowList[this.drawSelectIndex].options.stepID,
        description: this.description,
      };
      // 保存场景步骤数据
      this.SaveSceneStepData(params);
    },
    /**
     * 选择应用时触发的方法
     * @param {Object} row 应用数据
     * @param {number} index 应用索引
     */
    async hangleAppItem(row, index) {
      if (!this.appActivIndex) {
        // 保存应用信息
        this.matchAppData(row);
      } else if (this.appActivIndex !== row.appId) {
        this.$confirm(
          "切换应用会清空操作、账号及配置内的所有数据，确定切换吗?",
          "提示",
          {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          }
        )
          .then(async () => {
            // 重置当前选择的应用插件名称
            this.CurrentAppRow.plugName = "";
            // 重置当前选择的应用账号名称
            this.CurrentAppRow.step_acc_name = "";
            this.CurrentAppRow.description = "";
            // 重置当前步骤的资源类型
            this.drawShowList[this.drawSelectIndex].options.actionType = "";
            // 重置当前步骤的 API ID
            this.drawShowList[this.drawSelectIndex].options.apiId = "";
            this.drawShowList[this.drawSelectIndex].options.apiName = "";
            // 重置当前步骤的插件 ID
            this.drawShowList[this.drawSelectIndex].options.plugId = "";
            // 重置当前步骤的插件名称
            this.drawShowList[this.drawSelectIndex].options.plugName = "";
            // 重置当前步骤的账号 ID
            this.drawShowList[this.drawSelectIndex].options.step_acc_id = "";
            // 重置当前步骤的账号名称
            this.drawShowList[this.drawSelectIndex].options.step_acc_name = "";
            this.drawShowList[this.drawSelectIndex].options.stepDescribe = "";
            this.apiIdActiv = "";
            this.apiList = [];
            this.pluginActiv = "";
            this.pluginList = [];
            this.userActivId = "";
            this.userList = [];
            // 保存应用信息
            this.matchAppData(row);
            // 清空步骤配置
            await this.clearFlowStep();
          })
          .catch(() => {});
      }
    },
    async matchAppData(row) {
      // 更新当前选中的应用 ID
      this.appActivIndex = row.id;
      // 更新当前选择的应用 ID
      this.CurrentAppRow.appId = row.id;
      // 更新当前选择的应用名称
      this.CurrentAppRow.appName = row.name;
      // 更新当前步骤的应用 ID
      this.drawShowList[this.drawSelectIndex].options.appId = row.id;
      // 更新当前步骤的应用名称
      this.drawShowList[this.drawSelectIndex].options.appName = row.name;

      // 切换到选择操作标签页
      this.activeOtherTabName = "选择操作";
      // 切换到 API 接口标签页
      this.activeApiPliginTabName = "API接口";
      // 清空 API 或插件搜索关键字
      this.operateCodeOrName = "";
      // 更新当前步骤的资源类型
      this.drawShowList[this.drawSelectIndex].options.actionType = "API接口";
      // 实时保存配置
      let params = {
        flowId: this.sceneID,
        id: this.drawShowList[this.drawSelectIndex].options.stepID,
        appId: row.id,
        appName: row.name,
        actionType: "",
        plugId: "",
        plugName: "",
        apiId: "",
        apiName: "",
        step_acc_name: "",
        step_acc_id: "",
      };
      // 保存场景步骤数据
      await this.SaveSceneStepData(params);
      // 获取 API 列表
      await this.GetApiList(row.id);
      // 获取插件列表
      // await this.getPluginList(row.id);
      // // 获取用户列表
      await this.GetAccountListAPI(row.id);
    },
    async clearFlowStep() {
      let params = {
        id: this.drawShowList[this.drawSelectIndex].options.stepID,
      };
      let res = await authApi(
        "sysFlowStepService",
        "",
        "clearFlowStep",
        "",
        params
      );
    },
    /**
     * API 或者插件的搜索
     */
    searchApiPlugin() {
      // 检查是否选择了应用
      if (!this.drawShowList[this.drawSelectIndex].options.appId) {
        this.$vmNews("请先选择应用");
        return;
      }
      if (this.activeApiPliginTabName === "API接口") {
        // 显示搜索遮罩
        this.drawMask = true;
        // 5 秒后隐藏搜索遮罩
        setTimeout(() => {
          this.drawMask = false;
        }, 5000);
        // 获取 API 列表
        this.GetApiList(this.drawShowList[this.drawSelectIndex].options.appId);
      } else if (this.activeApiPliginTabName === "插件") {
        // 显示搜索遮罩
        this.drawMask = true;
        // 5 秒后隐藏搜索遮罩
        setTimeout(() => {
          this.drawMask = false;
        }, 5000);
        // 获取插件列表
        this.getPluginList(
          this.drawShowList[this.drawSelectIndex].options.appId
        );
      }
    },
    /**
     * 切换 API 插件标签页
     * @param {string} e 标签页值
     */
    ApiPliginTabChangeEvent(e) {
      // 更新当前操作是 API 还是插件
      this.activeApiPliginTabName = e;
    },
    // 选择API
    hangleApiClickEvent(item) {
      this.pluginActiv = "";
      this.drawShowList[this.drawSelectIndex].options.plugId = "";
      this.drawShowList[this.drawSelectIndex].options.plugName = "";
      // 更新选择的 API ID
      this.apiIdActiv = item.id;
      // 更新当前步骤的 API ID
      this.drawShowList[this.drawSelectIndex].options.apiId = item.id;
      this.drawShowList[this.drawSelectIndex].options.apiName = item.apiName;
      // 更新当前选择的应用步骤描述
      this.CurrentAppRow.description = item.apiName;
      this.drawShowList[this.drawSelectIndex].options.stepDescribe =
        item.apiName;
      // 更新当前步骤的资源类型
      this.drawShowList[this.drawSelectIndex].options.actionType =
        this.activeApiPliginTabName;
      // 切换到选择账号标签页
      this.activeOtherTabName = "选择账号";
      let params = {
        flowId: this.sceneID,
        id: this.drawShowList[this.drawSelectIndex].options.stepID,
        actionType: this.activeApiPliginTabName,
        plugId: "",
        plugName: "",
        apiId: item.id,
        apiName: item.apiName,
      };
      // 保存场景步骤数据
      this.SaveSceneStepData(params);
    },
    // 选择插件
    hanglePluginClickEvent(item) {
      // 更新选择的 API ID
      this.apiIdActiv = "";
      // 更新当前步骤的 API ID
      this.drawShowList[this.drawSelectIndex].options.apiId = "";
      this.drawShowList[this.drawSelectIndex].options.apiName = "";
      this.pluginActiv = item.id;
      this.drawShowList[this.drawSelectIndex].options.plugId = item.id;
      this.drawShowList[this.drawSelectIndex].options.plugName = item.plugName;
      // 更新当前选择的应用步骤描述
      this.CurrentAppRow.description = item.plugName;
      this.drawShowList[this.drawSelectIndex].options.stepDescribe =
        item.plugName;
      // 更新当前步骤的资源类型
      this.drawShowList[this.drawSelectIndex].options.actionType =
        this.activeApiPliginTabName;
      // 切换到选择账号标签页
      this.activeOtherTabName = "选择账号";
      let params = {
        flowId: this.sceneID,
        id: this.drawShowList[this.drawSelectIndex].options.stepID,
        actionType: this.activeApiPliginTabName,
        plugId: item.id,
        plugName: item.plugName,
        apiId: "",
        apiName: "",
      };
      // 保存场景步骤数据
      this.SaveSceneStepData(params);
    },
    /**
     * 选择账号 --》 添加账号
     */
    addAccount() {
      if (!this.appActivIndex) {
        this.$vmNews("请选择应用");
        return;
      }
      // 打开添加账号弹窗
      this.$refs.addAccount.openDialog(
        this.appActivIndex,
        this.sceneID,
        this.drawShowList[this.drawSelectIndex].options.stepID
      );
    },
    /**
     * 重新加载用户列表
     */
    addAccountConfirmClick() {
      // 获取用户列表
      this.GetAccountListAPI(this.appActivIndex);
    },
    /**
     * 当前选中的用户
     * @param {Object} item 用户数据
     */
    async handleUserClickEvent(item) {
      // 更新选择的用户 ID
      this.userActivId = item.id;
      // 更新当前选择的应用账号名称
      this.CurrentAppRow.step_acc_name = item.name;
      // 更新当前步骤的用户 ID
      this.drawShowList[this.drawSelectIndex].options.step_acc_id = item.id;
      // 更新当前步骤的用户账号名称
      this.drawShowList[this.drawSelectIndex].options.step_acc_name = item.name;
      this.outsideFormData = {
        tableName: "",
      };
      this.ColumnsFormData = {};
      this.outsideOptions = [];
      this.outsideColumns = [];
      let params = {
        flowId: this.sceneID,
        id: this.drawShowList[this.drawSelectIndex].options.stepID,
        step_acc_name: item.name,
        step_acc_id: item.id,
      };
      // 保存场景步骤数据
      await this.SaveSceneStepData(params);
      // 切换到配置应用
      this.activeOtherTabName = "配置应用";
      // 获取表数据
      await this.queryTables(item.id);
      this.$nextTick(() => {
        this.resetForm("outsideForm");
      });
    },
    /**
     * 重置表单
     * @param {string} formName 表单的ref
     */
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    /**
     * 获取表列表
     * @param {string} stepAccountId 账号ID
     */
    async queryTables(stepAccountId) {
      let params = {
        stepAccountId: stepAccountId,
      };
      let res = await authApi(
        "sysFlowDataBaseExtServiceImpl",
        "",
        "queryTables",
        "",
        params
      );
      this.drawMask = false;
      if (res.status == "200") {
        this.outsideOptions = res.attribute;
      }
    },
    // 切换表时
    outsideSelectChange(val) {
      if (val) {
        this.outsideColumns = [];
        this.queryColumns(val);
      }
    },
    // 获取表字段
    async queryColumns(tableName) {
      let params = {
        stepAccountId: this.userActivId, //账户id
        tableName: tableName,
      };
      let res = await authApi(
        "sysFlowDataBaseExtServiceImpl",
        "",
        "queryColumns",
        "",
        params
      );
      this.drawMask = false;
      if (res.status == "200") {
        this.outsideColumns = res.attribute.cloums || [];
        this.ColumnsRules = res.attribute.rules || {};
        this.$nextTick(() => {
          this.ColumnsFormData = {};
          this.resetForm("ColumnsForm");
        });
      }
    },
    /**
     * 获取插件列表
     * @param {string} appId 应用 ID
     */
    async getPluginList(appId) {
      let params = {
        appId: appId,
        name: this.operateCodeOrName,
      };
      let res = await authApi(
        "sysApplicationApiService",
        "",
        "queryEntity",
        "",
        params
      );
      this.drawMask = false;
      if (res.status == "200") {
        this.pluginList = res.attribute;
      }
    },
    /**
     * 获取 api 列表
     * @param {string} appId 应用 ID
     */
    async GetApiList(appId) {
      let params = {
        appId: appId,
        name: this.operateCodeOrName,
      };
      let res = await authApi(
        "sysApplicationApiService",
        "",
        "queryEntity",
        "",
        params
      );
      this.drawMask = false;
      if (res.status == "200") {
        this.apiList = res.attribute;
      }
    },
    /**
     * 获取用户列表
     * @param {string} appId 应用 ID
     */
    async GetAccountListAPI(appId) {
      let params = {
        appId: appId,
      };
      let res = await authApi(
        "sysApplicationAccountService",
        "",
        "queryAccountList",
        "",
        params
      );
      this.drawMask = false;
      if (res.status == "200") {
        this.userList = res.attribute;
      }
    },
    /**
     * 根据任务类型获取时间划分的标题
     * @param {number} taskType 任务类型
     * @returns {string} 时间划分的标题
     */
    getTimeDivide(taskType) {
      if (taskType === 1) {
        return "秒级";
      } else if (taskType === 2) {
        return "分钟级";
      } else if (taskType === 3) {
        return "小时级";
      } else if (taskType === 4) {
        return "天级";
      }
    },
    /**
     * 编辑场景名称
     */
    editSceneName() {
      // 编辑场景名称的参数
      let row = {
        flowId: this.sceneID,
      };
      // 在下一个 DOM 更新周期后打开编辑场景名称的弹窗
      this.$nextTick(() => {
        this.$refs.editSence.openDialog(row, "edit");
      });
    },
    /**
     * 更新场景名称
     * @param {string} sceneID 场景 ID
     * @param {Object} res 响应数据
     */
    updateTitle(sceneID, res) {
      // 更新场景名称
      this.sceneName = res.sceneName;
      this.title = res.sceneName;
      // 更新触发模式
      this.triggerMode = res.triggerMode;
      if (this.triggerMode === 2) {
        this.drawShowList[this.drawSelectIndex].actionName = "定时触发";
      } else if (this.triggerMode === 1) {
        this.drawShowList[this.drawSelectIndex].actionName = "应用程序触发";
      } else if (this.triggerMode === 4) {
        this.drawShowList[this.drawSelectIndex].actionName = "Webhook触发";
      } else if (this.triggerMode === 3) {
        this.drawShowList[this.drawSelectIndex].actionName = "手动触发";
      }
    },
    // 场景步骤---【确定】
    handleConfirmClick() {
      this.examineHandleClose();
    },
    // 关闭场景步骤弹窗
    examineHandleClose() {
      // 触发关闭事件
      this.$emit("examineHandleClose");
      this.examineOperateDialog = false;
      this.sceneName = "";
      // 清空画布列表
      this.drawShowList = [];
      // 重置当前选中的步骤索引
      this.drawSelectIndex = "";
      // 重置当前选择操作的类型
      this.activTimeIndex = "";
      // 重置 cron 表达式
      this.expression = "";
      // 清空应用搜索关键字
      this.appCodeOrName = "";
      // 重置当前选中的应用 ID
      this.appActivIndex = "";
      // 清空 API 或插件搜索关键字
      this.operateCodeOrName = "";
      // 重置当前操作是 API 还是插件
      this.activeApiPliginTabName = "API接口";
      // 重置选择的 API ID
      this.apiIdActiv = "";
      // 清空 API 列表
      this.apiList = [];
      // 重置选择的插件 ID
      this.pluginActiv = "";
      // 清空插件列表
      this.pluginList = [];
      // 重置选择的用户 ID
      this.userActivId = "";
      // 清空用户列表
      this.userList = [];
      this.representation = false;
    },

    handleKeyDown(e, columnName, rowIndex) {
      const editor = this.$refs["contentEditor" + columnName + rowIndex][0];

      if (e.key === "Backspace") {
        // 检查是否在光标前有token需要删除
        const selection = window.getSelection();
        if (selection.rangeCount > 0) {
          const range = selection.getRangeAt(0);

          // 如果光标在文本开头或者前一个兄弟节点是token
          if (range.startOffset === 0) {
            const prevSibling = range.startContainer.previousSibling;
            if (
              prevSibling &&
              prevSibling.classList &&
              prevSibling.classList.contains("content-token")
            ) {
              e.preventDefault();
              prevSibling.remove();
              this.$message.success("已删除元素");
              return;
            }
          }
        }
      }

      // 清除token选中状态（除了特殊键）
      if (
        ![
          "Backspace",
          "Delete",
          "ArrowLeft",
          "ArrowRight",
          "ArrowUp",
          "ArrowDown",
        ].includes(e.key)
      ) {
        this.clearTokenSelection(columnName, rowIndex);
      }
    },
    // 清除token选中状态
    clearTokenSelection(columnName, rowIndex) {
      const editor = this.$refs["contentEditor" + columnName + rowIndex][0];

      this.lastSelectedTokenIndex = -1;
    },
    // 处理输入事件
    handleInput(e, columnName, rowIndex) {
      // 清除token选中状态
      this.clearTokenSelection(columnName, rowIndex);

      // 强制更新computed属性
      this.$forceUpdate();
    },
    // 处理编辑器点击
    handleEditorClick(e, columnName, rowIndex) {
      const editor = this.$refs["contentEditor" + columnName + rowIndex][0];
      this.currenrActiveNodeRef = "contentEditor" + columnName + rowIndex;

      // 如果点击的不是token，清除选中状态
      if (
        !e.target.classList.contains("content-token") &&
        !e.target.closest(".content-token")
      ) {
        this.clearTokenSelection(columnName, rowIndex);
      }

      // 确保编辑器获得焦点
      if (e.target === editor || editor.contains(e.target)) {
        editor.focus();
      }
    },
    // 处理粘贴事件
    handlePaste(e, columnName, rowIndex) {
      // 清除token选中状态
      this.clearTokenSelection(columnName, rowIndex);
    },
    // 处理编辑器获得焦点
    handleEditorFocus(e, columnName, rowIndex) {
      const editor = this.$refs["contentEditor" + columnName + rowIndex][0];

      // 如果编辑器为空，设置光标到开始位置
      if (this.isEmpty(columnName, rowIndex)) {
        setTimeout(() => {
          const range = document.createRange();
          const selection = window.getSelection();
          range.setStart(editor, 0);
          range.setEnd(editor, 0);
          selection.removeAllRanges();
          selection.addRange(range);
        }, 0);
      }
    },
    // 判断当前编辑器是否为空
    isEmpty(columnName, rowIndex) {
      const editor = this.$refs["contentEditor" + columnName + rowIndex][0];
      if (!editor) return true;
      const content = editor.textContent.trim();
      const hasTokens = editor.querySelectorAll(".content-token").length > 0;
      return content === "" && !hasTokens;
    },
    // 处理编辑器失去焦点
    handleEditorBlur(e, columnName, rowIndex) {
      // 可以在这里处理失去焦点的逻辑
    },
    handleClearNodeToEditor(columnName, rowIndex) {
      const editor = this.$refs["contentEditor" + columnName + rowIndex][0];
      if (!editor) return;
      let nodeRef = "contentEditor" + columnName + rowIndex;
      this.currenrActiveNodeRef = nodeRef;

      editor.innerHTML = ""; // 先清空内容
      this.$forceUpdate();
      this.$nextTick(() => {
        // 创建 range 和 selection
        const range = document.createRange();
        const selection = window.getSelection();

        // 将 range 定位到 editor 的最后一个子节点
        range.selectNodeContents(editor);
        range.collapse(false); // 折叠到末尾
        // 清空现有选区并设置新 range
        selection.removeAllRanges();
        selection.addRange(range);
        // 确保编辑器有焦点
        editor.focus();
      });
    },

    //添加节点
    handleAddNodeToEditor(columnName, rowIndex) {
      let nodeRef = "contentEditor" + columnName + rowIndex;
      this.currenrActiveNodeRef = nodeRef;
      this.representation = true;
      this.representationActiveName = "first";

      // 这段代码的目的是 让光标停留在最后一个span标签后面
      const editor = this.$refs[this.currenrActiveNodeRef][0];
      if (!editor) return;
      // 创建 range 和 selection
      const range = document.createRange();
      const selection = window.getSelection();

      // 将 range 定位到 editor 的最后一个子节点
      range.selectNodeContents(editor);
      range.collapse(false); // 折叠到末尾
      // 清空现有选区并设置新 range
      selection.removeAllRanges();
      selection.addRange(range);
      // 确保编辑器有焦点
      editor.focus();
    },
    handleNodeSelected(path) {
      this.selectedNode = path;
      this.insertToken(path, "node-reference");
    },
    handleTagSelected(label){

    },
    // 插入token到编辑器
    insertToken(text, type) {
      if (!this.currenrActiveNodeRef) return;

      const editor = this.$refs[this.currenrActiveNodeRef][0];
      if (!editor) return;

      // 确保编辑器有焦点
      editor.focus();

      const token = this.createTokenElement(text, type);

      // 获取当前光标位置
      const selection = window.getSelection();
      if (selection.rangeCount > 0) {
        const range = selection.getRangeAt(0);
        range.deleteContents();

        // 插入token
        range.insertNode(token);

        // 在token后添加一个空格
        const space = document.createTextNode(" ");
        range.setStartAfter(token);
        range.insertNode(space);

        // 使用setTimeout确保DOM更新完成后设置光标
        setTimeout(() => {
          if (!this.setCursorAfter(space)) {
            // 如果设置失败，则设置到编辑器末尾
            this.setCursorToEnd();
          }
        }, 10); // 增加延迟时间确保DOM完全更新
      } else {
        // 如果没有选中区域，直接添加到末尾
        editor.appendChild(token);
        const space = document.createTextNode(" ");
        editor.appendChild(space);

        // 使用setTimeout确保DOM更新完成后设置光标
        setTimeout(() => {
          if (!this.setCursorAfter(space)) {
            this.setCursorToEnd();
          }
        }, 10);
      }

      // 强制更新
      this.$forceUpdate();
    },
    // 设置光标到末尾
    setCursorToEnd() {
      if (!this.currenrActiveNodeRef) return;

      const editor = this.$refs[this.currenrActiveNodeRef][0];
      if (!editor) return;

      const range = document.createRange();
      const selection = window.getSelection();
      range.selectNodeContents(editor);
      range.collapse(false);
      selection.removeAllRanges();
      selection.addRange(range);
    },

    // 设置光标到指定节点后面
    setCursorAfter(node) {
      try {
        const selection = window.getSelection();
        const range = document.createRange();
        range.setStartAfter(node);
        range.collapse(true);
        selection.removeAllRanges();
        selection.addRange(range);
        return true;
      } catch (error) {
        return false;
      }
    },
    // 创建token元素
    createTokenElement(text, type) {
      const token = document.createElement("span");
      token.className = `content-token token-function`;
      token.contentEditable = false;
      token.setAttribute("data-token-id", ++this.tokenCounter);
      token.setAttribute("data-token-type", type);
      token.setAttribute("data-token-text", text);

      if (type === "node-reference") {
        token.innerHTML = `<i class="el-icon-connection"></i> ${text}`;
      }
      return token;
    },
    // 设置光标到末尾
    setCursorToEnd() {
      // 清除之前的选中状态
      if (!this.currenrActiveNodeRef) return;
      const editor = this.$refs[this.currenrActiveNodeRef][0];
      if (!editor) return;

      const range = document.createRange();
      const selection = window.getSelection();
      range.selectNodeContents(editor);
      range.collapse(false);
      selection.removeAllRanges();
      selection.addRange(range);
    },
    closeRepContainer() {
      this.representationActiveName = "first";
      this.representation = false;
      this.selectedNode = "";
      this.currenrActiveNodeRef = "";
    },
  },
};
</script>

<style scoped lang="scss">
::v-deep .el-radio-group {
  background: #fff;
  padding: 2px;
  margin: 0 10px 0 10px;
  border-radius: 4px;
}
::v-deep .el-radio-button__inner {
  border: 0 !important;
  background-color: #fff;
  color: #999999;
  font-weight: 400;
  font-size: 14px;
  padding: 7px 15px;
}

::v-deep .el-radio-button__orig-radio:checked + .el-radio-button__inner {
  background-color: #f5f5f5;
  color: #333333;
  box-shadow: none;
  border-radius: 4px;
}
.drawContent {
  width: 100%;
  height: calc(100vh - 100px);
  display: flex;

  .drawCanvas {
    width: 40%;
    height: 100%;
    background: url("../images/background.png") no-repeat;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -ms-flex-direction: column;
    flex-direction: column;
    -ms-flex-pack: center;
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    overflow-y: auto;
    padding: 50px 0;

    .drawItem {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;

      .title {
        font-weight: 400;
        font-size: 14px;
        color: #333333;
        margin-bottom: 5px;
      }

      .drawBox {
        width: 300px;
        height: 58px;
        background: #ffffff;
        border-radius: 4px;
        border: 1px solid #dbdde1;
        font-weight: 400;
        font-size: 14px;
        color: #333333;
        display: flex;
        // justify-content: center;
        align-items: center;
        position: relative;

        .img {
          margin: 0 10px;
          width: 30px;
          height: 30px;
          border-radius: 50%;
          display: flex;
          align-items: center;
          justify-content: center;
          border: 1px solid #f18709;

          img {
            width: 60%;
            height: 60%;
          }
        }
        .iconStyle {
          margin: 0 10px;
          width: 30px;
          height: 30px;
          border-radius: 50%;
          display: flex;
          align-items: center;
          justify-content: center;

          img {
            width: 100%;
            height: 100%;
            border-radius: 50%;
          }
        }

        .actionName {
          font-weight: 400;
          font-size: 14px;
          color: #333333;
        }

        .content {
          font-weight: 500;
          font-size: 14px;
          color: #333333;
          margin-top: 5px;
        }
      }
      .drawBox:hover {
        background: #f2fcff;
        border: 1px solid #1478f5;
      }

      .del {
        position: absolute;
        right: -5px;
        top: -3px;
        cursor: pointer;
        width: 16px;
        height: 16px;
        background: #fff;

        img {
          width: 100%;
          height: 100%;
        }
      }

      .active {
        background: #f2fcff;
        border: 1px solid #1478f5;
      }

      .line-wrapper {
        width: 100%;
        display: flex;
        justify-content: center;
        position: relative;

        img {
          position: absolute;
          cursor: pointer;
          width: 20px;
          height: 20px;
          top: 33px;
          left: 140px;
          display: none;
        }
      }
      .line-wrapper:hover img {
        display: block;
      }
      .line {
        width: 1px;
        height: 60px;
        border: 1px solid #dbdde1;
        margin: 10px 0;
      }
    }
  }

  .drawAction {
    width: 60%;
    height: 100%;
    background-color: #f5f5f5;
    position: relative;

    .nextButton {
      position: absolute;
      right: 15px;
      top: 8px;
      color: #1477f3;
      cursor: pointer;
      font-size: 14px;
    }
    ::v-deep .el-tabs__header {
      margin: 0;
      background: #ffffff;

      .el-tabs__nav {
        margin-left: 10px;
      }
    }
  }
}
// cron表达式样式
.crontabBox {
  padding: 15px;

  .crontabBoxTitle {
    margin-bottom: 15px;
    color: #333333;
  }
  ::v-deep .el-tabs--border-card {
    border-radius: 8px;
    box-shadow: unset;
    border: 1px solid #dadce0;
  }
  ::v-deep .popup-main {
    border-radius: 8px;
    border: 1px solid #dadce0;
    font-size: 14px;
  }
  ::v-deep .popup-result {
    border: unset;
    margin: 0 auto;
    padding: 15px 10px 5px 15px;

    .title {
      width: unset;
      margin-left: unset;
      background: transparent;
      color: #333;
    }
  }
  ::v-deep .el-tabs__header {
    border-radius: 8px 8px 0 0;
    margin: 0;
    background: #f5f7fa !important;
    .el-tabs__nav {
      margin-left: 0 !important;
    }
  }

  ::v-deep .el-tabs__header .el-tabs__item:first-child {
    border-radius: 8px 0 0 0;
    margin-left: -2px;
    margin-top: 0px;
  }
  ::v-deep .pop_btn {
    text-align: center;
    margin-top: 10px;
    margin-bottom: 10px;
    .el-button:last-child {
      display: none;
    }
  }
}
.drawItemBox {
  display: flex;
  background: #ffffff;
  padding: 10px;

  .title {
    font-weight: 400;
    font-size: 14px;
    color: #333333;
  }

  .drawBox {
    background: #ffffff;
    font-weight: 400;
    font-size: 14px;
    color: #333333;
    display: flex;
    position: relative;
    align-items: center;

    .img {
      margin-right: 20px;
    }

    .actionName {
      font-weight: 400;
      font-size: 14px;
      color: #333333;
      margin-bottom: 5px;
    }

    .content {
      font-weight: 500;
      font-size: 14px;
      color: #333333;
      margin-top: 5px;
    }
  }

  .del {
    position: absolute;
    right: 5px;
    top: 2px;
    cursor: pointer;
  }

  .active {
    background: #f2fcff;
    border: 1px solid #1478f5;
  }

  .line {
    width: 1px;
    height: 60px;
    border: 1px solid #dbdde1;
    margin: 10px 0;
  }
}

// 选择操作
.timeWrap {
  padding: 15px;
  box-sizing: border-box;

  .timeItem {
    width: 100%;
    height: 58px;
    background: #ffffff;
    border-radius: 4px;
    border: 1px solid #dbdde1;
    padding: 10px 14px;
    box-sizing: border-box;
    margin-bottom: 10px;
    display: flex;

    .imgBox {
      width: 15px;
      height: 20px;
      margin-right: 3px;

      img {
        width: 100%;
        height: 100%;
      }
    }
    .title {
      font-weight: 500;
      font-size: 14px;
      color: #333333;
    }

    .content {
      font-weight: 400;
      font-size: 14px;
      color: #333333;
    }
  }

  .timeItem:hover {
    background: #f2fcff;
    border: 1px solid #1478f5;
  }

  .activTimeItem {
    background: #f2fcff;
    border-radius: 4px;
    border: 1px solid #1478f6;
  }
}

.app {
  .applist {
    display: flex;
    padding: 10px;
    flex-wrap: wrap;

    .appItem {
      width: 202px;
      height: 58px;
      background: #ffffff;
      border-radius: 4px;
      padding: 0 10px;
      display: flex;
      flex-direction: row;
      align-items: center;
      margin-right: 10px;
      border: 1px solid #fff;
      margin-bottom: 10px;
      cursor: pointer;

      .imgBox {
        width: 15px;
        height: 22px;
        margin-right: 3px;

        img {
          width: 100%;
          height: 100%;
        }
      }

      .appIcon {
        width: 44px;
        height: 44px;
        margin-right: 10px;
        border-radius: 50%;
      }

      .name {
        font-weight: 400;
        font-size: 14px;
        color: #333333;
        flex: 1;
      }
    }
    .appItem:hover {
      background: #f2fcff;
      border: 1px solid #1478f5;
    }
    .active {
      background: #f2fcff;
      border: 1px solid #1478f5;
    }
  }
}

.DescribeDataBox {
  display: flex;
  flex-direction: column;
  padding: 10px 15px 10px 10px;
  font-size: 15px;
  color: #333;

  span {
    margin-bottom: 10px;
  }
}
.search {
  display: flex;
  margin: 10px;

  .input {
    margin-right: 10px;
  }
}

.ApiPliginBox {
  height: calc(100vh - 270px);
  overflow: auto;
  padding-right: 5px;
  .appItem {
    height: unset !important;
    display: flex;
    flex-direction: column;
    width: 100% !important;
    padding: 10px !important;
    align-items: flex-start !important;
    margin-right: 0 !important;
    color: #333333 !important;
    font-size: 14px !important;

    .name:first-child {
      font-weight: 500;
      color: #333333;
    }
  }
}

.userList {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 10px 15px 10px 10px;
  font-size: 14px;

  .userItem {
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    background: #ffffff;
    border-radius: 4px;
    border: 1px solid #dbdde1;
    margin-bottom: 10px;
    padding: 15px;
    cursor: pointer;
  }
  .status {
    margin-right: 10px;
    font-size: 18px !important;
  }
  .userAccountIcon {
    width: 15px;
    height: 15px;
    margin-right: 10px;
    img {
      width: 100%;
      height: 100%;
    }
  }

  .userItem:hover {
    background: #f2fcff;
    border: 1px solid #1478f5;
  }
  .userBtn {
    padding: 15px 10px;
    border: 1px dashed #dbdde1;
  }
  .userBtn:hover {
    background: #f2fcff;
    border: 1px dashed #1478f6;
  }
}

.userContentBox {
  width: 100%;
  height: calc(100vh - 200px);
  overflow: auto;

  .active {
    background: #f2fcff;
    border: 1px solid #1478f5;
  }
}
.redBox {
  background: #fff1eb;
  border-radius: 4px;
  border: 1px solid #ffb999;
  color: #ff5100;
  font-size: 12px;
  text-align: center;
  padding: 2px 8px;
  margin-left: 5px;
}

.successBox {
  background: #f6ffed;
  border-radius: 4px;
  border: 1px solid #b7eb8f;
  color: #52c41a;
  font-size: 12px;
  text-align: center;
  padding: 2px 8px;
  margin-left: 5px;
}

.settingBox {
  padding: 10px;

  .title {
    margin-bottom: 10px;
    color: #333333;
    font-weight: 500;
    font-size: 14px;
  }
}
.settingbtn {
  width: 20px;
  height: 20px;
  font-size: 16px;
  color: #1478f6;
  text-align: center;
  line-height: 20px;
  cursor: pointer;
  margin: 0 auto;
  position: absolute;
  top: 90px;
  left: 19px;
  z-index: 999;
  padding: 6px;
}

.settingTabs {
  width: 100%;
  padding: 10px 15px 10px 10px;
  .tabs {
    display: flex;
    align-items: center;
    height: 32px;
    background: #fff;
    border-radius: 4px;
    padding: 2px;
    width: fit-content;

    .tabsItem {
      height: 28px;
      line-height: 28px;
      background: #fff;
      border-radius: 3px;
      font-size: 14px;
      color: #999;
      padding: 0 10px;
      cursor: pointer;
    }

    .active {
      background: #f5f5f5;
      color: #333;
    }
  }

  ::v-deep .el-switch {
    height: 23px !important;
    line-height: 23px !important;
  }
}

.currentDrawBox {
  background: #ffffff;
  display: flex;
  align-items: center;
  font-size: 14px;
  color: #333;
  .img {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    margin-right: 10px;

    img {
      width: 100%;
      height: 100%;
      border-radius: 50%;
    }
  }

  .actionName {
    font-weight: 400;
    color: #333333;
    margin-bottom: 5px;
  }
  .content {
    font-weight: 500;
    color: #333333;
    margin-bottom: 5px;
  }

  .drawimg {
    margin-right: 10px;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid #f18709;

    img {
      width: 60%;
      height: 60%;
    }
  }
}

.drawItemBtn {
  background: #ffffff;
  padding: 10px 50px;
  font-size: 14px;
  color: #1478f6;
  border: 1px dashed #dbdde1;
  border-radius: 4px;
  cursor: pointer;
  margin-top: 50px;
}
.drawItemBtn:hover {
  background: #f2fcff;
  border: 1px dashed #1478f6;
}

.DescribeContent {
  display: -webkit-box;
  /*作为弹性伸缩盒子模型显示。*/
  -webkit-box-orient: vertical;
  /*作为弹性伸缩盒子模型显示。*/
  -webkit-line-clamp: 1; //*显示的行*/
  overflow: hidden;
  /*溢出隐藏*/
  /* 对于连字情况或者纯字母，可以解决 */
  word-break: break-all;
  // max-width: 100px;
}

.InterfaceConfiguration {
  background: #fff;
  margin: 10px;
  padding: 10px;
  border-radius: 4px;

  .InterCigTitle {
    font-size: 14px;
    margin-bottom: 10px;
  }
}

::v-deep .operatingClass {
  display: flex;
  align-items: center;
  .el-radio-group {
    background: unset !important;
  }
}

::v-deep .CodeMirror {
  height: 100% !important;
}

.toolbar {
  background: #fff;
  padding: 8px;
  font-size: 14px;
  border-radius: 4px 4px 0 0;
  display: flex;
  justify-content: space-between;
  align-items: center;

  select {
    width: 100px;
    margin-left: 10px;
    padding: 2px;
  }
}
.fullScreen {
  display: flex;
  align-items: center;
  font-size: 14px;
  margin-left: 10px;
  cursor: pointer;

  > img {
    width: 15px;
    height: 15px;
    margin-right: 5px;
  }
}

.acionImg {
  width: 15px;
  height: 15px;
  margin-left: 5px;
}

::v-deep .el-form-item {
  margin-bottom: 0 !important;
}
::v-deep .el-form-item__label {
  padding-bottom: 0 !important;
  font-weight: bold;
}

.outsideContent {
  height: calc(100vh - 220px);
  overflow: auto;
  padding: 0 10px 10px 10px;
}
::v-deep .el-collapse-item__header.is-active {
  padding-left: 10px !important;
}
// ------------------------
.editor-container {
  flex: 1;
  overflow: hidden;
  position: relative;
}
.editorIcon {
  position: absolute;
  right: 10px;
  top: 0;
  font-size: 20px;
  color: #999999;
}

.clearIcon {
  display: none;
  position: absolute;
  top: 0;
  right: 35px;
  font-size: 20px;
  color: #999999;
}
.editor-container:hover .clearIcon {
  display: block;
}
/* hover 时显示 close-icon */
.editor-container:hover .close-icon {
  display: inline-flex; /* 或 block，根据你的布局 */
}
.content-editor {
  border: 1px solid #e5e7eb;
  border-radius: 4px;
  min-height: 36px;
  padding: 0 50px 0 15px;
  background: #fff;
  position: relative;
  font-size: 14px;
  // line-height: 1.6;
  overflow-y: auto;
  outline: none;
  word-wrap: break-word;
}

.content-editor:focus {
  border-color: #409eff;
}

.content-editor:empty:before {
  content: attr(data-placeholder);
  color: #9ca3af;
  font-style: italic;
  pointer-events: none;
}

.content-editor:focus:empty:before {
  content: "";
}

/* 确保空编辑器也能显示光标 */
.content-editor:empty {
  min-height: 20px;
}

.content-editor:focus {
  outline: none;
}

// --------------------------------
::v-deep .content-token {
  display: inline-table;
  padding: 0 10px;
  border-radius: 4px;
  margin: 2px;
  cursor: pointer;
  transition: all 0.2s ease;
  vertical-align: middle;
  font-size: 13px;
  font-weight: 500;
  user-select: none;
}
::v-deep .token-function {
  background: #e0e7ff;
  color: #5b21b6;
  border: 1px solid #8b5cf6;
}

::v-deep .repContainer {
  width: 100%;
  height: 100%;
  background: #f5f5f5;
  padding: 10px;
  position: relative;
}
.treeNodeBox {
  height: calc(100% - 50px);
  overflow-y: auto;
}

.closeRepContainer {
  position: absolute;
  top: 20px;
  right: 12px;
  font-size: 14px;
  cursor: pointer;
  display: flex;
  align-items: center;

  i {
    margin-right: 5px;
  }
}
.closeRepContainer:hover {
  color: #409eff;
}

.repItem {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  cursor: pointer;
}

.repItem:hover .repItemValue{
  color: #409eff;
}

.repItemValue {
  color: #6b7280;
  font-size: 13px;
  margin-left: 10px;
}
</style>
































