mirror of
https://gitee.com/fit2cloud-feizhiyun/MeterSphere.git
synced 2024-11-30 02:58:31 +08:00
Merge branch 'master' of https://github.com/metersphere/metersphere
This commit is contained in:
commit
daa8f3821e
@ -101,7 +101,6 @@ public abstract class MsTestElement {
|
|||||||
public String getJmx(HashTree hashTree) {
|
public String getJmx(HashTree hashTree) {
|
||||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||||
SaveService.saveTree(hashTree, baos);
|
SaveService.saveTree(hashTree, baos);
|
||||||
System.out.print(baos.toString());
|
|
||||||
return baos.toString();
|
return baos.toString();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -13,6 +13,7 @@ import io.metersphere.api.service.ApiTestEnvironmentService;
|
|||||||
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
|
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.commons.utils.LogUtil;
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
import io.metersphere.commons.utils.ScriptEngineUtils;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
@ -158,12 +159,13 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
|||||||
sampler.setDomain(URLDecoder.decode(urlObject.getHost(), "UTF-8"));
|
sampler.setDomain(URLDecoder.decode(urlObject.getHost(), "UTF-8"));
|
||||||
sampler.setPort(urlObject.getPort());
|
sampler.setPort(urlObject.getPort());
|
||||||
sampler.setProtocol(urlObject.getProtocol());
|
sampler.setProtocol(urlObject.getProtocol());
|
||||||
|
String envPath = StringUtils.equals(urlObject.getPath(), "/") ? "" : urlObject.getPath();
|
||||||
if (CollectionUtils.isNotEmpty(this.getRest()) && this.isRest()) {
|
if (CollectionUtils.isNotEmpty(this.getRest()) && this.isRest()) {
|
||||||
sampler.setPath(getRestParameters(URLDecoder.decode(urlObject.getPath(), "UTF-8")));
|
envPath = getRestParameters(URLDecoder.decode(envPath, "UTF-8"));
|
||||||
|
sampler.setPath(envPath);
|
||||||
}
|
}
|
||||||
if (CollectionUtils.isNotEmpty(this.getArguments())) {
|
if (CollectionUtils.isNotEmpty(this.getArguments())) {
|
||||||
sampler.setPath(getPostQueryParameters(URLDecoder.decode(urlObject.getPath(), "UTF-8")));
|
sampler.setPath(getPostQueryParameters(URLDecoder.decode(envPath, "UTF-8")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -221,7 +223,8 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
|||||||
stringBuffer.append("/");
|
stringBuffer.append("/");
|
||||||
Map<String, String> keyValueMap = new HashMap<>();
|
Map<String, String> keyValueMap = new HashMap<>();
|
||||||
this.getRest().stream().filter(KeyValue::isEnable).filter(KeyValue::isValid).forEach(keyValue ->
|
this.getRest().stream().filter(KeyValue::isEnable).filter(KeyValue::isValid).forEach(keyValue ->
|
||||||
keyValueMap.put(keyValue.getName(), keyValue.getValue())
|
keyValueMap.put(keyValue.getName(), keyValue.getValue() != null && keyValue.getValue().startsWith("@") ?
|
||||||
|
ScriptEngineUtils.calculate(keyValue.getValue()) : keyValue.getValue())
|
||||||
);
|
);
|
||||||
try {
|
try {
|
||||||
Pattern p = Pattern.compile("(\\{)([\\w]+)(\\})");
|
Pattern p = Pattern.compile("(\\{)([\\w]+)(\\})");
|
||||||
@ -243,7 +246,8 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
|||||||
stringBuffer.append(path);
|
stringBuffer.append(path);
|
||||||
stringBuffer.append("?");
|
stringBuffer.append("?");
|
||||||
this.getArguments().stream().filter(KeyValue::isEnable).filter(KeyValue::isValid).forEach(keyValue ->
|
this.getArguments().stream().filter(KeyValue::isEnable).filter(KeyValue::isValid).forEach(keyValue ->
|
||||||
stringBuffer.append(keyValue.getName()).append("=").append(keyValue.getValue()).append("&")
|
stringBuffer.append(keyValue.getName()).append("=").append(keyValue.getValue() != null && keyValue.getValue().startsWith("@") ?
|
||||||
|
ScriptEngineUtils.calculate(keyValue.getValue()) : keyValue.getValue()).append("&")
|
||||||
);
|
);
|
||||||
return stringBuffer.substring(0, stringBuffer.length() - 1);
|
return stringBuffer.substring(0, stringBuffer.length() - 1);
|
||||||
}
|
}
|
||||||
@ -251,7 +255,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
|||||||
private Arguments httpArguments(List<KeyValue> list) {
|
private Arguments httpArguments(List<KeyValue> list) {
|
||||||
Arguments arguments = new Arguments();
|
Arguments arguments = new Arguments();
|
||||||
list.stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue -> {
|
list.stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue -> {
|
||||||
HTTPArgument httpArgument = new HTTPArgument(keyValue.getName(), keyValue.getValue());
|
HTTPArgument httpArgument = new HTTPArgument(keyValue.getName(), keyValue.getValue() != null && keyValue.getValue().startsWith("@") ? ScriptEngineUtils.calculate(keyValue.getValue()) : keyValue.getValue());
|
||||||
httpArgument.setAlwaysEncoded(keyValue.isEncode());
|
httpArgument.setAlwaysEncoded(keyValue.isEncode());
|
||||||
if (StringUtils.isNotBlank(keyValue.getContentType())) {
|
if (StringUtils.isNotBlank(keyValue.getContentType())) {
|
||||||
httpArgument.setContentType(keyValue.getContentType());
|
httpArgument.setContentType(keyValue.getContentType());
|
||||||
|
@ -66,7 +66,7 @@ public class JMeterService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HashTree getHashTree(Object scriptWrapper) throws Exception {
|
public static HashTree getHashTree(Object scriptWrapper) throws Exception {
|
||||||
Field field = scriptWrapper.getClass().getDeclaredField("testPlan");
|
Field field = scriptWrapper.getClass().getDeclaredField("testPlan");
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
return (HashTree) field.get(scriptWrapper);
|
return (HashTree) field.get(scriptWrapper);
|
||||||
|
@ -166,6 +166,16 @@ public class JmeterDocumentParser {
|
|||||||
u += k + "=" + v;
|
u += k + "=" + v;
|
||||||
return u;
|
return u;
|
||||||
});
|
});
|
||||||
|
//rest参数处理
|
||||||
|
if (url.contains("@")) {
|
||||||
|
String vars[] = url.split("@");
|
||||||
|
for (String item : vars) {
|
||||||
|
if (item.endsWith("/")) {
|
||||||
|
item = item.substring(0, item.length() - 1);
|
||||||
|
}
|
||||||
|
url = url.replace("@" + item, ScriptEngineUtils.calculate("@" + item));
|
||||||
|
}
|
||||||
|
}
|
||||||
ele.setTextContent(url + ((params != null && !params.equals("?")) ? params : ""));
|
ele.setTextContent(url + ((params != null && !params.equals("?")) ? params : ""));
|
||||||
break;
|
break;
|
||||||
case "Argument.value":
|
case "Argument.value":
|
||||||
|
@ -349,8 +349,8 @@ public class ApiAutomationService {
|
|||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogUtil.error(ex.getMessage());
|
LogUtil.error(ex.getMessage());
|
||||||
}
|
}
|
||||||
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig());
|
|
||||||
|
|
||||||
|
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig());
|
||||||
String runMode = ApiRunMode.SCENARIO.name();
|
String runMode = ApiRunMode.SCENARIO.name();
|
||||||
if (StringUtils.isNotBlank(request.getRunMode()) && StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) {
|
if (StringUtils.isNotBlank(request.getRunMode()) && StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) {
|
||||||
runMode = ApiRunMode.SCENARIO_PLAN.name();
|
runMode = ApiRunMode.SCENARIO_PLAN.name();
|
||||||
@ -380,9 +380,10 @@ public class ApiAutomationService {
|
|||||||
config.setConfig(envConfig);
|
config.setConfig(envConfig);
|
||||||
HashTree hashTree = request.getTestElement().generateHashTree(config);
|
HashTree hashTree = request.getTestElement().generateHashTree(config);
|
||||||
// 调用执行方法
|
// 调用执行方法
|
||||||
jMeterService.runDefinition(request.getId(), hashTree, request.getReportId(), ApiRunMode.SCENARIO.name());
|
|
||||||
createScenarioReport(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(),
|
createScenarioReport(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(),
|
||||||
SessionUtils.getUserId());
|
SessionUtils.getUserId());
|
||||||
|
// 调用执行方法
|
||||||
|
jMeterService.runDefinition(request.getId(), hashTree, request.getReportId(), ApiRunMode.SCENARIO.name());
|
||||||
return request.getId();
|
return request.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,6 @@ public class Translator {
|
|||||||
* 单Key翻译
|
* 单Key翻译
|
||||||
*/
|
*/
|
||||||
public static String get(String key) {
|
public static String get(String key) {
|
||||||
return messageSource.getMessage(key, null, "Not Support Key", LocaleContextHolder.getLocale());
|
return messageSource.getMessage(key, null, "Not Support Key: " + key, LocaleContextHolder.getLocale());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 79343a2763b014355f91fc21b2356a95ae437973
|
Subproject commit c10b11f224e4186306e6ae3a3976e29a42af96a5
|
@ -0,0 +1,3 @@
|
|||||||
|
create index project_workspace_id_index on project (workspace_id);
|
||||||
|
create index test_case_review_creator_index on test_case_review (creator);
|
||||||
|
create index test_case_review_project_project_id_index on test_case_review_project (project_id);
|
@ -60,6 +60,7 @@ test_resource_pool_name_is_null=Test Resource Pool name cannot be null
|
|||||||
test_resource_pool_name_already_exists=The test resource pool name already exists
|
test_resource_pool_name_already_exists=The test resource pool name already exists
|
||||||
load_test=Load Test
|
load_test=Load Test
|
||||||
test_resource_pool_is_use=This resource pool is in use and cannot be deleted
|
test_resource_pool_is_use=This resource pool is in use and cannot be deleted
|
||||||
|
only_one_k8s=Only one K8S can be added
|
||||||
#project
|
#project
|
||||||
project_name_is_null=Project name cannot be null
|
project_name_is_null=Project name cannot be null
|
||||||
project_name_already_exists=The project name already exists
|
project_name_already_exists=The project name already exists
|
||||||
|
@ -60,6 +60,7 @@ test_resource_pool_name_is_null=资源池名称不能为空
|
|||||||
test_resource_pool_name_already_exists=资源池名称已存在
|
test_resource_pool_name_already_exists=资源池名称已存在
|
||||||
load_test=性能测试
|
load_test=性能测试
|
||||||
test_resource_pool_is_use=正在使用此资源池,无法删除
|
test_resource_pool_is_use=正在使用此资源池,无法删除
|
||||||
|
only_one_k8s=只能添加一个 K8S
|
||||||
#project
|
#project
|
||||||
project_name_is_null=项目名称不能为空
|
project_name_is_null=项目名称不能为空
|
||||||
project_name_already_exists=项目名称已存在
|
project_name_already_exists=项目名称已存在
|
||||||
|
@ -60,6 +60,7 @@ test_resource_pool_name_is_null=資源池名稱不能為空
|
|||||||
test_resource_pool_name_already_exists=資源池名稱已存在
|
test_resource_pool_name_already_exists=資源池名稱已存在
|
||||||
load_test=性能測試
|
load_test=性能測試
|
||||||
test_resource_pool_is_use=正在使用此資源池,無法刪除
|
test_resource_pool_is_use=正在使用此資源池,無法刪除
|
||||||
|
only_one_k8s=只能添加一個 K8S
|
||||||
#project
|
#project
|
||||||
project_name_is_null=項目名稱不能為空
|
project_name_is_null=項目名稱不能為空
|
||||||
project_name_already_exists=項目名稱已存在
|
project_name_already_exists=項目名稱已存在
|
||||||
|
@ -91,6 +91,7 @@
|
|||||||
name: "MsApiComponent",
|
name: "MsApiComponent",
|
||||||
props: {
|
props: {
|
||||||
request: {},
|
request: {},
|
||||||
|
currentScenario: {},
|
||||||
node: {},
|
node: {},
|
||||||
currentEnvironmentId: String,
|
currentEnvironmentId: String,
|
||||||
},
|
},
|
||||||
@ -178,7 +179,13 @@
|
|||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.runData = [];
|
this.runData = [];
|
||||||
this.request.useEnvironment = this.currentEnvironmentId;
|
this.request.useEnvironment = this.currentEnvironmentId;
|
||||||
this.runData.push(this.request);
|
|
||||||
|
let debugData = {
|
||||||
|
id: this.currentScenario.id, name: this.currentScenario.name, type: "scenario",
|
||||||
|
variables: this.currentScenario.variables, referenced: 'Created', enableCookieShare: this.enableCookieShare,
|
||||||
|
environmentId: this.currentEnvironmentId, hashTree: [this.request]
|
||||||
|
};
|
||||||
|
this.runData.push(debugData);
|
||||||
/*触发执行操作*/
|
/*触发执行操作*/
|
||||||
this.reportId = getUUID().substring(0, 8);
|
this.reportId = getUUID().substring(0, 8);
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@
|
|||||||
<!--提取规则-->
|
<!--提取规则-->
|
||||||
<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 导入 -->
|
<!--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" :currentScenario="currentScenario" :currentEnvironmentId="currentEnvironmentId" @remove="remove" @copyRow="copyRow" v-if="data.type==='HTTPSamplerProxy'||data.type==='DubboSampler'||data.type==='JDBCSampler'||data.type==='TCPSampler'" :node="node"/>
|
||||||
</template>
|
</template>
|
||||||
</span>
|
</span>
|
||||||
</el-tree>
|
</el-tree>
|
||||||
|
211
frontend/src/business/components/common/json/JsonTable.vue
Normal file
211
frontend/src/business/components/common/json/JsonTable.vue
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
<template>
|
||||||
|
<div v-loading="loading">
|
||||||
|
<el-table
|
||||||
|
:data="tableData"
|
||||||
|
style="width: 100%;margin-bottom: 20px;"
|
||||||
|
row-key="id"
|
||||||
|
default-expand-all
|
||||||
|
@cell-click="editor"
|
||||||
|
:tree-props="{children: 'children', hasChildren: 'hasChildren'}">
|
||||||
|
<el-table-column
|
||||||
|
prop="name"
|
||||||
|
label="名称">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-input v-if="scope.row.id === tabClickIndex && tabClickProperty === 'name'" v-model="scope.row.name" size="mini" style="padding-left: 20px" @blur="inputBlur(scope.row)"></el-input>
|
||||||
|
<span v-else>{{scope.row.name}}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="required"
|
||||||
|
label="必输项"
|
||||||
|
align="center"
|
||||||
|
width="80">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-checkbox v-model="scope.row.required"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="type"
|
||||||
|
width="120px"
|
||||||
|
label="类型">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-select v-model="scope.row.type" slot="prepend" size="small">
|
||||||
|
<el-option v-for="item in typeData" :key="item.id" :label="item.label" :value="item.id"/>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="value"
|
||||||
|
label="内容">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-input v-if="scope.row.id === tabClickIndex && tabClickProperty === 'value'" v-model="scope.row.value" size="mini"></el-input>
|
||||||
|
<span v-else>{{scope.row.value}}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="describe"
|
||||||
|
label="描述">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-input v-if="scope.row.id === tabClickIndex && tabClickProperty === 'describe'" v-model="scope.row.describe" size="mini"></el-input>
|
||||||
|
<span v-else>{{scope.row.describe}}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="opt"
|
||||||
|
label="操作"
|
||||||
|
width="100">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div>
|
||||||
|
<i class="el-icon-setting" style="margin-left: 5px;cursor: pointer" @click="setting(scope.row)"/>
|
||||||
|
<i class="el-icon-plus" style="margin-left: 5px;cursor: pointer" @click="add(scope.row)"/>
|
||||||
|
<i class="el-icon-close" style="margin-left: 5px;cursor: pointer" @click="deleteRow(scope.row)"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import {getUUID} from "@/common/js/utils";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MsJsonTable",
|
||||||
|
components: {},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
tableData: [{
|
||||||
|
id: "root",
|
||||||
|
parent: null,
|
||||||
|
name: 'root',
|
||||||
|
required: true,
|
||||||
|
type: 'object',
|
||||||
|
value: 'object',
|
||||||
|
describe: 'describe',
|
||||||
|
editor: false,
|
||||||
|
children: [],
|
||||||
|
}]
|
||||||
|
,
|
||||||
|
tabClickProperty: "",
|
||||||
|
tabClickIndex: "",
|
||||||
|
typeData: [
|
||||||
|
{id: 'string', label: 'string'},
|
||||||
|
{id: 'number', label: 'number'},
|
||||||
|
{id: 'array', label: 'array'},
|
||||||
|
{id: 'object', label: 'object'},
|
||||||
|
{id: 'boolean', label: 'boolean'},
|
||||||
|
{id: 'integer', label: 'integer'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
editor(row, column) {
|
||||||
|
switch (column.property) {
|
||||||
|
case 'name':
|
||||||
|
this.tabClickIndex = row.id
|
||||||
|
this.tabClickProperty = column.property
|
||||||
|
break
|
||||||
|
case 'value':
|
||||||
|
this.tabClickIndex = row.id
|
||||||
|
this.tabClickProperty = column.property
|
||||||
|
break;
|
||||||
|
case 'describe':
|
||||||
|
this.tabClickIndex = row.id
|
||||||
|
this.tabClickProperty = column.property
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inputBlur() {
|
||||||
|
this.tabClickIndex = null;
|
||||||
|
this.tabClickProperty = '';
|
||||||
|
this.reload();
|
||||||
|
},
|
||||||
|
reload() {
|
||||||
|
this.loading = true;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setting() {
|
||||||
|
|
||||||
|
},
|
||||||
|
add(row) {
|
||||||
|
let obj = {
|
||||||
|
id: getUUID(),
|
||||||
|
name: 'field',
|
||||||
|
required: true,
|
||||||
|
type: 'string',
|
||||||
|
value: 'test',
|
||||||
|
parent: null,
|
||||||
|
describe: 'describe',
|
||||||
|
children: [],
|
||||||
|
}
|
||||||
|
console.log("all", this.tableData)
|
||||||
|
console.log("row", row)
|
||||||
|
|
||||||
|
if (row.type === "object") {
|
||||||
|
obj.parent = row.id;
|
||||||
|
row.children.push(obj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let parentRow = {};
|
||||||
|
const index = this.tableData.findIndex(d => d.id != undefined && row.parent != undefined && d.id === row.parent);
|
||||||
|
if (index != -1) {
|
||||||
|
parentRow = this.tableData[index];
|
||||||
|
} else {
|
||||||
|
for (let i in this.tableData) {
|
||||||
|
if (this.tableData[i].children) {
|
||||||
|
parentRow = this.recursiveRemove(this.tableData[i].children, row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(parentRow)
|
||||||
|
if (parentRow) {
|
||||||
|
obj.parent = parentRow.id;
|
||||||
|
parentRow.children.push(obj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.tableData.push(obj);
|
||||||
|
},
|
||||||
|
recursiveRemove(arr, row) {
|
||||||
|
for (let i in arr) {
|
||||||
|
const index = arr.findIndex(d => d.id != undefined && row.id != undefined && d.id === row.id)
|
||||||
|
if (index != -1) {
|
||||||
|
arr.splice(index, 1);
|
||||||
|
return arr[i];
|
||||||
|
}
|
||||||
|
if (arr[i].children != undefined && arr[i].children.length > 0) {
|
||||||
|
this.recursiveRemove(arr[i].children, row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deleteRow(row) {
|
||||||
|
const index = this.tableData.findIndex(d => d.id != undefined && row.id != undefined && d.id === row.id)
|
||||||
|
if (index == -1) {
|
||||||
|
this.tableData.forEach(item => {
|
||||||
|
if (item.children) {
|
||||||
|
this.recursiveRemove(item.children, row);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.tableData.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.name-input >>> .el-input__inner {
|
||||||
|
height: 25px;
|
||||||
|
line-height: 25px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1 +1 @@
|
|||||||
Subproject commit 8cda5c873cd9985c97adb34efacf507167fa4182
|
Subproject commit 7d43154a7c19732407a8e9ace8a7d1ea13c91f36
|
@ -372,9 +372,9 @@ export default {
|
|||||||
test_error_log: 'Test Error Log',
|
test_error_log: 'Test Error Log',
|
||||||
test_log_details: 'Test Log Details',
|
test_log_details: 'Test Log Details',
|
||||||
test_details: 'Test Details',
|
test_details: 'Test Details',
|
||||||
test_duration: 'Test Duration:{0} minutes {1} seconds',
|
test_duration: 'Current Execution Time:{0} minutes {1} seconds',
|
||||||
test_start_time: 'Test Start Time',
|
test_start_time: 'Start Execution Time',
|
||||||
test_end_time: 'Test End Time',
|
test_end_time: 'Plan End Time',
|
||||||
test_stop_now: 'Test Stop Now',
|
test_stop_now: 'Test Stop Now',
|
||||||
test_stop_now_confirm: 'Are you sure you want to stop the current test immediately?',
|
test_stop_now_confirm: 'Are you sure you want to stop the current test immediately?',
|
||||||
test_rerun_confirm: 'Are you sure you want to rerun the current test immediately?',
|
test_rerun_confirm: 'Are you sure you want to rerun the current test immediately?',
|
||||||
|
@ -369,9 +369,9 @@ export default {
|
|||||||
test_error_log: '错误记录',
|
test_error_log: '错误记录',
|
||||||
test_log_details: '日志详情',
|
test_log_details: '日志详情',
|
||||||
test_details: '测试详情',
|
test_details: '测试详情',
|
||||||
test_duration: '持续时间:{0} 分钟 {1} 秒',
|
test_duration: '当前执行时长:{0} 分钟 {1} 秒',
|
||||||
test_start_time: '开始时间',
|
test_start_time: '开始执行时间',
|
||||||
test_end_time: '结束时间',
|
test_end_time: '计划结束时间',
|
||||||
test_stop_now: '立即停止',
|
test_stop_now: '立即停止',
|
||||||
test_stop_now_confirm: '确定要立即停止当前测试吗?',
|
test_stop_now_confirm: '确定要立即停止当前测试吗?',
|
||||||
test_rerun_confirm: '确定要再次执行当前测试吗?',
|
test_rerun_confirm: '确定要再次执行当前测试吗?',
|
||||||
|
@ -369,9 +369,9 @@ export default {
|
|||||||
test_error_log: '錯誤記錄',
|
test_error_log: '錯誤記錄',
|
||||||
test_log_details: '日誌詳情',
|
test_log_details: '日誌詳情',
|
||||||
test_details: '測試詳情',
|
test_details: '測試詳情',
|
||||||
test_duration: '持續時間:{0} 分鐘 {1} 秒',
|
test_duration: '當前執行時長:{0} 分鐘 {1} 秒',
|
||||||
test_start_time: '開始時間',
|
test_start_time: '開始執行時間',
|
||||||
test_end_time: '結束時間',
|
test_end_time: '計劃結束時間',
|
||||||
test_stop_now: '立即停止',
|
test_stop_now: '立即停止',
|
||||||
test_stop_now_confirm: '確定要立即停止當前測試嗎?',
|
test_stop_now_confirm: '確定要立即停止當前測試嗎?',
|
||||||
test_rerun_confirm: '確定要再次執行當前測試嗎?',
|
test_rerun_confirm: '確定要再次執行當前測試嗎?',
|
||||||
|
Loading…
Reference in New Issue
Block a user