2025-05-30 10:04:55 +08:00
|
|
|
|
<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>
|
2025-05-30 19:59:25 +08:00
|
|
|
|
<div
|
|
|
|
|
class="rightDialogClass_main drawContent"
|
|
|
|
|
v-if="drawShowList.length > 0"
|
|
|
|
|
style="background: #fff"
|
|
|
|
|
>
|
2025-06-20 18:58:03 +08:00
|
|
|
|
<!-- 步骤画布 -->
|
|
|
|
|
<div class="drawCanvas" v-show="!representation">
|
2025-05-30 10:04:55 +08:00
|
|
|
|
<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"
|
2025-06-20 18:58:03 +08:00
|
|
|
|
v-if="ele.options.stepDescribe"
|
2025-05-30 10:04:55 +08:00
|
|
|
|
>
|
2025-06-20 18:58:03 +08:00
|
|
|
|
{{ ele.options.stepDescribe }}
|
2025-05-30 10:04:55 +08:00
|
|
|
|
</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>
|
2025-06-20 18:58:03 +08:00
|
|
|
|
<!-- 动态内容及其表达式 -->
|
|
|
|
|
<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>
|
2025-05-30 10:04:55 +08:00
|
|
|
|
<!-- 操作区 -->
|
2025-05-30 19:59:25 +08:00
|
|
|
|
<!-- 第一步的时候单独处理 -->
|
2025-05-30 10:04:55 +08:00
|
|
|
|
<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>
|
2025-06-20 18:58:03 +08:00
|
|
|
|
<el-tab-pane
|
|
|
|
|
label="2. 配置"
|
|
|
|
|
name="配置"
|
|
|
|
|
:disabled="!this.activTimeIndex"
|
|
|
|
|
>
|
2025-05-30 10:04:55 +08:00
|
|
|
|
<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>
|
2025-05-30 19:59:25 +08:00
|
|
|
|
<!-- 其他步骤 -->
|
|
|
|
|
<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>
|
2025-06-20 18:58:03 +08:00
|
|
|
|
<el-tab-pane
|
|
|
|
|
label="2. 选择操作"
|
|
|
|
|
name="选择操作"
|
|
|
|
|
:disabled="!this.appActivIndex"
|
|
|
|
|
>
|
2025-05-30 19:59:25 +08:00
|
|
|
|
<!-- 选中的操作步骤 -->
|
|
|
|
|
<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)"
|
2025-06-20 18:58:03 +08:00
|
|
|
|
:class="{ active: apiIdActiv == item.id }"
|
2025-05-30 19:59:25 +08:00
|
|
|
|
>
|
|
|
|
|
<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)"
|
2025-06-20 18:58:03 +08:00
|
|
|
|
:class="{ active: pluginActiv == item.id }"
|
2025-05-30 19:59:25 +08:00
|
|
|
|
>
|
|
|
|
|
<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>
|
2025-06-20 18:58:03 +08:00
|
|
|
|
<el-tab-pane
|
|
|
|
|
label="3. 选择账号"
|
|
|
|
|
name="选择账号"
|
|
|
|
|
:disabled="
|
|
|
|
|
!this.appActivIndex || !(this.apiIdActiv || this.pluginActiv)
|
|
|
|
|
"
|
|
|
|
|
>
|
2025-05-30 19:59:25 +08:00
|
|
|
|
<!-- 选中的操作步骤 -->
|
|
|
|
|
<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"
|
2025-06-20 18:58:03 +08:00
|
|
|
|
style="justify-content: flex-start"
|
2025-05-30 19:59:25 +08:00
|
|
|
|
@click="handleUserClickEvent(item, index)"
|
|
|
|
|
:class="{ active: userActivId == item.id }"
|
|
|
|
|
>
|
2025-06-20 18:58:03 +08:00
|
|
|
|
<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>
|
2025-05-30 19:59:25 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</el-tab-pane>
|
2025-06-20 18:58:03 +08:00
|
|
|
|
<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>
|
2025-05-30 19:59:25 +08:00
|
|
|
|
</el-tabs>
|
|
|
|
|
</div>
|
2025-05-30 10:04:55 +08:00
|
|
|
|
</div>
|
|
|
|
|
</base-right-dialog>
|
|
|
|
|
<editSence ref="editSence" @handleConfirmClick="updateTitle"></editSence>
|
2025-05-30 19:59:25 +08:00
|
|
|
|
<addAccount
|
|
|
|
|
ref="addAccount"
|
|
|
|
|
@handleConfirmClick="addAccountConfirmClick"
|
|
|
|
|
></addAccount>
|
2025-05-30 10:04:55 +08:00
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
// 导入编辑场景组件
|
|
|
|
|
import baseRightDialog from "@/components/base/baseRightDialog/index.vue";
|
|
|
|
|
import editSence from "./editSence.vue";
|
|
|
|
|
import { authApi } from "@/api/apis/auth";
|
|
|
|
|
// 导入步骤添加和使用的常量
|
2025-06-20 18:58:03 +08:00
|
|
|
|
import { stepAdd, stepUse, timeDivide, representationData } from "./constant";
|
2025-05-30 10:04:55 +08:00
|
|
|
|
// 导入 cron 表达式组件
|
|
|
|
|
import FishCrontab from "fish-crontab";
|
2025-05-30 19:59:25 +08:00
|
|
|
|
// 导入添加账号组件
|
|
|
|
|
import addAccount from "./addAccount.vue";
|
2025-06-20 18:58:03 +08:00
|
|
|
|
import baseForm from "@/components/base/baseNewForm";
|
|
|
|
|
import treeNode from "./TreeNode";
|
|
|
|
|
import IconsDialog from "../../tool/build/IconsDialog.vue";
|
2025-05-30 10:04:55 +08:00
|
|
|
|
export default {
|
|
|
|
|
components: {
|
|
|
|
|
editSence,
|
|
|
|
|
baseRightDialog,
|
|
|
|
|
FishCrontab,
|
2025-05-30 19:59:25 +08:00
|
|
|
|
addAccount,
|
2025-06-20 18:58:03 +08:00
|
|
|
|
baseForm,
|
|
|
|
|
treeNode,
|
|
|
|
|
IconsDialog,
|
2025-05-30 10:04:55 +08:00
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
examineOperateDialog: false, //判断是都打开弹窗
|
|
|
|
|
sceneLoading: false, //遮照
|
|
|
|
|
sceneName: "", //场景名称
|
|
|
|
|
sceneID: "", //场景ID
|
|
|
|
|
// 画布列表,对应右侧操作区域
|
|
|
|
|
drawShowList: [],
|
|
|
|
|
drawSelectIndex: 0, // 当前选中的画布索引
|
|
|
|
|
|
2025-05-30 19:59:25 +08:00
|
|
|
|
//当步骤为1时
|
|
|
|
|
timeDivide: timeDivide,
|
|
|
|
|
activeTabName: "选择操作", // 显示的操作栏
|
|
|
|
|
activTimeIndex: "", // 当前选择操作的类型
|
|
|
|
|
expression: "", //cron表达式
|
|
|
|
|
// 其他步骤
|
|
|
|
|
activeOtherTabName: "",
|
|
|
|
|
CurrentAppRow: {}, // 当前选择的应用数据
|
|
|
|
|
appCodeOrName: "", //应用搜索条件
|
|
|
|
|
drawMask: false,
|
|
|
|
|
|
2025-05-30 10:04:55 +08:00
|
|
|
|
// 应用列表
|
|
|
|
|
appList: [],
|
|
|
|
|
appCodeOrName: "", // 应用搜索关键字
|
|
|
|
|
appActivIndex: "", // 当前选中的应用 ID
|
2025-05-30 19:59:25 +08:00
|
|
|
|
description: "", //应用描述
|
|
|
|
|
operateCodeOrName: "", //api 或者 插件的搜索
|
|
|
|
|
activeApiPliginTabName: "API接口", // 当前操作是 API 还是插件
|
|
|
|
|
// API 插件列表
|
|
|
|
|
pluginList: [],
|
|
|
|
|
// API 接口列表
|
|
|
|
|
apiList: [],
|
|
|
|
|
apiIdActiv: "", // 选择的 API ID
|
|
|
|
|
pluginActiv: "", // 选择的插件 ID
|
|
|
|
|
// 用户列表
|
|
|
|
|
userList: [],
|
|
|
|
|
userActivId: "", // 选择的用户 ID
|
2025-06-20 18:58:03 +08:00
|
|
|
|
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,
|
2025-05-30 10:04:55 +08:00
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
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");
|
|
|
|
|
}
|
2025-05-30 19:59:25 +08:00
|
|
|
|
|
|
|
|
|
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,
|
2025-06-20 18:58:03 +08:00
|
|
|
|
taskType: item.apiId,
|
2025-05-30 19:59:25 +08:00
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
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,
|
2025-06-20 18:58:03 +08:00
|
|
|
|
stepDescribe: item.apiName || item.plugName,
|
2025-05-30 19:59:25 +08:00
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// 在下一个 DOM 更新周期后执行操作
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
// 选中第一个步骤
|
|
|
|
|
this.drawSelectIndex = 0;
|
|
|
|
|
this.selectDrawItem(this.drawSelectIndex);
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
// 新增时生成第一步
|
|
|
|
|
let params = {
|
|
|
|
|
flowId: this.sceneID,
|
|
|
|
|
step: 1,
|
|
|
|
|
stepType: 2,
|
|
|
|
|
};
|
|
|
|
|
this.SaveSceneStepData(params, "first");
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-30 10:04:55 +08:00
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 新增、实时修改场景步骤基本信息
|
|
|
|
|
* @param {Object} params 请求参数
|
|
|
|
|
* @param {string} type 操作类型
|
2025-05-30 19:59:25 +08:00
|
|
|
|
* @param {string} insertIndex 用于插入
|
2025-05-30 10:04:55 +08:00
|
|
|
|
*/
|
|
|
|
|
async SaveSceneStepData(params, type, insertIndex) {
|
|
|
|
|
let res = await authApi(
|
|
|
|
|
"sysFlowStepService",
|
|
|
|
|
"",
|
2025-05-30 19:59:25 +08:00
|
|
|
|
"saveOrUpdateFlowStep",
|
2025-05-30 10:04:55 +08:00
|
|
|
|
"",
|
|
|
|
|
params
|
|
|
|
|
);
|
|
|
|
|
// 隐藏场景加载状态
|
|
|
|
|
this.sceneLoading = false;
|
|
|
|
|
if (res.status == "200") {
|
2025-05-30 19:59:25 +08:00
|
|
|
|
// 第一次打开弹窗
|
2025-05-30 10:04:55 +08:00
|
|
|
|
if (type === "first") {
|
|
|
|
|
let obj = [
|
|
|
|
|
{
|
|
|
|
|
...stepAdd,
|
|
|
|
|
options: {
|
|
|
|
|
// 步骤 id
|
|
|
|
|
stepID: res.attribute.id,
|
|
|
|
|
step: 1,
|
|
|
|
|
stepType: 2, // 步骤类型(1、触发方式 2、应用 3、 数据集 4、条件
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
if (this.triggerMode === 2) {
|
2025-05-30 19:59:25 +08:00
|
|
|
|
obj[0].actionName = "定时触发";
|
2025-05-30 10:04:55 +08:00
|
|
|
|
} else if (this.triggerMode === 1) {
|
2025-05-30 19:59:25 +08:00
|
|
|
|
obj[0].actionName = "应用程序触发";
|
2025-05-30 10:04:55 +08:00
|
|
|
|
} else if (this.triggerMode === 4) {
|
2025-05-30 19:59:25 +08:00
|
|
|
|
obj[0].actionName = "Webhook触发";
|
2025-05-30 10:04:55 +08:00
|
|
|
|
} 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);
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-05-30 19:59:25 +08:00
|
|
|
|
// 插入时
|
2025-05-30 10:04:55 +08:00
|
|
|
|
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);
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-05-30 19:59:25 +08:00
|
|
|
|
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);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-30 10:04:55 +08:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 手动新增场景步骤
|
|
|
|
|
*/
|
2025-05-30 19:59:25 +08:00
|
|
|
|
addDrwaItem() {
|
2025-05-30 10:04:55 +08:00
|
|
|
|
// 新增步骤的参数
|
|
|
|
|
let params = {
|
|
|
|
|
flowId: this.sceneID,
|
|
|
|
|
step: this.drawShowList.length + 1,
|
|
|
|
|
stepType: 2,
|
|
|
|
|
};
|
|
|
|
|
// 保存场景步骤数据
|
|
|
|
|
this.SaveSceneStepData(params, "add");
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 切换步骤时
|
|
|
|
|
* @param {number} index 步骤索引
|
|
|
|
|
*/
|
2025-06-20 18:58:03 +08:00
|
|
|
|
async selectDrawItem(index) {
|
2025-05-30 10:04:55 +08:00
|
|
|
|
// 更新当前选中的步骤索引
|
|
|
|
|
this.drawSelectIndex = index;
|
2025-05-30 19:59:25 +08:00
|
|
|
|
// 先清空
|
|
|
|
|
this.pluginActiv = "";
|
|
|
|
|
this.apiIDActiv = "";
|
|
|
|
|
this.userActivId = "";
|
2025-06-20 18:58:03 +08:00
|
|
|
|
this.CurrentAppRow = {};
|
2025-05-30 19:59:25 +08:00
|
|
|
|
if (index === 0) {
|
|
|
|
|
this.activeTabName = "选择操作";
|
|
|
|
|
} else {
|
|
|
|
|
this.activeOtherTabName = "选择应用";
|
|
|
|
|
// 清空应用搜索关键字
|
|
|
|
|
this.appCodeOrName = "";
|
|
|
|
|
// 获取应用列表
|
2025-06-20 18:58:03 +08:00
|
|
|
|
await this.getAppList();
|
2025-05-30 19:59:25 +08:00
|
|
|
|
// 获取场景步骤数据
|
2025-06-20 18:58:03 +08:00
|
|
|
|
await this.GetSceneStepData();
|
2025-05-30 19:59:25 +08:00
|
|
|
|
}
|
2025-05-30 10:04:55 +08:00
|
|
|
|
},
|
2025-05-30 19:59:25 +08:00
|
|
|
|
/**
|
|
|
|
|
* 获取场景步骤数据
|
|
|
|
|
*/
|
|
|
|
|
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,
|
|
|
|
|
};
|
|
|
|
|
// 更新当前步骤的选项
|
2025-06-20 18:58:03 +08:00
|
|
|
|
obj.stepDescribe = obj.apiName || obj.plugName;
|
2025-05-30 19:59:25 +08:00
|
|
|
|
this.drawShowList[this.drawSelectIndex].options = obj;
|
2025-06-20 18:58:03 +08:00
|
|
|
|
// 更新当前选择的应用步骤描述
|
|
|
|
|
this.CurrentAppRow.description = obj.stepDescribe;
|
2025-05-30 19:59:25 +08:00
|
|
|
|
if (this.drawSelectIndex == 0) {
|
|
|
|
|
this.expression = obj.taskCorn;
|
|
|
|
|
this.activTimeIndex = obj.apiId;
|
|
|
|
|
} else {
|
2025-06-20 18:58:03 +08:00
|
|
|
|
this.activeApiPliginTabName = obj.actionType || "API接口";
|
2025-05-30 10:04:55 +08:00
|
|
|
|
|
2025-05-30 19:59:25 +08:00
|
|
|
|
// 清空 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、插件、账号
|
2025-06-20 18:58:03 +08:00
|
|
|
|
await this.GetApiList(this.appActivIndex);
|
2025-05-30 19:59:25 +08:00
|
|
|
|
// this.getPluginList(this.appActivIndex);
|
2025-06-20 18:58:03 +08:00
|
|
|
|
await this.GetAccountListAPI(this.appActivIndex);
|
2025-05-30 19:59:25 +08:00
|
|
|
|
} else {
|
|
|
|
|
// 重置当前选中的应用 ID
|
|
|
|
|
this.appActivIndex = "";
|
|
|
|
|
// 重置当前选择的应用数据
|
|
|
|
|
this.CurrentAppRow = {};
|
|
|
|
|
}
|
2025-06-20 18:58:03 +08:00
|
|
|
|
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 = "";
|
|
|
|
|
}
|
|
|
|
|
});
|
2025-05-30 19:59:25 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
2025-05-30 10:04:55 +08:00
|
|
|
|
/**
|
|
|
|
|
* 删除场景步骤
|
|
|
|
|
* @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);
|
|
|
|
|
},
|
2025-05-30 19:59:25 +08:00
|
|
|
|
// ----------------------------------------------步骤一相关操作
|
|
|
|
|
/**
|
|
|
|
|
* 处理时间项点击事件
|
|
|
|
|
* @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");
|
|
|
|
|
},
|
2025-05-30 10:04:55 +08:00
|
|
|
|
/**
|
|
|
|
|
* cron 表达式点击确定时时间插件回调
|
|
|
|
|
* @param {string} value cron 表达式的值
|
|
|
|
|
*/
|
|
|
|
|
crontabFill(value) {
|
|
|
|
|
// 更新 cron 表达式
|
|
|
|
|
this.expression = value;
|
|
|
|
|
// 更新当前步骤的任务值
|
|
|
|
|
this.drawShowList[this.drawSelectIndex].options.taskValue = value;
|
2025-05-30 19:59:25 +08:00
|
|
|
|
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();
|
2025-05-30 10:04:55 +08:00
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 获取应用列表
|
|
|
|
|
*/
|
|
|
|
|
async getAppList() {
|
|
|
|
|
// 获取应用列表的参数
|
|
|
|
|
let params = {
|
2025-05-30 19:59:25 +08:00
|
|
|
|
name: this.appCodeOrName,
|
2025-05-30 10:04:55 +08:00
|
|
|
|
};
|
|
|
|
|
// 调用获取应用列表的 API
|
|
|
|
|
let res = await authApi(
|
|
|
|
|
"sysApplicationService",
|
|
|
|
|
"",
|
|
|
|
|
"queryEntity",
|
|
|
|
|
"",
|
|
|
|
|
params
|
|
|
|
|
);
|
|
|
|
|
// 隐藏搜索遮罩
|
|
|
|
|
this.drawMask = false;
|
|
|
|
|
if (res.status == "200") {
|
|
|
|
|
// 更新应用列表
|
|
|
|
|
this.appList = res.attribute;
|
|
|
|
|
}
|
|
|
|
|
},
|
2025-05-30 19:59:25 +08:00
|
|
|
|
/**
|
|
|
|
|
* 步骤描述变化时保存数据
|
|
|
|
|
*/
|
|
|
|
|
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) {
|
2025-06-20 18:58:03 +08:00
|
|
|
|
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(() => {});
|
2025-05-30 19:59:25 +08:00
|
|
|
|
}
|
|
|
|
|
},
|
2025-06-20 18:58:03 +08:00
|
|
|
|
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
|
|
|
|
|
);
|
|
|
|
|
},
|
2025-05-30 19:59:25 +08:00
|
|
|
|
/**
|
|
|
|
|
* 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;
|
2025-06-20 18:58:03 +08:00
|
|
|
|
// 更新当前选择的应用步骤描述
|
|
|
|
|
this.CurrentAppRow.description = item.apiName;
|
|
|
|
|
this.drawShowList[this.drawSelectIndex].options.stepDescribe =
|
|
|
|
|
item.apiName;
|
2025-05-30 19:59:25 +08:00
|
|
|
|
// 更新当前步骤的资源类型
|
|
|
|
|
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;
|
2025-06-20 18:58:03 +08:00
|
|
|
|
// 更新当前选择的应用步骤描述
|
|
|
|
|
this.CurrentAppRow.description = item.plugName;
|
|
|
|
|
this.drawShowList[this.drawSelectIndex].options.stepDescribe =
|
|
|
|
|
item.plugName;
|
2025-05-30 19:59:25 +08:00
|
|
|
|
// 更新当前步骤的资源类型
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
// 打开添加账号弹窗
|
2025-06-20 18:58:03 +08:00
|
|
|
|
this.$refs.addAccount.openDialog(
|
|
|
|
|
this.appActivIndex,
|
|
|
|
|
this.sceneID,
|
|
|
|
|
this.drawShowList[this.drawSelectIndex].options.stepID
|
|
|
|
|
);
|
2025-05-30 19:59:25 +08:00
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 重新加载用户列表
|
|
|
|
|
*/
|
|
|
|
|
addAccountConfirmClick() {
|
|
|
|
|
// 获取用户列表
|
|
|
|
|
this.GetAccountListAPI(this.appActivIndex);
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 当前选中的用户
|
|
|
|
|
* @param {Object} item 用户数据
|
|
|
|
|
*/
|
2025-06-20 18:58:03 +08:00
|
|
|
|
async handleUserClickEvent(item) {
|
2025-05-30 19:59:25 +08:00
|
|
|
|
// 更新选择的用户 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;
|
2025-06-20 18:58:03 +08:00
|
|
|
|
this.outsideFormData = {
|
|
|
|
|
tableName: "",
|
|
|
|
|
};
|
|
|
|
|
this.ColumnsFormData = {};
|
|
|
|
|
this.outsideOptions = [];
|
|
|
|
|
this.outsideColumns = [];
|
2025-05-30 19:59:25 +08:00
|
|
|
|
let params = {
|
|
|
|
|
flowId: this.sceneID,
|
|
|
|
|
id: this.drawShowList[this.drawSelectIndex].options.stepID,
|
|
|
|
|
step_acc_name: item.name,
|
|
|
|
|
step_acc_id: item.id,
|
|
|
|
|
};
|
|
|
|
|
// 保存场景步骤数据
|
2025-06-20 18:58:03 +08:00
|
|
|
|
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");
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-05-30 19:59:25 +08:00
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 获取插件列表
|
|
|
|
|
* @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;
|
|
|
|
|
}
|
|
|
|
|
},
|
2025-05-30 10:04:55 +08:00
|
|
|
|
/**
|
|
|
|
|
* 根据任务类型获取时间划分的标题
|
|
|
|
|
* @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) {
|
2025-05-30 19:59:25 +08:00
|
|
|
|
this.drawShowList[this.drawSelectIndex].actionName = "定时触发";
|
2025-05-30 10:04:55 +08:00
|
|
|
|
} else if (this.triggerMode === 1) {
|
2025-05-30 19:59:25 +08:00
|
|
|
|
this.drawShowList[this.drawSelectIndex].actionName = "应用程序触发";
|
2025-05-30 10:04:55 +08:00
|
|
|
|
} else if (this.triggerMode === 4) {
|
2025-05-30 19:59:25 +08:00
|
|
|
|
this.drawShowList[this.drawSelectIndex].actionName = "Webhook触发";
|
2025-05-30 10:04:55 +08:00
|
|
|
|
} else if (this.triggerMode === 3) {
|
|
|
|
|
this.drawShowList[this.drawSelectIndex].actionName = "手动触发";
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 场景步骤---【确定】
|
|
|
|
|
handleConfirmClick() {
|
|
|
|
|
this.examineHandleClose();
|
|
|
|
|
},
|
|
|
|
|
// 关闭场景步骤弹窗
|
|
|
|
|
examineHandleClose() {
|
|
|
|
|
// 触发关闭事件
|
|
|
|
|
this.$emit("examineHandleClose");
|
|
|
|
|
this.examineOperateDialog = false;
|
|
|
|
|
this.sceneName = "";
|
2025-05-30 19:59:25 +08:00
|
|
|
|
// 清空画布列表
|
|
|
|
|
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 = [];
|
2025-06-20 18:58:03 +08:00
|
|
|
|
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 = "";
|
2025-05-30 10:04:55 +08:00
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
2025-05-30 19:59:25 +08:00
|
|
|
|
::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;
|
|
|
|
|
}
|
2025-05-30 10:04:55 +08:00
|
|
|
|
.drawContent {
|
|
|
|
|
width: 100%;
|
2025-05-30 19:59:25 +08:00
|
|
|
|
height: calc(100vh - 100px);
|
2025-05-30 10:04:55 +08:00
|
|
|
|
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;
|
2025-06-20 18:58:03 +08:00
|
|
|
|
margin-top: 5px;
|
2025-05-30 10:04:55 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-30 19:59:25 +08:00
|
|
|
|
.drawItemBox {
|
2025-05-30 10:04:55 +08:00
|
|
|
|
display: flex;
|
2025-05-30 19:59:25 +08:00
|
|
|
|
background: #ffffff;
|
|
|
|
|
padding: 10px;
|
2025-05-30 10:04:55 +08:00
|
|
|
|
|
2025-05-30 19:59:25 +08:00
|
|
|
|
.title {
|
2025-05-30 10:04:55 +08:00
|
|
|
|
font-weight: 400;
|
2025-05-30 19:59:25 +08:00
|
|
|
|
font-size: 14px;
|
2025-05-30 10:04:55 +08:00
|
|
|
|
color: #333333;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-30 19:59:25 +08:00
|
|
|
|
.drawBox {
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #333333;
|
2025-05-30 10:04:55 +08:00
|
|
|
|
display: flex;
|
2025-05-30 19:59:25 +08:00
|
|
|
|
position: relative;
|
2025-05-30 10:04:55 +08:00
|
|
|
|
align-items: center;
|
|
|
|
|
|
2025-05-30 19:59:25 +08:00
|
|
|
|
.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;
|
2025-06-20 18:58:03 +08:00
|
|
|
|
margin-top: 5px;
|
2025-05-30 10:04:55 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-30 19:59:25 +08:00
|
|
|
|
|
|
|
|
|
.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;
|
|
|
|
|
}
|
2025-05-30 10:04:55 +08:00
|
|
|
|
}
|
2025-05-30 19:59:25 +08:00
|
|
|
|
|
2025-05-30 10:04:55 +08:00
|
|
|
|
// 选择操作
|
|
|
|
|
.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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-30 19:59:25 +08:00
|
|
|
|
|
|
|
|
|
.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;
|
|
|
|
|
}
|
2025-06-20 18:58:03 +08:00
|
|
|
|
.status {
|
|
|
|
|
margin-right: 10px;
|
|
|
|
|
font-size: 18px !important;
|
|
|
|
|
}
|
2025-05-30 19:59:25 +08:00
|
|
|
|
.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;
|
|
|
|
|
}
|
2025-06-20 18:58:03 +08:00
|
|
|
|
|
|
|
|
|
::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;
|
|
|
|
|
}
|
2025-05-30 19:59:25 +08:00
|
|
|
|
</style>
|
2025-06-20 18:58:03 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|