2960 lines
83 KiB
Vue
2960 lines
83 KiB
Vue
<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>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|