feat(性能测试): 性能测试高级配置增加选项

--story=1013936 --user=宋天阳 【性能测试】高级配置增加可配置项
https://www.tapd.cn/55049933/s/1443207
This commit is contained in:
song-tianyang 2023-12-13 12:12:52 +08:00 committed by 刘瑞斌
parent 6235a20af8
commit c30dac746f
14 changed files with 301 additions and 22 deletions

View File

@ -1327,6 +1327,14 @@ const message = {
"The file already exists in the project, please import it directly", "The file already exists in the project, please import it directly",
project_file_update_type_error: "Updated file types must be consistent", project_file_update_type_error: "Updated file types must be consistent",
csv_has_header: "Contains Title", csv_has_header: "Contains Title",
csv_file_end_recycle: "Recycle when file end",
csv_file_end_stop_thread: "Stop thread when file end",
csv_file_end_stop_thread_option: {
all: "All thread",
group: "Thread group",
thread: "Thread",
},
thread_share: "Thread share",
csv_split: "CSV Split", csv_split: "CSV Split",
on_sample_error: "Sampler error", on_sample_error: "Sampler error",
continue: "Continue", continue: "Continue",

View File

@ -1284,6 +1284,14 @@ const message = {
load_api_automation_jmx: "引用接口自动化场景", load_api_automation_jmx: "引用接口自动化场景",
project_file_exist: "项目中已存在该文件,请直接引用", project_file_exist: "项目中已存在该文件,请直接引用",
csv_has_header: "包含表头", csv_has_header: "包含表头",
csv_file_end_recycle: "遇到文件结束符再次循环",
csv_file_end_stop_thread: "遇到文件结束符停止线程",
csv_file_end_stop_thread_option: {
all: "所有线程",
group: "当前线程组",
thread: "当前线程",
},
thread_share: "线程共享模式",
csv_split: "CSV分割", csv_split: "CSV分割",
on_sample_error: "取样器错误后", on_sample_error: "取样器错误后",
continue: "继续", continue: "继续",

View File

@ -1283,6 +1283,14 @@ const message = {
load_api_automation_jmx: "引用接口自動化場景", load_api_automation_jmx: "引用接口自動化場景",
project_file_exist: "項目中已存在該文件,請直接引用", project_file_exist: "項目中已存在該文件,請直接引用",
csv_has_header: "包含表頭", csv_has_header: "包含表頭",
csv_file_end_recycle: "遇到文件結束符再次循環",
csv_file_end_stop_thread: "遇到文件結束符停止線程",
csv_file_end_stop_thread_option: {
all: "所有線程",
group: "當前線程組",
thread: "當前線程",
},
thread_share: "線程共享模式",
csv_split: "CSV分割", csv_split: "CSV分割",
on_sample_error: "取樣器錯誤後", on_sample_error: "取樣器錯誤後",
continue: "繼續", continue: "繼續",

View File

@ -10,11 +10,13 @@ import io.metersphere.jmeter.utils.ScriptEngineUtils;
import io.metersphere.parse.EngineSourceParser; import io.metersphere.parse.EngineSourceParser;
import io.metersphere.parse.EngineSourceParserFactory; import io.metersphere.parse.EngineSourceParserFactory;
import io.metersphere.service.BaseTestResourcePoolService; import io.metersphere.service.BaseTestResourcePoolService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.Node; import org.dom4j.Node;
import org.dom4j.tree.BaseElement;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -41,11 +43,24 @@ public class JmeterDocumentParser implements EngineSourceParser {
private final static String HTTP_SAMPLER_PROXY = "HTTPSamplerProxy"; private final static String HTTP_SAMPLER_PROXY = "HTTPSamplerProxy";
private final static String CSV_DATA_SET = "CSVDataSet"; private final static String CSV_DATA_SET = "CSVDataSet";
private final static String THREAD_GROUP_AUTO_STOP = "io.metersphere.jmeter.reporters.ThreadGroupAutoStop"; private final static String THREAD_GROUP_AUTO_STOP = "io.metersphere.jmeter.reporters.ThreadGroupAutoStop";
private final static List<String> SCRIPTS = new ArrayList<>() {{
add("JSR223PreProcessor");
add("JSR223PostProcessor");
add("JSR223Sampler");
add("JSR223Assertion");
add("JSR223Timer");
add("JSR223Listener");
}};
private EngineContext context; private EngineContext context;
private boolean cacheScript = false;
@Override @Override
public byte[] parse(EngineContext context, InputStream source) throws Exception { public byte[] parse(EngineContext context, InputStream source) throws Exception {
this.context = context; this.context = context;
Object cacheScriptObj = context.getProperty("cacheScript");
if (cacheScriptObj != null) {
cacheScript = BooleanUtils.toBoolean(cacheScriptObj.toString());
}
Document document = EngineSourceParserFactory.getDocument(source); Document document = EngineSourceParserFactory.getDocument(source);
@ -56,7 +71,6 @@ public class JmeterDocumentParser implements EngineSourceParser {
// jmeterTestPlan的子元素肯定是<hashTree></hashTree> // jmeterTestPlan的子元素肯定是<hashTree></hashTree>
parseHashTree(ele); parseHashTree(ele);
} }
return EngineSourceParserFactory.getBytes(document); return EngineSourceParserFactory.getBytes(document);
} }
@ -110,12 +124,31 @@ public class JmeterDocumentParser implements EngineSourceParser {
} else if (ele.getName().endsWith(RESULT_COLLECTOR)) { } else if (ele.getName().endsWith(RESULT_COLLECTOR)) {
// 处理结果收集器性能测试不需要这些 // 处理结果收集器性能测试不需要这些
processResultCollector(ele); processResultCollector(ele);
} else if (CollectionUtils.containsAny(SCRIPTS, ele.getName())) {
this.elementCacheScript(ele);
} }
} }
} }
} }
private void elementCacheScript(Element element) {
List<Element> childNodes = element.elements();
Element cacheKeyNode = null;
for (Element item : childNodes) {
if (nodeNameEquals(item, STRING_PROP) && StringUtils.equalsIgnoreCase(item.attributeValue("name"), "cacheKey")) {
cacheKeyNode = item;
break;
}
}
if (cacheKeyNode == null) {
cacheKeyNode = new BaseElement(STRING_PROP);
cacheKeyNode.addAttribute("name", "cacheKey");
element.add(cacheKeyNode);
}
cacheKeyNode.setText(cacheScript ? "true" : "false");
}
private void processThreadType(Element ele) { private void processThreadType(Element ele) {
Object threadType = context.getProperty("threadType"); Object threadType = context.getProperty("threadType");
if (threadType instanceof List) { if (threadType instanceof List) {
@ -238,20 +271,101 @@ public class JmeterDocumentParser implements EngineSourceParser {
private void processCsvDataSet(Element element) { private void processCsvDataSet(Element element) {
List<Element> childNodes = element.elements(); List<Element> childNodes = element.elements();
String fileName = null;
for (Element item : childNodes) { for (Element item : childNodes) {
if (nodeNameEquals(item, STRING_PROP)) { if (nodeNameEquals(item, STRING_PROP)) {
String filenameTag = item.attributeValue("name"); if (StringUtils.equals(item.attributeValue("name"), "filename")) {
if (StringUtils.equals(filenameTag, "filename")) { fileName = item.getText();
// 截取文件名 String separator = "/";
handleFilename(item); if (!StringUtils.contains(fileName, "/")) {
// 切割CSV文件 separator = "\\";
splitCsvFile(item); }
fileName = fileName.substring(fileName.lastIndexOf(separator) + 1);
break; break;
} }
} }
} }
Element recycleNode = null;
Element stopThreadNode = null;
Element shareModeNode = null;
for (Element item : childNodes) {
String filenameTag = item.attributeValue("name");
if (nodeNameEquals(item, STRING_PROP)) {
if (StringUtils.equals(filenameTag, "filename")) {
// 截取文件名
handleFilename(item);
splitCsvFile(item);
// 切割CSV文件
} else if (StringUtils.equalsIgnoreCase(filenameTag, "shareMode")) {
shareModeNode = item;
}
} else if (nodeNameEquals(item, BOOL_PROP)) {
if (StringUtils.equalsIgnoreCase(filenameTag, "recycle")) {
recycleNode = item;
} else if (StringUtils.equalsIgnoreCase(filenameTag, "stopThread")) {
stopThreadNode = item;
}
}
} }
if (stopThreadNode == null) {
stopThreadNode = new BaseElement(BOOL_PROP);
stopThreadNode.addAttribute("name", "stopThread");
element.add(stopThreadNode);
}
if (recycleNode == null) {
recycleNode = new BaseElement(BOOL_PROP);
recycleNode.addAttribute("name", "recycle");
element.add(recycleNode);
}
if (shareModeNode == null) {
shareModeNode = new BaseElement(STRING_PROP);
shareModeNode.addAttribute("name", "shareMode");
element.add(shareModeNode);
}
setShareMode(shareModeNode, fileName);
setRecycle(recycleNode, fileName);
setStopThread(stopThreadNode, fileName);
}
private void setShareMode(Node item, String fileName) {
Object csvConfig = context.getProperty("csvConfig");
if (csvConfig == null) {
return;
}
Object config = ((Map) csvConfig).get(fileName);
if (config != null) {
String shareMode = String.valueOf(((Map) (config)).get("shareMode"));
item.setText(shareMode);
}
}
private void setRecycle(Node item, String fileName) {
Object csvConfig = context.getProperty("csvConfig");
if (csvConfig == null) {
return;
}
Object config = ((Map) csvConfig).get(fileName);
if (config != null) {
Boolean recycle = (Boolean) ((Map) (config)).get("recycle");
item.setText(String.valueOf(BooleanUtils.toBoolean(recycle)));
}
}
private void setStopThread(Node item, String fileName) {
Object csvConfig = context.getProperty("csvConfig");
if (csvConfig == null) {
return;
}
Object config = ((Map) csvConfig).get(fileName);
if (config != null) {
Boolean recycle = (Boolean) ((Map) (config)).get("stopThread");
item.setText(String.valueOf(BooleanUtils.toBoolean(recycle)));
}
}
private void splitCsvFile(Node item) { private void splitCsvFile(Node item) {
String filename = item.getText(); String filename = item.getText();
filename = StringUtils.removeStart(filename, "/test/"); filename = StringUtils.removeStart(filename, "/test/");

View File

@ -37,7 +37,14 @@ export default {
}); });
let csvFiles = []; let csvFiles = [];
for (const f of csvSet) { for (const f of csvSet) {
csvFiles.push({name: f, csvSplit: false, csvHasHeader: true}); csvFiles.push({
name: f,
csvSplit: false,
csvHasHeader: true,
recycle: true,
stopThread: false,
shareMode: "shareMode.thread"
});
} }
this.$refs.advancedConfig.csvFiles = csvFiles; this.$refs.advancedConfig.csvFiles = csvFiles;

View File

@ -162,7 +162,14 @@ export default {
}); });
let csvFiles = []; let csvFiles = [];
for (const f of csvSet) { for (const f of csvSet) {
csvFiles.push({name: f, csvSplit: false, csvHasHeader: true}); csvFiles.push({
name: f,
csvSplit: false,
csvHasHeader: true,
recycle: true,
stopThread: false,
shareMode: "shareMode.thread"
});
} }
this.$set(handler, "threadGroups", threadGroups); this.$set(handler, "threadGroups", threadGroups);
@ -196,7 +203,14 @@ export default {
}); });
let csvFiles = []; let csvFiles = [];
for (const f of csvSet) { for (const f of csvSet) {
csvFiles.push({name: f, csvSplit: false, csvHasHeader: true}); csvFiles.push({
name: f,
csvSplit: false,
csvHasHeader: true,
recycle: true,
stopThread: false,
shareMode: "shareMode.thread"
});
} }
this.$set(handler, "threadGroups", threadGroups); this.$set(handler, "threadGroups", threadGroups);

