refactor(接口自动化): 修改页面布局和FAB按钮位置

This commit is contained in:
q4speed 2020-12-24 11:45:15 +08:00
parent 0b68685e0d
commit 611b1e3c97
2 changed files with 837 additions and 768 deletions

View File

@ -1,41 +1,42 @@
<template>
<el-card class="card-content">
<div>
<el-card>
<div class="card-content">
<div class="ms-main-div" @click="showAll">
<el-row>
<el-col>
<!--操作按钮-->
<div class="ms-opt-btn">
<el-button type="primary" size="small" @click="editScenario">{{$t('commons.save')}}</el-button>
<el-button type="primary" size="small" @click="editScenario">{{ $t('commons.save') }}</el-button>
</div>
</el-col>
</el-row>
<div class="tip">{{$t('test_track.plan_view.base_info')}}</div>
<el-form :model="currentScenario" label-position="right" label-width="80px" size="small" :rules="rules" ref="currentScenario" style="margin-right: 20px">
<div class="tip">{{ $t('test_track.plan_view.base_info') }}</div>
<el-form :model="currentScenario" label-position="right" label-width="80px" size="small" :rules="rules"
ref="currentScenario" style="margin-right: 20px">
<!-- 基础信息 -->
<el-row>
<el-col :span="12">
<el-col :span="7">
<el-form-item :label="$t('commons.name')" prop="name">
<el-input class="ms-scenario-input" size="small" v-model="currentScenario.name"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="7">
<el-form-item :label="$t('test_track.module.module')" prop="apiScenarioModuleId">
<el-select class="ms-scenario-input" size="small" v-model="currentScenario.apiScenarioModuleId">
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-col :span="7">
<el-form-item :label="$t('commons.status')" prop="status">
<el-select class="ms-scenario-input" size="small" v-model="currentScenario.status">
<el-option v-for="item in options" :key="item.id" :label="item.label" :value="item.id"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
</el-row>
<el-row>
<el-col :span="7">
<el-form-item :label="$t('api_test.definition.request.responsible')" prop="principal">
<el-select v-model="currentScenario.principal"
:placeholder="$t('api_test.definition.request.responsible')" filterable size="small"
@ -47,20 +48,16 @@
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-col :span="7">
<el-form-item :label="$t('test_track.case.priority')" prop="level">
<el-select class="ms-scenario-input" size="small" v-model="currentScenario.level">
<el-option v-for="item in levels" :key="item.id" :label="item.label" :value="item.id"/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="7">
<el-form-item :label="$t('api_test.automation.follow_people')" prop="followPeople">
<el-select v-model="currentScenario.followPeople"
:placeholder="$t('api_test.automation.follow_people')" filterable size="small"
@ -76,14 +73,13 @@
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-col :span="7">
<el-form-item label="Tag" prop="tags">
<ms-input-tag :currentScenario="currentScenario" ref="tag"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="7">
<el-form-item :label="$t('commons.description')" prop="description">
<el-input class="ms-http-textarea"
v-model="currentScenario.description"
@ -99,7 +95,7 @@
<!-- 场景步骤-->
<div v-loading="loading">
<div @click="showAll">
<p class="tip">{{$t('api_test.automation.scenario_step')}} </p>
<p class="tip">{{ $t('api_test.automation.scenario_step') }} </p>
</div>
<el-row>
<el-col :span="21">
@ -107,20 +103,21 @@
<div class="ms-debug-div" @click="showAll">
<el-row style="margin: 5px">
<el-col :span="6" class="ms-col-one ms-font">
{{currentScenario.name ===undefined || ''? $t('api_test.scenario.name') : currentScenario.name}}
{{ currentScenario.name === undefined || '' ? $t('api_test.scenario.name') : currentScenario.name }}
</el-col>
<el-col :span="3" class="ms-col-one ms-font">
{{$t('api_test.automation.step_total')}}{{scenarioDefinition.length}}
{{ $t('api_test.automation.step_total') }}{{ scenarioDefinition.length }}
</el-col>
<el-col :span="3" class="ms-col-one ms-font">
<el-link class="head" @click="showScenarioParameters">{{$t('api_test.automation.scenario_total')}}</el-link>
{{this.currentScenario.variables!=undefined?this.currentScenario.variables.length-1: 0}}
<el-link class="head" @click="showScenarioParameters">{{ $t('api_test.automation.scenario_total') }}
</el-link>
{{ this.currentScenario.variables != undefined ? this.currentScenario.variables.length - 1 : 0 }}
</el-col>
<el-col :span="3" class="ms-col-one ms-font">
<el-checkbox v-model="enableCookieShare">共享cookie</el-checkbox>
</el-col>
<el-col :span="7" class="ms-font">
{{$t('api_test.definition.request.run_env')}}
{{ $t('api_test.definition.request.run_env') }}
<el-select v-model="currentEnvironmentId" size="small" class="ms-htt-width"
:placeholder="$t('api_test.definition.request.run_env')"
clearable>
@ -140,7 +137,8 @@
</el-select>
</el-col>
<el-col :span="2">
<el-button size="small" type="primary" @click="runDebug">{{$t('api_test.request.debug')}}</el-button>
<el-button size="small" type="primary" @click="runDebug">{{ $t('api_test.request.debug') }}
</el-button>
</el-col>
</el-row>
</div>
@ -151,39 +149,54 @@
:expand-on-click-node="false"
@node-expand="nodeExpand"
@node-collapse="nodeCollapse"
:allow-drop="allowDrop" @node-drag-end="allowDrag" @node-click="nodeClick" v-if="!loading" draggable>
:allow-drop="allowDrop" @node-drag-end="allowDrag" @node-click="nodeClick" v-if="!loading"
draggable>
<span class="custom-tree-node father" slot-scope="{ node, data}" style="width: 96%">
<template>
<!-- 场景 -->
<ms-api-scenario-component v-if="data.type==='scenario'" :scenario="data" :node="node" @remove="remove" @copyRow="copyRow"/>
<ms-api-scenario-component v-if="data.type==='scenario'" :scenario="data" :node="node"
@remove="remove" @copyRow="copyRow"/>
<!--条件控制器-->
<ms-if-controller :controller="data" :node="node" v-if="data.type==='IfController'" @remove="remove" @copyRow="copyRow"/>
<ms-if-controller :controller="data" :node="node" v-if="data.type==='IfController'"
@remove="remove" @copyRow="copyRow"/>
<!--等待控制器-->
<ms-constant-timer :timer="data" :node="node" v-if="data.type==='ConstantTimer'" @remove="remove" @copyRow="copyRow"/>
<ms-constant-timer :timer="data" :node="node" v-if="data.type==='ConstantTimer'" @remove="remove"
@copyRow="copyRow"/>
<!--自定义脚本-->
<ms-jsr233-processor v-if="data.type==='JSR223Processor'" @remove="remove" @copyRow="copyRow" :title="$t('api_test.automation.customize_script')"
style-type="color: #7B4D12;background-color: #F1EEE9" :jsr223-processor="data" :node="node"/>
<ms-jsr233-processor v-if="data.type==='JSR223Processor'" @remove="remove" @copyRow="copyRow"
:title="$t('api_test.automation.customize_script')"
style-type="color: #7B4D12;background-color: #F1EEE9"
:jsr223-processor="data" :node="node"/>
<!--前置脚本-->
<ms-jsr233-processor v-if="data.type==='JSR223PreProcessor'" @remove="remove" @copyRow="copyRow" :title="$t('api_test.definition.request.pre_script')"
style-type="color: #B8741A;background-color: #F9F1EA" :jsr223-processor="data" :node="node"/>
<ms-jsr233-processor v-if="data.type==='JSR223PreProcessor'" @remove="remove" @copyRow="copyRow"
:title="$t('api_test.definition.request.pre_script')"
style-type="color: #B8741A;background-color: #F9F1EA"
:jsr223-processor="data" :node="node"/>
<!--后置脚本-->
<ms-jsr233-processor v-if="data.type==='JSR223PostProcessor'" @remove="remove" @copyRow="copyRow" :title="$t('api_test.definition.request.post_script')"
style-type="color: #783887;background-color: #F2ECF3" :jsr223-processor="data" :node="node"/>
<ms-jsr233-processor v-if="data.type==='JSR223PostProcessor'" @remove="remove" @copyRow="copyRow"
:title="$t('api_test.definition.request.post_script')"
style-type="color: #783887;background-color: #F2ECF3"
:jsr223-processor="data" :node="node"/>
<!--断言规则-->
<ms-api-assertions v-if="data.type==='Assertions'" @remove="remove" @copyRow="copyRow" customizeStyle="margin-top: 0px" :assertions="data" :node="node"/>
<ms-api-assertions v-if="data.type==='Assertions'" @remove="remove" @copyRow="copyRow"
customizeStyle="margin-top: 0px" :assertions="data" :node="node"/>
<!--提取规则-->
<ms-api-extract @remove="remove" @copyRow="copyRow" v-if="data.type==='Extract'" customizeStyle="margin-top: 0px" :extract="data" :node="node"/>
<ms-api-extract @remove="remove" @copyRow="copyRow" v-if="data.type==='Extract'"
customizeStyle="margin-top: 0px" :extract="data" :node="node"/>
<!--API 导入 -->
<ms-api-component :request="data" :currentEnvironmentId="currentEnvironmentId" @remove="remove" @copyRow="copyRow" v-if="data.type==='HTTPSamplerProxy'||data.type==='DubboSampler'||data.type==='JDBCSampler'||data.type==='TCPSampler'" :node="node"/>
<ms-api-component :request="data" :currentEnvironmentId="currentEnvironmentId" @remove="remove"
@copyRow="copyRow"
v-if="data.type==='HTTPSamplerProxy'||data.type==='DubboSampler'||data.type==='JDBCSampler'||data.type==='TCPSampler'"
:node="node"/>
</template>
</span>
</el-tree>
</div>
</el-col>
<!-- 按钮列表 -->
<div>
<el-col :span="3">
<vue-fab id="fab" mainBtnColor="#783887" :click-auto-close="false">
<vue-fab id="fab" mainBtnColor="#783887" size="small" :global-options="globalOptions"
:click-auto-close="false" v-outside-click="outsideClick">
<fab-item
v-for="(item, index) in buttons"
:key="index"
@ -196,23 +209,30 @@
@clickItem="item.click"/>
</vue-fab>
</el-col>
</div>
</el-row>
</div>
<!--接口列表-->
<el-drawer :visible.sync="apiListVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :modal="false" size="90%">
<el-drawer :visible.sync="apiListVisible" :destroy-on-close="true" direction="ltr" :withHeader="false"
:modal="false" size="90%">
<ms-api-definition :visible="visibleRef" :currentRow="currentRow"/>
<el-button style="float: right;margin: 0px 20px 0px" type="primary" @click="pushApiOrCase('REF')">{{$t('api_test.scenario.reference')}}</el-button>
<el-button style="float: right;" type="primary" @click="pushApiOrCase('Copy')">{{ $t('commons.copy') }}</el-button>
<el-button style="float: right;margin: 0px 20px 0px" type="primary" @click="pushApiOrCase('REF')">
{{ $t('api_test.scenario.reference') }}
</el-button>
<el-button style="float: right;" type="primary" @click="pushApiOrCase('Copy')">{{
$t('commons.copy')
}}
</el-button>
</el-drawer>
<!--自定义接口-->
<el-drawer :visible.sync="customizeVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :title="$t('api_test.automation.customize_req')" style="overflow: auto" :modal="false" size="90%">
<el-drawer :visible.sync="customizeVisible" :destroy-on-close="true" direction="ltr" :withHeader="false"
:title="$t('api_test.automation.customize_req')" style="overflow: auto" :modal="false" size="90%">
<ms-api-customize :request="customizeRequest" @addCustomizeApi="addCustomizeApi"/>
</el-drawer>
<!--场景导入 -->
<el-drawer :visible.sync="scenarioVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :title="$t('api_test.automation.scenario_import')" style="overflow: auto" :modal="false" size="90%">
<el-drawer :visible.sync="scenarioVisible" :destroy-on-close="true" direction="ltr" :withHeader="false"
:title="$t('api_test.automation.scenario_import')" style="overflow: auto" :modal="false" size="90%">
<ms-import-api-scenario @addScenario="addScenario"/>
</el-drawer>
@ -223,12 +243,14 @@
<ms-run :debug="true" :environment="currentEnvironmentId" :reportId="reportId" :run-data="debugData"
@runRefresh="runRefresh" ref="runTest"/>
<!-- 调试结果 -->
<el-drawer :visible.sync="debugVisible" :destroy-on-close="true" direction="ltr" :withHeader="true" :modal="false" size="90%">
<el-drawer :visible.sync="debugVisible" :destroy-on-close="true" direction="ltr" :withHeader="true" :modal="false"
size="90%">
<ms-api-report-detail :report-id="reportId" :debug="true" :currentProjectId="projectId"/>
</el-drawer>
<!--场景公共参数-->
<ms-scenario-parameters :currentScenario="currentScenario" @addParameters="addParameters" ref="scenarioParameters"/>
<ms-scenario-parameters :currentScenario="currentScenario" @addParameters="addParameters"
ref="scenarioParameters"/>
<!--外部导入-->
<api-import ref="apiImport" :saved="false" @refresh="apiImport"/>
</div>
@ -236,32 +258,33 @@
</template>
<script>
import {API_STATUS, PRIORITY} from "../../definition/model/JsonData";
import {WORKSPACE_ID} from '@/common/js/constants';
import {Assertions, Extract, IfController, JSR223Processor, ConstantTimer} from "../../definition/model/ApiTestModel";
import MsJsr233Processor from "./Jsr233Processor";
import {parseEnvironment} from "../../definition/model/EnvironmentModel";
import MsConstantTimer from "./ConstantTimer";
import MsIfController from "./IfController";
import MsApiAssertions from "../../definition/components/assertion/ApiAssertions";
import MsApiExtract from "../../definition/components/extract/ApiExtract";
import MsApiDefinition from "./api/ApiDefinition";
import MsApiComponent from "./ApiComponent";
import {ELEMENTS, ELEMENT_TYPE} from "./Setting";
import MsApiCustomize from "./ApiCustomize";
import {getUUID, getCurrentProjectID} from "@/common/js/utils";
import ApiEnvironmentConfig from "../../definition/components/environment/ApiEnvironmentConfig";
import MsInputTag from "./MsInputTag";
import MsRun from "./DebugRun";
import MsImportApiScenario from "./ImportApiScenario";
import MsApiScenarioComponent from "./ApiScenarioComponent";
import MsApiReportDetail from "../report/ApiReportDetail";
import MsScenarioParameters from "./ScenarioParameters";
import ApiImport from "../../definition/components/import/ApiImport";
import InputTag from 'vue-input-tag'
import "@/common/css/material-icons.css"
import {API_STATUS, PRIORITY} from "../../definition/model/JsonData";
import {WORKSPACE_ID} from '@/common/js/constants';
import {Assertions, Extract, IfController, JSR223Processor, ConstantTimer} from "../../definition/model/ApiTestModel";
import MsJsr233Processor from "./Jsr233Processor";
import {parseEnvironment} from "../../definition/model/EnvironmentModel";
import MsConstantTimer from "./ConstantTimer";
import MsIfController from "./IfController";
import MsApiAssertions from "../../definition/components/assertion/ApiAssertions";
import MsApiExtract from "../../definition/components/extract/ApiExtract";
import MsApiDefinition from "./api/ApiDefinition";
import MsApiComponent from "./ApiComponent";
import {ELEMENTS, ELEMENT_TYPE} from "./Setting";
import MsApiCustomize from "./ApiCustomize";
import {getUUID, getCurrentProjectID} from "@/common/js/utils";
import ApiEnvironmentConfig from "../../definition/components/environment/ApiEnvironmentConfig";
import MsInputTag from "./MsInputTag";
import MsRun from "./DebugRun";
import MsImportApiScenario from "./ImportApiScenario";
import MsApiScenarioComponent from "./ApiScenarioComponent";
import MsApiReportDetail from "../report/ApiReportDetail";
import MsScenarioParameters from "./ScenarioParameters";
import ApiImport from "../../definition/components/import/ApiImport";
import InputTag from 'vue-input-tag'
import "@/common/css/material-icons.css"
import OutsideClick from "@/common/js/outside-click";
export default {
export default {
name: "EditApiScenario",
props: {
moduleOptions: Array,
@ -325,6 +348,9 @@
projectId: "",
visibleRef: "",
enableCookieShare: false,
globalOptions: {
spacing: 30
}
}
}
,
@ -340,6 +366,7 @@
,
watch: {}
,
directives: {OutsideClick},
computed: {
buttons() {
let buttons = [
@ -447,7 +474,7 @@
},
methods: {
getIdx(index) {
return -1 * index - 2.25; //
return index - 0.33
},
showButton(...names) {
for (const name of names) {
@ -457,6 +484,9 @@
}
return false;
},
outsideClick() {
this.operatingElements = ELEMENTS.get("ALL");
},
addComponent(type) {
switch (type) {
case ELEMENT_TYPE.IfController:
@ -708,8 +738,7 @@
allowDrop(draggingNode, dropNode, dropType) {
if (dropType != "inner") {
return true;
}
else if (dropType === "inner" && dropNode.data.referenced != 'REF' && dropNode.data.referenced != 'Deleted'
} else if (dropType === "inner" && dropNode.data.referenced != 'REF' && dropNode.data.referenced != 'Deleted'
&& ELEMENTS.get(dropNode.data.type).indexOf(draggingNode.data.type) != -1) {
return true;
}
@ -854,8 +883,14 @@
this.currentScenario.modulePath = this.getPath(this.currentScenario.apiScenarioModuleId);
// 便
let scenario = {
id: this.currentScenario.id, enableCookieShare: this.enableCookieShare, name: this.currentScenario.name, variables: this.currentScenario.variables,
type: "scenario", referenced: 'Created', environmentId: this.currentEnvironmentId, hashTree: this.scenarioDefinition
id: this.currentScenario.id,
enableCookieShare: this.enableCookieShare,
name: this.currentScenario.name,
variables: this.currentScenario.variables,
type: "scenario",
referenced: 'Created',
environmentId: this.currentEnvironmentId,
hashTree: this.scenarioDefinition
};
this.currentScenario.scenarioDefinition = scenario;
if (this.currentScenario.tags instanceof Array) {
@ -892,106 +927,109 @@
}
}
}
}
}
</script>
<style scoped>
.ms-scenario-input {
.card-content {
height: calc(100vh - 196px);
overflow-y: auto;
}
.ms-scenario-input {
width: 100%;
}
}
.ms-main-div {
.ms-main-div {
background-color: white;
}
}
.ms-opt-btn {
.ms-opt-btn {
float: right;
margin-right: 20px;
}
}
.ms-debug-div {
margin-left: 20px;
.ms-debug-div {
border: 1px #DCDFE6 solid;
border-radius: 4px;
margin-right: 10px;
}
margin-right: 20px;
}
.ms-scenario-button {
.ms-scenario-button {
margin-left: 30%;
padding: 7px;
}
}
.tip {
.tip {
padding: 3px 5px;
font-size: 16px;
border-radius: 4px;
border-left: 4px solid #783887;
}
}
.ms-api-col {
.ms-api-col {
background-color: #7C3985;
border-color: #7C3985;
margin-right: 10px;
color: white;
}
}
.ms-font {
.ms-font {
color: #303133;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", Arial, sans-serif;
font-size: 13px;
}
}
.ms-col-one {
.ms-col-one {
margin-top: 5px;
}
}
#fab {
bottom: unset;
#fab {
right: 90px;
z-index: 5;
}
}
/deep/ .el-tree-node__content {
/deep/ .el-tree-node__content {
height: 100%;
margin-top: 8px;
vertical-align: center;
}
}
/deep/ .el-card__body {
/deep/ .el-card__body {
padding: 15px;
}
}
/deep/ .el-drawer__body {
/deep/ .el-drawer__body {
overflow: auto;
}
}
/deep/ .el-step__icon.is-text {
/deep/ .el-step__icon.is-text {
border: 1px solid;
}
}
/deep/ .el-drawer__header {
/deep/ .el-drawer__header {
margin-bottom: 0px;
}
}
/deep/ .el-link {
/deep/ .el-link {
font-weight: normal;
}
}
/deep/ .el-checkbox {
/deep/ .el-checkbox {
color: #303133;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", Arial, sans-serif;
font-size: 13px;
font-weight: normal;
}
}
/deep/ .el-checkbox__label {
/deep/ .el-checkbox__label {
padding-left: 5px;
}
}
.head {
.head {
border-bottom: 1px solid #303133;
color: #303133;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", Arial, sans-serif;
font-size: 13px;
}
}
</style>

View File

@ -0,0 +1,31 @@
const OutsideClick = {
// 初始化指令
bind(el, binding, vnode) {
function documentHandler(e) {
// 这里判断点击的元素是否是本身,是本身,则返回
if (el.contains(e.target)) {
return false;
}
// 判断指令中是否绑定了函数
if (binding.expression) {
// 如果绑定了函数 则调用那个函数此处binding.value就是handleClose方法
binding.value(e);
}
}
// 给当前元素绑定个私有变量方便在unbind中可以解除事件监听
el.__vueClickOutside__ = documentHandler;
document.addEventListener('click', documentHandler);
},
update() {
},
unbind(el, binding) {
// 解除事件监听
document.removeEventListener('click', el.__vueClickOutside__);
delete el.__vueClickOutside__;
},
};
export default OutsideClick;