View File

@ -673,7 +673,14 @@ export default {
}); });
let csvFiles = []; let csvFiles = [];
for (const f of csvSet) { for (const f of csvSet) {
csvFiles.push({name: f, csvSplit: false, csvHasHeader: true}); csvFiles.push({
name: f,
csvSplit: false,
csvHasHeader: true,
recycle: true,
stopThread: false,
shareMode: "shareMode.thread"
});
} }
this.$set(handler, "threadGroups", threadGroups); this.$set(handler, "threadGroups", threadGroups);
@ -681,7 +688,6 @@ export default {
this.$refs.basicConfig.threadGroups = threadGroups; this.$refs.basicConfig.threadGroups = threadGroups;
this.$refs.pressureConfig.threadGroups = threadGroups; this.$refs.pressureConfig.threadGroups = threadGroups;
this.$refs.advancedConfig.csvFiles = csvFiles; this.$refs.advancedConfig.csvFiles = csvFiles;
this.$refs.pressureConfig.resourcePoolChange(); this.$refs.pressureConfig.resourcePoolChange();
handler.calculateTotalChart(); handler.calculateTotalChart();
}, },

View File

@ -2,7 +2,7 @@
<div> <div>
<!-- 基本配置 --> <!-- 基本配置 -->
<el-row> <el-row>
<el-col :span="6"> <el-col :span="5">
<el-form :inline="true" :disabled="isReadOnly"> <el-form :inline="true" :disabled="isReadOnly">
<el-form-item> <el-form-item>
<div>{{ $t('load_test.connect_timeout') }}</div> <div>{{ $t('load_test.connect_timeout') }}</div>
@ -18,7 +18,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="5">
<el-form :inline="true" :disabled="isReadOnly"> <el-form :inline="true" :disabled="isReadOnly">
<el-form-item> <el-form-item>
<div>{{ $t('load_test.response_timeout') }}</div> <div>{{ $t('load_test.response_timeout') }}</div>
@ -34,7 +34,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="5">
<el-form :inline="true" :disabled="isReadOnly"> <el-form :inline="true" :disabled="isReadOnly">
<el-form-item> <el-form-item>
<div> <div>
@ -64,7 +64,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="5">
<el-form :inline="true" :disabled="isReadOnly"> <el-form :inline="true" :disabled="isReadOnly">
<el-form-item> <el-form-item>
<div>{{ $t('load_test.custom_http_code') }}</div> <div>{{ $t('load_test.custom_http_code') }}</div>
@ -77,6 +77,13 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-col> </el-col>
<el-col :span="4">
<el-form :disabled="isReadOnly" :inline="true">
<el-form-item :label="$t('performance_test.cache_script')">
<el-checkbox v-model="cacheScript"/>
</el-form-item>
</el-form>
</el-col>
</el-row> </el-row>
<!-- DNS --> <!-- DNS -->
@ -177,6 +184,30 @@
<el-switch :disabled="isReadOnly || !row.csvSplit" v-model="row.csvHasHeader"/> <el-switch :disabled="isReadOnly || !row.csvSplit" v-model="row.csvHasHeader"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('load_test.csv_file_end_recycle')" align="center" prop="recycle">
<template v-slot:default="{row}">
<el-switch v-model="row.recycle" :disabled="isReadOnly"/>
</template>
</el-table-column>
<el-table-column :label="$t('load_test.csv_file_end_stop_thread')" align="center" prop="stopThread">
<template v-slot:default="{row}">
<el-switch v-model="row.stopThread" :disabled="isReadOnly"/>
</template>
</el-table-column>
<el-table-column :label="$t('load_test.thread_share')" align="center" prop="shareMode">
<template v-slot:default="{row}">
<el-select v-model="row.shareMode" :disabled="isReadOnly">
<el-option key="shareMode.all" :label="$t('load_test.csv_file_end_stop_thread_option.all')"
value="shareMode.all"></el-option>
<el-option key="shareMode.group" :label="$t('load_test.csv_file_end_stop_thread_option.group')"
value="shareMode.group"></el-option>
<el-option key="shareMode.thread" :label="$t('load_test.csv_file_end_stop_thread_option.thread')"
value="shareMode.thread"></el-option>
</el-select>
</template>
</el-table-column>
</el-table> </el-table>
</el-col> </el-col>
</el-row> </el-row>
@ -481,6 +512,7 @@ export default {
csvFiles: [], csvFiles: [],
csvConfig: [], csvConfig: [],
statusCodeStr: '', statusCodeStr: '',
cacheScript: false,
granularity: undefined, granularity: undefined,
granularityData: [ granularityData: [
{start: 0, end: 100, granularity: 1}, {start: 0, end: 100, granularity: 1},
@ -523,7 +555,11 @@ export default {
} }
}, },
csvFiles() { csvFiles() {
this.refreshCsv(); if (this.testId) {
this.getAdvancedConfig();
} else if (this.reportId) {
this.getAdvancedConfig('report');
}
} }
}, },
methods: { methods: {
@ -538,6 +574,7 @@ export default {
this.domains = data.domains || []; this.domains = data.domains || [];
this.params = data.params || []; this.params = data.params || [];
this.granularity = data.granularity; this.granularity = data.granularity;
this.cacheScript = data.cacheScript;
this.monitorParams = data.monitorParams || []; this.monitorParams = data.monitorParams || [];
this.properties = data.properties || []; this.properties = data.properties || [];
this.systemProperties = data.systemProperties || []; this.systemProperties = data.systemProperties || [];
@ -548,8 +585,23 @@ export default {
refreshCsv() { refreshCsv() {
if (this.csvConfig && this.csvFiles) { if (this.csvConfig && this.csvFiles) {
this.csvFiles.forEach(f => { this.csvFiles.forEach(f => {
f.csvSplit = this.csvConfig[f.name]?.csvSplit; f.csvSplit = this.csvConfig[f.name]?.csvSplit
f.csvHasHeader = this.csvConfig[f.name]?.csvHasHeader; f.csvHasHeader = this.csvConfig[f.name]?.csvHasHeader;
f.recycle = this.csvConfig[f.name]?.recycle;
f.stopThread = this.csvConfig[f.name]?.stopThread;
f.shareMode = this.csvConfig[f.name]?.shareMode;
if (f.csvHasHeader === undefined) {
f.csvHasHeader = true;
}
if (f.stopThread === undefined) {
f.stopThread = false;
}
if (f.recycle === undefined) {
f.recycle = true;
}
if (f.shareMode === undefined) {
f.shareMode = "shareMode.thread";
}
}); });
} }
}, },
@ -661,11 +713,18 @@ export default {
properties: this.properties, properties: this.properties,
systemProperties: this.systemProperties, systemProperties: this.systemProperties,
csvConfig: this.csvFiles.reduce((result, curr) => { csvConfig: this.csvFiles.reduce((result, curr) => {
result[curr.name] = {csvHasHeader: curr.csvHasHeader, csvSplit: curr.csvSplit}; result[curr.name] = {
csvHasHeader: curr.csvHasHeader,
csvSplit: curr.csvSplit,
recycle: curr.recycle,
stopThread: curr.stopThread,
shareMode: curr.shareMode
};
return result; return result;
}, {}), }, {}),
domains: this.domains, domains: this.domains,
granularity: this.granularity, granularity: this.granularity,
cacheScript: this.cacheScript,
monitorParams: this.monitorParams monitorParams: this.monitorParams
}; };
}, },

View File

@ -15,6 +15,7 @@ const message = {
error_samples: 'Error samples', error_samples: 'Error samples',
all_samples: 'All samples', all_samples: 'All samples',
response_3_samples: 'The first three pieces of data', response_3_samples: 'The first three pieces of data',
cache_script: 'Cache script',
} }
} }
export default { export default {

View File

@ -15,6 +15,7 @@ const message = {
error_samples: '错误请求', error_samples: '错误请求',
all_samples: '所有请求', all_samples: '所有请求',
response_3_samples: '默认抽样前3个请求的响应数据', response_3_samples: '默认抽样前3个请求的响应数据',
cache_script: '缓存编译脚本',
} }
} }

View File

@ -15,6 +15,7 @@ const message = {
error_samples: '錯誤請求', error_samples: '錯誤請求',
all_samples: '所有請求', all_samples: '所有請求',
response_3_samples: '默认抽样前3个请求的响应数据', response_3_samples: '默认抽样前3个请求的响应数据',
cache_script: '緩存編譯腳本',
} }
} }

View File

@ -37,7 +37,14 @@ export default {
}); });
let csvFiles = []; let csvFiles = [];
for (const f of csvSet) { for (const f of csvSet) {
csvFiles.push({name: f, csvSplit: false, csvHasHeader: true}); csvFiles.push({
name: f,
csvSplit: false,
csvHasHeader: true,
recycle: true,
stopThread: false,
shareMode: "shareMode.thread"
});
} }
this.$refs.advancedConfig.csvFiles = csvFiles; this.$refs.advancedConfig.csvFiles = csvFiles;

View File

@ -175,6 +175,30 @@
<el-switch :disabled="readOnly || !row.csvSplit" v-model="row.csvHasHeader"/> <el-switch :disabled="readOnly || !row.csvSplit" v-model="row.csvHasHeader"/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column :label="$t('load_test.csv_file_end_recycle')" align="center" prop="recycle">
<template v-slot:default="{row}">
<el-switch v-model="row.recycle" :disabled="isReadOnly"/>
</template>
</el-table-column>
<el-table-column :label="$t('load_test.csv_file_end_stop_thread')" align="center" prop="stopThread">
<template v-slot:default="{row}">
<el-switch v-model="row.stopThread" :disabled="isReadOnly"/>
</template>
</el-table-column>
<el-table-column :label="$t('load_test.thread_share')" align="center" prop="shareMode">
<template v-slot:default="{row}">
<el-select v-model="row.shareMode" :disabled="isReadOnly">
<el-option key="shareMode.all" :label="$t('load_test.csv_file_end_stop_thread_option.all')"
value="shareMode.all"></el-option>
<el-option key="shareMode.group" :label="$t('load_test.csv_file_end_stop_thread_option.group')"
value="shareMode.group"></el-option>
<el-option key="shareMode.thread" :label="$t('load_test.csv_file_end_stop_thread_option.thread')"
value="shareMode.thread"></el-option>
</el-select>
</template>
</el-table-column>
</el-table> </el-table>
</el-col> </el-col>
</el-row> </el-row>
@ -439,6 +463,21 @@ export default {
this.csvFiles.forEach(f => { this.csvFiles.forEach(f => {
f.csvSplit = this.csvConfig[f.name]?.csvSplit; f.csvSplit = this.csvConfig[f.name]?.csvSplit;
f.csvHasHeader = this.csvConfig[f.name]?.csvHasHeader; f.csvHasHeader = this.csvConfig[f.name]?.csvHasHeader;
f.recycle = this.csvConfig[f.name]?.recycle;
f.stopThread = this.csvConfig[f.name]?.stopThread;
f.shareMode = this.csvConfig[f.name]?.shareMode;
if (f.csvHasHeader === undefined) {
f.csvHasHeader = true;
}
if (f.stopThread === undefined) {
f.stopThread = false;
}
if (f.recycle === undefined) {
f.recycle = true;
}
if (f.shareMode === undefined) {
f.shareMode = "shareMode.thread";
}
}); });
} }
} }
@ -561,7 +600,13 @@ export default {
params: this.params, params: this.params,
properties: this.properties, properties: this.properties,
csvConfig: this.csvFiles.reduce((result, curr) => { csvConfig: this.csvFiles.reduce((result, curr) => {
result[curr.name] = {csvHasHeader: curr.csvHasHeader, csvSplit: curr.csvSplit}; result[curr.name] = {
csvHasHeader: curr.csvHasHeader,
csvSplit: curr.csvSplit,
recycle: curr.recycle,
stopThread: curr.stopThread,
shareMode: curr.shareMode
};
return result; return result;
}, {}), }, {}),
domains: this.domains, domains: this.domains,

View File

@ -63,7 +63,7 @@ export default {
}); });
let csvFiles = []; let csvFiles = [];
for (const f of csvSet) { for (const f of csvSet) {
csvFiles.push({ name: f, csvSplit: false, csvHasHeader: true }); csvFiles.push({ name: f, csvSplit: false, csvHasHeader: true, recycle: true, stopThread: false, shareMode: "shareMode.thread" });
} }
if (this.$refs.advancedConfig) { if (this.$refs.advancedConfig) {
this.$refs.advancedConfig.csvFiles = csvFiles; this.$refs.advancedConfig.csvFiles = csvFiles;