Merge branch 'master' of https://github.com/metersphere/metersphere
This commit is contained in:
commit
5bd35fa4f1
|
@ -219,7 +219,7 @@
|
|||
<dependency>
|
||||
<groupId>io.metersphere</groupId>
|
||||
<artifactId>jmeter-plugins-dubbo</artifactId>
|
||||
<version>2.7.9</version>
|
||||
<version>2.7.10</version>
|
||||
</dependency>
|
||||
|
||||
<!-- LDAP Module -->
|
||||
|
|
|
@ -135,16 +135,21 @@ public class Swagger2Parser extends ApiImportAbstractParser {
|
|||
simpleRef = refModel.getSimpleRef();
|
||||
}
|
||||
Model model = definitions.get(simpleRef);
|
||||
JSONObject bodyParameters = getBodyJSONObjectParameters(model.getProperties(), definitions);
|
||||
HashSet<String> refSet = new HashSet<>();
|
||||
refSet.add(simpleRef);
|
||||
JSONObject bodyParameters = getBodyJSONObjectParameters(model.getProperties(), definitions, refSet);
|
||||
body.setRaw(bodyParameters.toJSONString());
|
||||
} else if (schema instanceof ArrayModel) {
|
||||
ArrayModel arrayModel = (ArrayModel) bodyParameter.getSchema();
|
||||
Property items = arrayModel.getItems();
|
||||
if (items instanceof RefProperty) {
|
||||
RefProperty refProperty = (RefProperty) items;
|
||||
Model model = definitions.get(refProperty.getSimpleRef());
|
||||
String simpleRef = refProperty.getSimpleRef();
|
||||
HashSet<String> refSet = new HashSet<>();
|
||||
refSet.add(simpleRef);
|
||||
Model model = definitions.get(simpleRef);
|
||||
JSONArray propertyList = new JSONArray();
|
||||
propertyList.add(getBodyJSONObjectParameters(model.getProperties(), definitions));
|
||||
propertyList.add(getBodyJSONObjectParameters(model.getProperties(), definitions, refSet));
|
||||
body.setRaw(propertyList.toString());
|
||||
}
|
||||
}
|
||||
|
@ -152,20 +157,26 @@ public class Swagger2Parser extends ApiImportAbstractParser {
|
|||
body.setFormat("json");
|
||||
}
|
||||
|
||||
private JSONObject getBodyJSONObjectParameters(Map<String, Property> properties, Map<String, Model> definitions) {
|
||||
private JSONObject getBodyJSONObjectParameters(Map<String, Property> properties, Map<String, Model> definitions, HashSet<String> refSet) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
properties.forEach((key, value) -> {
|
||||
if (value instanceof ObjectProperty) {
|
||||
ObjectProperty objectProperty = (ObjectProperty) value;
|
||||
jsonObject.put(key, getBodyJSONObjectParameters(objectProperty.getProperties(), definitions));
|
||||
jsonObject.put(key, getBodyJSONObjectParameters(objectProperty.getProperties(), definitions, refSet));
|
||||
} else if (value instanceof ArrayProperty) {
|
||||
ArrayProperty arrayProperty = (ArrayProperty) value;
|
||||
Property items = arrayProperty.getItems();
|
||||
if (items instanceof RefProperty) {
|
||||
RefProperty refProperty = (RefProperty) items;
|
||||
Model model = definitions.get(refProperty.getSimpleRef());
|
||||
String simpleRef = refProperty.getSimpleRef();
|
||||
if (refSet.contains(simpleRef)) {
|
||||
jsonObject.put(key, new JSONArray());
|
||||
return;
|
||||
}
|
||||
refSet.add(simpleRef);
|
||||
Model model = definitions.get(simpleRef);
|
||||
JSONArray propertyList = new JSONArray();
|
||||
propertyList.add(getBodyJSONObjectParameters(model.getProperties(), definitions));
|
||||
propertyList.add(getBodyJSONObjectParameters(model.getProperties(), definitions, refSet));
|
||||
jsonObject.put(key, propertyList);
|
||||
} else {
|
||||
jsonObject.put(key, new ArrayList<>());
|
||||
|
|
|
@ -15,35 +15,35 @@
|
|||
</el-input>
|
||||
|
||||
<el-button type="primary" plain :disabled="isReadOnly" @click="saveTest">
|
||||
{{$t('commons.save')}}
|
||||
{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
|
||||
<el-button type="primary" plain :disabled="isReadOnly"
|
||||
<el-button type="primary" plain :disabled="isReadOnly"
|
||||
@click="saveRunTest">
|
||||
{{$t('load_test.save_and_run')}}
|
||||
{{ $t('load_test.save_and_run') }}
|
||||
</el-button>
|
||||
|
||||
<!-- <el-button :disabled="isReadOnly" type="primary" plain v-if="isShowRun" @click="runTest">-->
|
||||
<!-- {{$t('api_test.run')}}-->
|
||||
<!-- </el-button>-->
|
||||
<!-- <el-button :disabled="isReadOnly" type="primary" plain v-if="isShowRun" @click="runTest">-->
|
||||
<!-- {{$t('api_test.run')}}-->
|
||||
<!-- </el-button>-->
|
||||
|
||||
<el-button :disabled="isReadOnly" type="warning" plain @click="cancel">{{$t('commons.cancel')}}
|
||||
<el-button :disabled="isReadOnly" type="warning" plain @click="cancel">{{ $t('commons.cancel') }}
|
||||
</el-button>
|
||||
|
||||
<el-dropdown trigger="click" @command="handleCommand">
|
||||
<el-button class="el-dropdown-link more" icon="el-icon-more" plain/>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="report">
|
||||
{{$t('api_report.title')}}
|
||||
{{ $t('api_report.title') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="performance" :disabled="create || isReadOnly">
|
||||
{{$t('api_test.create_performance_test')}}
|
||||
{{ $t('api_test.create_performance_test') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="export" :disabled="isReadOnly || create">
|
||||
{{$t('api_test.export_config')}}
|
||||
{{ $t('api_test.export_config') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="import" :disabled="isReadOnly">
|
||||
{{$t('api_test.api_import.label')}}
|
||||
{{ $t('api_test.api_import.label') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
@ -52,10 +52,12 @@
|
|||
|
||||
<ms-api-report-dialog :test-id="id" ref="reportDialog"/>
|
||||
|
||||
<ms-schedule-config :schedule="test.schedule" :is-read-only="isReadOnly" :save="saveCronExpression" @scheduleChange="saveSchedule" :check-open="checkScheduleEdit"/>
|
||||
<ms-schedule-config :schedule="test.schedule" :is-read-only="isReadOnly" :save="saveCronExpression"
|
||||
@scheduleChange="saveSchedule" :check-open="checkScheduleEdit"/>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<ms-api-scenario-config :debug-report-id="debugReportId" @runDebug="runDebug" :is-read-only="isReadOnly" :scenarios="test.scenarioDefinition" :project-id="test.projectId" ref="config"/>
|
||||
<ms-api-scenario-config :debug-report-id="debugReportId" @runDebug="runDebug" :is-read-only="isReadOnly"
|
||||
:scenarios="test.scenarioDefinition" :project-id="test.projectId" ref="config"/>
|
||||
</el-container>
|
||||
</el-card>
|
||||
</div>
|
||||
|
@ -63,274 +65,279 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import MsApiScenarioConfig from "./components/ApiScenarioConfig";
|
||||
import {Test} from "./model/ScenarioModel"
|
||||
import MsApiReportStatus from "../report/ApiReportStatus";
|
||||
import MsApiReportDialog from "./ApiReportDialog";
|
||||
import {checkoutTestManagerOrTestUser, downloadFile} from "@/common/js/utils";
|
||||
import MsScheduleConfig from "../../common/components/MsScheduleConfig";
|
||||
import ApiImport from "./components/import/ApiImport";
|
||||
import {getUUID} from "../../../../common/js/utils";
|
||||
import MsApiScenarioConfig from "./components/ApiScenarioConfig";
|
||||
import {Test} from "./model/ScenarioModel"
|
||||
import MsApiReportStatus from "../report/ApiReportStatus";
|
||||
import MsApiReportDialog from "./ApiReportDialog";
|
||||
import {checkoutTestManagerOrTestUser, downloadFile} from "@/common/js/utils";
|
||||
import MsScheduleConfig from "../../common/components/MsScheduleConfig";
|
||||
import ApiImport from "./components/import/ApiImport";
|
||||
import {getUUID} from "../../../../common/js/utils";
|
||||
import {ApiEvent, LIST_CHANGE} from "@/business/components/common/head/ListEvent";
|
||||
|
||||
export default {
|
||||
name: "MsApiTestConfig",
|
||||
export default {
|
||||
name: "MsApiTestConfig",
|
||||
|
||||
components: {ApiImport, MsScheduleConfig, MsApiReportDialog, MsApiReportStatus, MsApiScenarioConfig},
|
||||
components: {ApiImport, MsScheduleConfig, MsApiReportDialog, MsApiReportStatus, MsApiScenarioConfig},
|
||||
|
||||
props: ["id"],
|
||||
props: ["id"],
|
||||
|
||||
data() {
|
||||
return {
|
||||
reportVisible: false,
|
||||
create: false,
|
||||
result: {},
|
||||
projects: [],
|
||||
change: false,
|
||||
test: new Test(),
|
||||
isReadOnly: false,
|
||||
debugReportId: ''
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
'$route': 'init',
|
||||
test: {
|
||||
handler: function () {
|
||||
this.change = true;
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
init() {
|
||||
let projectId;
|
||||
|
||||
this.isReadOnly = !checkoutTestManagerOrTestUser();
|
||||
|
||||
if (this.id) {
|
||||
this.create = false;
|
||||
this.getTest(this.id);
|
||||
} else {
|
||||
this.create = true;
|
||||
this.test = new Test();
|
||||
if (this.$refs.config) {
|
||||
this.$refs.config.reset();
|
||||
}
|
||||
// 仅创建时获取选择的项目
|
||||
projectId = this.$store.state.common.projectId;
|
||||
}
|
||||
this.result = this.$get("/project/listAll", response => {
|
||||
this.projects = response.data;
|
||||
// 等待项目列表加载完
|
||||
if (projectId) this.test.projectId = projectId;
|
||||
})
|
||||
},
|
||||
getTest(id) {
|
||||
this.result = this.$get("/api/get/" + id, response => {
|
||||
if (response.data) {
|
||||
let item = response.data;
|
||||
|
||||
this.test = new Test({
|
||||
id: item.id,
|
||||
projectId: item.projectId,
|
||||
name: item.name,
|
||||
status: item.status,
|
||||
scenarioDefinition: JSON.parse(item.scenarioDefinition),
|
||||
schedule: item.schedule ? item.schedule : {},
|
||||
});
|
||||
this.$refs.config.reset();
|
||||
}
|
||||
});
|
||||
},
|
||||
save(callback) {
|
||||
let validator = this.test.isValid();
|
||||
if (!validator.isValid) {
|
||||
this.$warning(this.$t(validator.info));
|
||||
return;
|
||||
}
|
||||
this.change = false;
|
||||
let bodyFiles = this.getBodyUploadFiles();
|
||||
let url = this.create ? "/api/create" : "/api/update";
|
||||
let jmx = this.test.toJMX();
|
||||
let blob = new Blob([jmx.xml], {type: "application/octet-stream"});
|
||||
let file = new File([blob], jmx.name);
|
||||
this.result = this.$fileUpload(url, file, bodyFiles, this.test,response => {
|
||||
if (callback) callback();
|
||||
this.create = false;
|
||||
this.resetBodyFile();
|
||||
});
|
||||
},
|
||||
saveTest() {
|
||||
this.save(() => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
if (this.create) {
|
||||
this.$router.push({
|
||||
path: '/api/test/edit?id=' + this.test.id
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
runTest() {
|
||||
this.result = this.$post("/api/run", {id: this.test.id, triggerMode: 'MANUAL'}, (response) => {
|
||||
this.$success(this.$t('api_test.running'));
|
||||
this.$router.push({
|
||||
path: '/api/report/view/' + response.data
|
||||
})
|
||||
});
|
||||
},
|
||||
saveRunTest() {
|
||||
this.change = false;
|
||||
|
||||
this.save(() => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.runTest();
|
||||
})
|
||||
},
|
||||
getBodyUploadFiles() {
|
||||
let bodyUploadFiles = [];
|
||||
this.test.bodyUploadIds = [];
|
||||
this.test.scenarioDefinition.forEach(scenario => {
|
||||
scenario.requests.forEach(request => {
|
||||
if (request.body) {
|
||||
request.body.kvs.forEach( param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
let fileId = getUUID().substring(0, 8);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
this.test.bodyUploadIds.push(fileId);
|
||||
bodyUploadFiles.push(item.file);
|
||||
// item.file = undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
return bodyUploadFiles;
|
||||
},
|
||||
resetBodyFile() {
|
||||
//下次保存不再上传已传文件
|
||||
this.test.scenarioDefinition.forEach(scenario => {
|
||||
scenario.requests.forEach(request => {
|
||||
if (request.body) {
|
||||
request.body.kvs.forEach( param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
item.file = undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
cancel() {
|
||||
this.$router.push('/api/test/list/all');
|
||||
},
|
||||
handleCommand(command) {
|
||||
switch (command) {
|
||||
case "report":
|
||||
this.$refs.reportDialog.open();
|
||||
break;
|
||||
case "performance":
|
||||
this.$store.commit('setTest', {
|
||||
projectId: this.test.projectId,
|
||||
name: this.test.name,
|
||||
jmx: this.test.toJMX()
|
||||
})
|
||||
this.$router.push({
|
||||
path: "/performance/test/create"
|
||||
})
|
||||
break;
|
||||
case "export":
|
||||
downloadFile(this.test.name + ".json", this.test.export());
|
||||
break;
|
||||
case "import":
|
||||
this.$refs.apiImport.open();
|
||||
break;
|
||||
}
|
||||
},
|
||||
saveCronExpression(cronExpression) {
|
||||
this.test.schedule.enable = true;
|
||||
this.test.schedule.value = cronExpression;
|
||||
this.saveSchedule();
|
||||
},
|
||||
saveSchedule() {
|
||||
this.checkScheduleEdit();
|
||||
let param = {};
|
||||
param = this.test.schedule;
|
||||
param.resourceId = this.test.id;
|
||||
let url = '/api/schedule/create';
|
||||
if (param.id) {
|
||||
url = '/api/schedule/update';
|
||||
}
|
||||
this.$post(url, param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.getTest(this.test.id);
|
||||
});
|
||||
},
|
||||
checkScheduleEdit() {
|
||||
if (this.create) {
|
||||
this.$message(this.$t('api_test.environment.please_save_test'));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
runDebug(scenario) {
|
||||
if (this.create) {
|
||||
this.$warning(this.$t('api_test.environment.please_save_test'));
|
||||
return;
|
||||
}
|
||||
|
||||
let url = "/api/run/debug";
|
||||
let runningTest = new Test();
|
||||
Object.assign(runningTest, this.test);
|
||||
runningTest.scenarioDefinition = [];
|
||||
runningTest.scenarioDefinition.push(scenario);
|
||||
let validator = runningTest.isValid();
|
||||
if (!validator.isValid) {
|
||||
this.$warning(this.$t(validator.info));
|
||||
return;
|
||||
}
|
||||
|
||||
let jmx = runningTest.toJMX();
|
||||
let blob = new Blob([jmx.xml], {type: "application/octet-stream"});
|
||||
let file = new File([blob], jmx.name);
|
||||
this.$fileUpload(url, file, null, this.test,response => {
|
||||
this.debugReportId = response.data;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.init();
|
||||
data() {
|
||||
return {
|
||||
reportVisible: false,
|
||||
create: false,
|
||||
result: {},
|
||||
projects: [],
|
||||
change: false,
|
||||
test: new Test(),
|
||||
isReadOnly: false,
|
||||
debugReportId: ''
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
'$route': 'init',
|
||||
test: {
|
||||
handler: function () {
|
||||
this.change = true;
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
init() {
|
||||
let projectId;
|
||||
|
||||
this.isReadOnly = !checkoutTestManagerOrTestUser();
|
||||
|
||||
if (this.id) {
|
||||
this.create = false;
|
||||
this.getTest(this.id);
|
||||
} else {
|
||||
this.create = true;
|
||||
this.test = new Test();
|
||||
if (this.$refs.config) {
|
||||
this.$refs.config.reset();
|
||||
}
|
||||
// 仅创建时获取选择的项目
|
||||
projectId = this.$store.state.common.projectId;
|
||||
}
|
||||
this.result = this.$get("/project/listAll", response => {
|
||||
this.projects = response.data;
|
||||
// 等待项目列表加载完
|
||||
if (projectId) this.test.projectId = projectId;
|
||||
})
|
||||
},
|
||||
getTest(id) {
|
||||
this.result = this.$get("/api/get/" + id, response => {
|
||||
if (response.data) {
|
||||
let item = response.data;
|
||||
|
||||
this.test = new Test({
|
||||
id: item.id,
|
||||
projectId: item.projectId,
|
||||
name: item.name,
|
||||
status: item.status,
|
||||
scenarioDefinition: JSON.parse(item.scenarioDefinition),
|
||||
schedule: item.schedule ? item.schedule : {},
|
||||
});
|
||||
this.$refs.config.reset();
|
||||
}
|
||||
});
|
||||
},
|
||||
save(callback) {
|
||||
let validator = this.test.isValid();
|
||||
if (!validator.isValid) {
|
||||
this.$warning(this.$t(validator.info));
|
||||
return;
|
||||
}
|
||||
this.change = false;
|
||||
let bodyFiles = this.getBodyUploadFiles();
|
||||
let url = this.create ? "/api/create" : "/api/update";
|
||||
let jmx = this.test.toJMX();
|
||||
let blob = new Blob([jmx.xml], {type: "application/octet-stream"});
|
||||
let file = new File([blob], jmx.name);
|
||||
this.result = this.$fileUpload(url, file, bodyFiles, this.test, response => {
|
||||
if (callback) callback();
|
||||
this.create = false;
|
||||
this.resetBodyFile();
|
||||
});
|
||||
},
|
||||
saveTest() {
|
||||
this.save(() => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
if (this.create) {
|
||||
this.$router.push({
|
||||
path: '/api/test/edit?id=' + this.test.id
|
||||
})
|
||||
}
|
||||
// 发送广播,刷新 head 上的最新列表
|
||||
ApiEvent.$emit(LIST_CHANGE);
|
||||
})
|
||||
},
|
||||
runTest() {
|
||||
this.result = this.$post("/api/run", {id: this.test.id, triggerMode: 'MANUAL'}, (response) => {
|
||||
this.$success(this.$t('api_test.running'));
|
||||
this.$router.push({
|
||||
path: '/api/report/view/' + response.data
|
||||
})
|
||||
});
|
||||
},
|
||||
saveRunTest() {
|
||||
this.change = false;
|
||||
|
||||
this.save(() => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.runTest();
|
||||
// 发送广播,刷新 head 上的最新列表
|
||||
ApiEvent.$emit(LIST_CHANGE);
|
||||
})
|
||||
},
|
||||
getBodyUploadFiles() {
|
||||
let bodyUploadFiles = [];
|
||||
this.test.bodyUploadIds = [];
|
||||
this.test.scenarioDefinition.forEach(scenario => {
|
||||
scenario.requests.forEach(request => {
|
||||
if (request.body) {
|
||||
request.body.kvs.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
let fileId = getUUID().substring(0, 8);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
this.test.bodyUploadIds.push(fileId);
|
||||
bodyUploadFiles.push(item.file);
|
||||
// item.file = undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
return bodyUploadFiles;
|
||||
},
|
||||
resetBodyFile() {
|
||||
//下次保存不再上传已传文件
|
||||
this.test.scenarioDefinition.forEach(scenario => {
|
||||
scenario.requests.forEach(request => {
|
||||
if (request.body) {
|
||||
request.body.kvs.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
item.file = undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
cancel() {
|
||||
this.$router.push('/api/test/list/all');
|
||||
},
|
||||
handleCommand(command) {
|
||||
switch (command) {
|
||||
case "report":
|
||||
this.$refs.reportDialog.open();
|
||||
break;
|
||||
case "performance":
|
||||
this.$store.commit('setTest', {
|
||||
projectId: this.test.projectId,
|
||||
name: this.test.name,
|
||||
jmx: this.test.toJMX()
|
||||
})
|
||||
this.$router.push({
|
||||
path: "/performance/test/create"
|
||||
})
|
||||
break;
|
||||
case "export":
|
||||
downloadFile(this.test.name + ".json", this.test.export());
|
||||
break;
|
||||
case "import":
|
||||
this.$refs.apiImport.open();
|
||||
break;
|
||||
}
|
||||
},
|
||||
saveCronExpression(cronExpression) {
|
||||
this.test.schedule.enable = true;
|
||||
this.test.schedule.value = cronExpression;
|
||||
this.saveSchedule();
|
||||
},
|
||||
saveSchedule() {
|
||||
this.checkScheduleEdit();
|
||||
let param = {};
|
||||
param = this.test.schedule;
|
||||
param.resourceId = this.test.id;
|
||||
let url = '/api/schedule/create';
|
||||
if (param.id) {
|
||||
url = '/api/schedule/update';
|
||||
}
|
||||
this.$post(url, param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.getTest(this.test.id);
|
||||
});
|
||||
},
|
||||
checkScheduleEdit() {
|
||||
if (this.create) {
|
||||
this.$message(this.$t('api_test.environment.please_save_test'));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
runDebug(scenario) {
|
||||
if (this.create) {
|
||||
this.$warning(this.$t('api_test.environment.please_save_test'));
|
||||
return;
|
||||
}
|
||||
|
||||
let url = "/api/run/debug";
|
||||
let runningTest = new Test();
|
||||
Object.assign(runningTest, this.test);
|
||||
runningTest.scenarioDefinition = [];
|
||||
runningTest.scenarioDefinition.push(scenario);
|
||||
let validator = runningTest.isValid();
|
||||
if (!validator.isValid) {
|
||||
this.$warning(this.$t(validator.info));
|
||||
return;
|
||||
}
|
||||
|
||||
let jmx = runningTest.toJMX();
|
||||
let blob = new Blob([jmx.xml], {type: "application/octet-stream"});
|
||||
let file = new File([blob], jmx.name);
|
||||
this.$fileUpload(url, file, null, this.test, response => {
|
||||
this.debugReportId = response.data;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.test-container {
|
||||
height: calc(100vh - 150px);
|
||||
min-height: 600px;
|
||||
}
|
||||
.test-container {
|
||||
height: calc(100vh - 150px);
|
||||
min-height: 600px;
|
||||
}
|
||||
|
||||
.test-name {
|
||||
width: 600px;
|
||||
margin-left: -20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.test-name {
|
||||
width: 600px;
|
||||
margin-left: -20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.test-project {
|
||||
min-width: 150px;
|
||||
}
|
||||
.test-project {
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
.test-container .more {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.test-container .more {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
import MsApiScenarioConfig from "./components/ApiScenarioConfig";
|
||||
import MsApiReportStatus from "../report/ApiReportStatus";
|
||||
import MsApiReportDialog from "./ApiReportDialog";
|
||||
import {getUUID} from "../../../../common/js/utils";
|
||||
|
||||
|
||||
export default {
|
||||
|
@ -116,7 +117,6 @@
|
|||
let item = response.data;
|
||||
this.tests.push(item);
|
||||
let test = new Test({
|
||||
id: item.id,
|
||||
projectId: item.projectId,
|
||||
name: this.ruleForm.testName,
|
||||
scenarioDefinition: JSON.parse(item.scenarioDefinition),
|
||||
|
@ -142,10 +142,36 @@
|
|||
save(callback) {
|
||||
this.change = false;
|
||||
let url = "/api/create";
|
||||
this.result = this.$request(this.getOptions(url), () => {
|
||||
let bodyFiles = this.getBodyUploadFiles();
|
||||
this.result = this.$request(this.getOptions(url, bodyFiles), () => {
|
||||
if (callback) callback();
|
||||
});
|
||||
},
|
||||
getBodyUploadFiles() {
|
||||
let bodyUploadFiles = [];
|
||||
this.test.bodyUploadIds = [];
|
||||
this.test.scenarioDefinition.forEach(scenario => {
|
||||
scenario.requests.forEach(request => {
|
||||
if (request.body) {
|
||||
request.body.kvs.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
let fileId = getUUID().substring(0, 8);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
this.test.bodyUploadIds.push(fileId);
|
||||
bodyUploadFiles.push(item.file);
|
||||
// item.file = undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
return bodyUploadFiles;
|
||||
},
|
||||
runTest() {
|
||||
this.result = this.$post("/api/run", {id: this.test.id, triggerMode: 'MANUAL'}, (response) => {
|
||||
this.$success(this.$t('api_test.running'));
|
||||
|
@ -155,12 +181,19 @@
|
|||
this.test = ""
|
||||
});
|
||||
},
|
||||
getOptions(url) {
|
||||
getOptions(url, bodyFiles) {
|
||||
|
||||
let formData = new FormData();
|
||||
if (bodyFiles) {
|
||||
bodyFiles.forEach(f => {
|
||||
formData.append("files", f);
|
||||
})
|
||||
}
|
||||
let requestJson = JSON.stringify(this.test);
|
||||
formData.append('request', new Blob([requestJson], {
|
||||
type: "application/json"
|
||||
}));
|
||||
|
||||
let jmx = this.test.toJMX();
|
||||
let blob = new Blob([jmx.xml], {type: "application/octet-stream"});
|
||||
formData.append("file", new File([blob], jmx.name));
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
<el-form :model="request" ref="request" label-width="100px">
|
||||
|
||||
<el-form-item :label="$t('api_test.request.connect_timeout')" prop="connectTimeout">
|
||||
<el-input-number size="small" :disabled="isReadOnly" v-model="request.connectTimeout" :placeholder="$t('commons.millisecond')" :maxlength="1000*10000000" />
|
||||
<el-input-number size="small" :disabled="isReadOnly" v-model="request.connectTimeout" :placeholder="$t('commons.millisecond')" :max="1000*10000000" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('api_test.request.response_timeout')" prop="responseTimeout">
|
||||
<el-input-number size="small" :disabled="isReadOnly" v-model="request.responseTimeout" :placeholder="$t('commons.millisecond')" :maxlength="1000*10000000"/>
|
||||
<el-input-number size="small" :disabled="isReadOnly" v-model="request.responseTimeout" :placeholder="$t('commons.millisecond')" :max="1000*10000000"/>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<el-col :span="4" class="script-index">
|
||||
<div class="template-title">{{$t('api_test.request.processor.code_template')}}</div>
|
||||
<div v-for="(template, index) in codeTemplates" :key="index" class="code-template">
|
||||
<el-link @click="addTemplate(template)">{{template.title}}</el-link>
|
||||
<el-link :disabled="template.disabled" @click="addTemplate(template)">{{template.title}}</el-link>
|
||||
</div>
|
||||
<div class="document-url">
|
||||
<el-link href="https://jmeter.apache.org/usermanual/component_reference.html#BeanShell_PostProcessor" type="primary">{{$t('commons.reference_documentation')}}</el-link>
|
||||
|
@ -29,23 +29,26 @@
|
|||
codeTemplates: [
|
||||
{
|
||||
title: this.$t('api_test.request.processor.code_template_get_variable'),
|
||||
value: 'vars.get("variable_name");'
|
||||
value: 'vars.get("variable_name");',
|
||||
},
|
||||
{
|
||||
title: this.$t('api_test.request.processor.code_template_set_variable'),
|
||||
value: 'vars.put("variable_name", "variable_value");'
|
||||
value: 'vars.put("variable_name", "variable_value");',
|
||||
},
|
||||
{
|
||||
title: this.$t('api_test.request.processor.code_template_get_response_header'),
|
||||
value: 'prev.getResponseHeaders();'
|
||||
value: 'prev.getResponseHeaders();',
|
||||
disabled: this.isPreProcessor
|
||||
},
|
||||
{
|
||||
title: this.$t('api_test.request.processor.code_template_get_response_code'),
|
||||
value: 'prev.getResponseCode();'
|
||||
value: 'prev.getResponseCode();',
|
||||
disabled: this.isPreProcessor
|
||||
},
|
||||
{
|
||||
title: this.$t('api_test.request.processor.code_template_get_response_result'),
|
||||
value: 'prev.getResponseDataAsString();'
|
||||
value: 'prev.getResponseDataAsString();',
|
||||
disabled: this.isPreProcessor
|
||||
}
|
||||
],
|
||||
isCodeEditAlive: true
|
||||
|
@ -61,6 +64,10 @@
|
|||
},
|
||||
beanShellProcessor: {
|
||||
type: Object,
|
||||
},
|
||||
isPreProcessor: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
<ms-api-extract :is-read-only="isReadOnly" :extract="request.extract"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('api_test.request.processor.pre_exec_script')" name="beanShellPreProcessor">
|
||||
<ms-bean-shell-processor :is-read-only="isReadOnly" :bean-shell-processor="request.beanShellPreProcessor"/>
|
||||
<ms-bean-shell-processor :is-pre-processor="true" :is-read-only="isReadOnly" :bean-shell-processor="request.beanShellPreProcessor"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('api_test.request.processor.post_exec_script')" name="beanShellPostProcessor">
|
||||
<ms-bean-shell-processor :is-read-only="isReadOnly" :bean-shell-processor="request.beanShellPostProcessor"/>
|
||||
|
|
|
@ -749,13 +749,15 @@ class JMXHttpRequest {
|
|||
|
||||
getPostQueryParameters(request, path) {
|
||||
if (this.method.toUpperCase() !== "GET") {
|
||||
path += '?';
|
||||
let parameters = [];
|
||||
request.parameters.forEach(parameter => {
|
||||
if (parameter.name && parameter.value) {
|
||||
parameters.push(parameter);
|
||||
}
|
||||
});
|
||||
if (parameters.length > 0) {
|
||||
path += '?';
|
||||
}
|
||||
for (let i = 0; i < parameters.length; i++) {
|
||||
let parameter = parameters[i];
|
||||
path += (parameter.name + '=' + parameter.value);
|
||||
|
@ -942,7 +944,7 @@ class JMXGenerator {
|
|||
|
||||
addBodyFormat(request) {
|
||||
let bodyFormat = request.body.format;
|
||||
if (bodyFormat) {
|
||||
if (!request.body.isKV() && bodyFormat) {
|
||||
switch (bodyFormat) {
|
||||
case BODY_FORMAT.JSON:
|
||||
this.addContentType(request, 'application/json');
|
||||
|
|
|
@ -72,7 +72,8 @@
|
|||
format() {
|
||||
if (this.mode === 'json') {
|
||||
try {
|
||||
this.formatData = JSON.stringify(JSON.parse(this.data), null, '\t');
|
||||
var JSONbigString = require('json-bigint')({"storeAsString": true});
|
||||
this.formatData = JSON.stringify(JSONbigString.parse(this.data), null, '\t');
|
||||
} catch (e) {
|
||||
if (this.data) {
|
||||
this.formatData = this.data;
|
||||
|
|
|
@ -60,6 +60,7 @@ import MsContainer from "../../common/components/MsContainer";
|
|||
import MsMainContainer from "../../common/components/MsMainContainer";
|
||||
import {checkoutTestManagerOrTestUser} from "../../../../common/js/utils";
|
||||
import MsScheduleConfig from "../../common/components/MsScheduleConfig";
|
||||
import {LIST_CHANGE, PerformanceEvent} from "@/business/components/common/head/ListEvent";
|
||||
|
||||
export default {
|
||||
name: "EditPerformanceTestPlan",
|
||||
|
@ -172,6 +173,8 @@ export default {
|
|||
this.$success(this.$t('commons.save_success'));
|
||||
this.$refs.advancedConfig.cancelAllEdit();
|
||||
this.$router.push({path: '/performance/test/all'})
|
||||
// 发送广播,刷新 head 上的最新列表
|
||||
PerformanceEvent.$emit(LIST_CHANGE);
|
||||
});
|
||||
},
|
||||
saveAndRun() {
|
||||
|
@ -187,6 +190,8 @@ export default {
|
|||
this.result = this.$post(this.runPath, {id: this.testPlan.id, triggerMode: 'MANUAL'}, (response) => {
|
||||
let reportId = response.data;
|
||||
this.$router.push({path: '/performance/report/view/' + reportId})
|
||||
// 发送广播,刷新 head 上的最新列表
|
||||
PerformanceEvent.$emit(LIST_CHANGE);
|
||||
})
|
||||
});
|
||||
},
|
||||
|
|
|
@ -286,4 +286,8 @@ export default {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 0 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
<el-table-column prop="description" :label="$t('commons.description')"/>
|
||||
<el-table-column :label="$t('commons.member')">
|
||||
<template v-slot:default="scope">
|
||||
<el-button type="text" class="member-size" @click="cellClick(scope.row)">{{scope.row.memberSize}}
|
||||
</el-button>
|
||||
<el-link type="primary" class="member-size" @click="cellClick(scope.row)">
|
||||
{{ scope.row.memberSize }}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.operating')">
|
||||
|
@ -27,7 +28,8 @@
|
|||
</el-card>
|
||||
|
||||
<!-- dialog of organization member -->
|
||||
<el-dialog :visible.sync="dialogOrgMemberVisible" width="70%" :destroy-on-close="true" @close="closeFunc" class="dialog-css">
|
||||
<el-dialog :visible.sync="dialogOrgMemberVisible" width="70%" :destroy-on-close="true" @close="closeFunc"
|
||||
class="dialog-css">
|
||||
<ms-table-header :condition.sync="dialogCondition" @create="addMember" @search="dialogSearch"
|
||||
:create-tip="$t('member.create')" :title="$t('commons.member')"/>
|
||||
<!-- organization member table -->
|
||||
|
@ -43,7 +45,8 @@
|
|||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.operating')">
|
||||
<template v-slot:default="scope">
|
||||
<ms-table-operator :tip2="$t('commons.remove')" @editClick="editMember(scope.row)" @deleteClick="delMember(scope.row)"/>
|
||||
<ms-table-operator :tip2="$t('commons.remove')" @editClick="editMember(scope.row)"
|
||||
@deleteClick="delMember(scope.row)"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -146,7 +149,8 @@
|
|||
<el-form-item :label="$t('commons.phone')" prop="phone">
|
||||
<el-input v-model="memberForm.phone" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.role')" prop="roleIds" :rules="{required: true, message: $t('role.please_choose_role'), trigger: 'change'}">
|
||||
<el-form-item :label="$t('commons.role')" prop="roleIds"
|
||||
:rules="{required: true, message: $t('role.please_choose_role'), trigger: 'change'}">
|
||||
<el-select v-model="memberForm.roleIds" multiple :placeholder="$t('role.please_choose_role')"
|
||||
class="select-width">
|
||||
<el-option
|
||||
|
@ -171,333 +175,331 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import MsCreateBox from "../CreateBox";
|
||||
import MsTablePagination from "../../common/pagination/TablePagination";
|
||||
import MsTableHeader from "../../common/components/MsTableHeader";
|
||||
import MsRolesTag from "../../common/components/MsRolesTag";
|
||||
import MsTableOperator from "../../common/components/MsTableOperator";
|
||||
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
|
||||
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||
import {
|
||||
getCurrentOrganizationId,
|
||||
getCurrentUser, listenGoBack,
|
||||
refreshSessionAndCookies,
|
||||
removeGoBackListener
|
||||
} from "../../../../common/js/utils";
|
||||
import {DEFAULT, ORGANIZATION} from "../../../../common/js/constants";
|
||||
import MsDeleteConfirm from "../../common/components/MsDeleteConfirm";
|
||||
import MsCreateBox from "../CreateBox";
|
||||
import MsTablePagination from "../../common/pagination/TablePagination";
|
||||
import MsTableHeader from "../../common/components/MsTableHeader";
|
||||
import MsRolesTag from "../../common/components/MsRolesTag";
|
||||
import MsTableOperator from "../../common/components/MsTableOperator";
|
||||
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
|
||||
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||
import {
|
||||
getCurrentOrganizationId,
|
||||
getCurrentUser,
|
||||
listenGoBack,
|
||||
refreshSessionAndCookies,
|
||||
removeGoBackListener
|
||||
} from "@/common/js/utils";
|
||||
import {DEFAULT, ORGANIZATION} from "@/common/js/constants";
|
||||
import MsDeleteConfirm from "../../common/components/MsDeleteConfirm";
|
||||
|
||||
export default {
|
||||
name: "MsOrganization",
|
||||
components: {
|
||||
MsDeleteConfirm,
|
||||
MsCreateBox,
|
||||
MsTablePagination,
|
||||
MsTableHeader,
|
||||
MsRolesTag,
|
||||
MsTableOperator,
|
||||
MsDialogFooter,
|
||||
MsTableOperatorButton
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
queryPath: '/organization/list',
|
||||
deletePath: '/organization/delete/',
|
||||
createPath: '/organization/add',
|
||||
updatePath: '/organization/update',
|
||||
result: {},
|
||||
dialogOrgAddVisible: false,
|
||||
dialogOrgUpdateVisible: false,
|
||||
dialogOrgMemberVisible: false,
|
||||
dialogOrgMemberAddVisible: false,
|
||||
dialogOrgMemberUpdateVisible: false,
|
||||
multipleSelection: [],
|
||||
currentPage: 1,
|
||||
pageSize: 5,
|
||||
total: 0,
|
||||
dialogCurrentPage: 1,
|
||||
dialogPageSize: 5,
|
||||
dialogTotal: 0,
|
||||
currentRow: {},
|
||||
condition: {},
|
||||
dialogCondition: {},
|
||||
tableData: [],
|
||||
memberLineData: [],
|
||||
form: {},
|
||||
memberForm: {},
|
||||
rule: {
|
||||
name: [
|
||||
{required: true, message: this.$t('organization.input_name'), trigger: 'blur'},
|
||||
{min: 2, max: 25, message: this.$t('commons.input_limit', [2, 25]), trigger: 'blur'},
|
||||
{
|
||||
required: true,
|
||||
pattern: /^[\u4e00-\u9fa5_a-zA-Z0-9.·-]+$/,
|
||||
message: this.$t('organization.special_characters_are_not_supported'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
description: [
|
||||
{max: 50, message: this.$t('commons.input_limit', [0, 50]), trigger: 'blur'}
|
||||
]
|
||||
},
|
||||
orgMemberRule: {
|
||||
userIds: [
|
||||
{required: true, message: this.$t('member.please_choose_member'), trigger: ['blur']}
|
||||
],
|
||||
roleIds: [
|
||||
{required: true, message: this.$t('role.please_choose_role'), trigger: ['blur']}
|
||||
]
|
||||
}
|
||||
export default {
|
||||
name: "MsOrganization",
|
||||
components: {
|
||||
MsDeleteConfirm,
|
||||
MsCreateBox,
|
||||
MsTablePagination,
|
||||
MsTableHeader,
|
||||
MsRolesTag,
|
||||
MsTableOperator,
|
||||
MsDialogFooter,
|
||||
MsTableOperatorButton
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
queryPath: '/organization/list',
|
||||
deletePath: '/organization/delete/',
|
||||
createPath: '/organization/add',
|
||||
updatePath: '/organization/update',
|
||||
result: {},
|
||||
dialogOrgAddVisible: false,
|
||||
dialogOrgUpdateVisible: false,
|
||||
dialogOrgMemberVisible: false,
|
||||
dialogOrgMemberAddVisible: false,
|
||||
dialogOrgMemberUpdateVisible: false,
|
||||
multipleSelection: [],
|
||||
currentPage: 1,
|
||||
pageSize: 5,
|
||||
total: 0,
|
||||
dialogCurrentPage: 1,
|
||||
dialogPageSize: 5,
|
||||
dialogTotal: 0,
|
||||
currentRow: {},
|
||||
condition: {},
|
||||
dialogCondition: {},
|
||||
tableData: [],
|
||||
memberLineData: [],
|
||||
form: {},
|
||||
memberForm: {},
|
||||
rule: {
|
||||
name: [
|
||||
{required: true, message: this.$t('organization.input_name'), trigger: 'blur'},
|
||||
{min: 2, max: 25, message: this.$t('commons.input_limit', [2, 25]), trigger: 'blur'},
|
||||
{
|
||||
required: true,
|
||||
pattern: /^[\u4e00-\u9fa5_a-zA-Z0-9.·-]+$/,
|
||||
message: this.$t('organization.special_characters_are_not_supported'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
description: [
|
||||
{max: 50, message: this.$t('commons.input_limit', [0, 50]), trigger: 'blur'}
|
||||
]
|
||||
},
|
||||
orgMemberRule: {
|
||||
userIds: [
|
||||
{required: true, message: this.$t('member.please_choose_member'), trigger: ['blur']}
|
||||
],
|
||||
roleIds: [
|
||||
{required: true, message: this.$t('role.please_choose_role'), trigger: ['blur']}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
activated() {
|
||||
this.initTableData();
|
||||
},
|
||||
methods: {
|
||||
create() {
|
||||
this.dialogOrgAddVisible = true;
|
||||
listenGoBack(this.closeFunc);
|
||||
},
|
||||
activated() {
|
||||
this.initTableData();
|
||||
addMember() {
|
||||
this.dialogOrgMemberAddVisible = true;
|
||||
this.memberForm = {};
|
||||
this.result = this.$get('/user/list/', response => {
|
||||
this.$set(this.memberForm, "userList", response.data);
|
||||
});
|
||||
this.result = this.$get('/role/list/org', response => {
|
||||
this.$set(this.memberForm, "roles", response.data);
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
create() {
|
||||
this.dialogOrgAddVisible = true;
|
||||
listenGoBack(this.closeFunc);
|
||||
},
|
||||
addMember() {
|
||||
this.dialogOrgMemberAddVisible = true;
|
||||
this.memberForm = {};
|
||||
this.result = this.$get('/user/list/', response => {
|
||||
this.$set(this.memberForm, "userList", response.data);
|
||||
});
|
||||
this.result = this.$get('/role/list/org', response => {
|
||||
this.$set(this.memberForm, "roles", response.data);
|
||||
})
|
||||
},
|
||||
edit(row) {
|
||||
this.dialogOrgUpdateVisible = true;
|
||||
this.form = Object.assign({}, row);
|
||||
listenGoBack(this.closeFunc);
|
||||
},
|
||||
editMember(row) {
|
||||
this.dialogOrgMemberUpdateVisible = true;
|
||||
this.memberForm = Object.assign({}, row);
|
||||
let roleIds = this.memberForm.roles.map(r => r.id);
|
||||
this.result = this.$get('/role/list/org', response => {
|
||||
this.$set(this.memberForm, "allroles", response.data);
|
||||
})
|
||||
// 编辑时填充角色信息
|
||||
this.$set(this.memberForm, 'roleIds', roleIds);
|
||||
listenGoBack(this.closeFunc);
|
||||
},
|
||||
cellClick(row) {
|
||||
// 保存当前点击的组织信息到currentRow
|
||||
this.currentRow = row;
|
||||
this.dialogOrgMemberVisible = true;
|
||||
let param = {
|
||||
name: '',
|
||||
organizationId: row.id
|
||||
};
|
||||
let path = "/user/special/org/member/list";
|
||||
this.result = this.$post(path + "/" + this.dialogCurrentPage + "/" + this.dialogPageSize, param, res => {
|
||||
let data = res.data;
|
||||
this.memberLineData = data.listObject;
|
||||
let url = "/userrole/list/org/" + row.id;
|
||||
for (let i = 0; i < this.memberLineData.length; i++) {
|
||||
this.$get(url + "/" + encodeURIComponent(this.memberLineData[i].id), response => {
|
||||
let roles = response.data;
|
||||
this.$set(this.memberLineData[i], "roles", roles);
|
||||
})
|
||||
edit(row) {
|
||||
this.dialogOrgUpdateVisible = true;
|
||||
this.form = Object.assign({}, row);
|
||||
listenGoBack(this.closeFunc);
|
||||
},
|
||||
editMember(row) {
|
||||
this.dialogOrgMemberUpdateVisible = true;
|
||||
this.memberForm = Object.assign({}, row);
|
||||
let roleIds = this.memberForm.roles.map(r => r.id);
|
||||
this.result = this.$get('/role/list/org', response => {
|
||||
this.$set(this.memberForm, "allroles", response.data);
|
||||
})
|
||||
// 编辑时填充角色信息
|
||||
this.$set(this.memberForm, 'roleIds', roleIds);
|
||||
listenGoBack(this.closeFunc);
|
||||
},
|
||||
cellClick(row) {
|
||||
// 保存当前点击的组织信息到currentRow
|
||||
this.currentRow = row;
|
||||
this.dialogOrgMemberVisible = true;
|
||||
let param = {
|
||||
name: '',
|
||||
organizationId: row.id
|
||||
};
|
||||
let path = "/user/special/org/member/list";
|
||||
this.result = this.$post(path + "/" + this.dialogCurrentPage + "/" + this.dialogPageSize, param, res => {
|
||||
let data = res.data;
|
||||
this.memberLineData = data.listObject;
|
||||
let url = "/userrole/list/org/" + row.id;
|
||||
for (let i = 0; i < this.memberLineData.length; i++) {
|
||||
this.$get(url + "/" + encodeURIComponent(this.memberLineData[i].id), response => {
|
||||
let roles = response.data;
|
||||
this.$set(this.memberLineData[i], "roles", roles);
|
||||
})
|
||||
}
|
||||
this.dialogTotal = data.itemCount;
|
||||
});
|
||||
listenGoBack(this.closeFunc);
|
||||
},
|
||||
dialogSearch() {
|
||||
let row = this.currentRow;
|
||||
this.dialogOrgMemberVisible = true;
|
||||
let param = this.dialogCondition;
|
||||
this.$set(param, 'organizationId', row.id);
|
||||
let path = "/user/special/org/member/list";
|
||||
this.result = this.$post(path + "/" + this.dialogCurrentPage + "/" + this.dialogPageSize, param, res => {
|
||||
let data = res.data;
|
||||
this.memberLineData = data.listObject;
|
||||
let url = "/userrole/list/org/" + row.id;
|
||||
for (let i = 0; i < this.memberLineData.length; i++) {
|
||||
this.$get(url + "/" + encodeURIComponent(this.memberLineData[i].id), response => {
|
||||
let roles = response.data;
|
||||
this.$set(this.memberLineData[i], "roles", roles);
|
||||
})
|
||||
}
|
||||
this.dialogTotal = data.itemCount;
|
||||
});
|
||||
},
|
||||
handleDelete(organization) {
|
||||
this.$refs.deleteConfirm.open(organization);
|
||||
},
|
||||
_handleDelete(organization) {
|
||||
this.$confirm(this.$t('organization.delete_confirm'), '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
cancelButtonText: this.$t('commons.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.result = this.$get(this.deletePath + organization.id, () => {
|
||||
let lastOrganizationId = getCurrentOrganizationId();
|
||||
let sourceId = organization.id;
|
||||
if (lastOrganizationId === sourceId) {
|
||||
refreshSessionAndCookies(DEFAULT, sourceId);
|
||||
}
|
||||
this.dialogTotal = data.itemCount;
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.initTableData();
|
||||
});
|
||||
listenGoBack(this.closeFunc);
|
||||
},
|
||||
dialogSearch() {
|
||||
let row = this.currentRow;
|
||||
this.dialogOrgMemberVisible = true;
|
||||
let param = this.dialogCondition;
|
||||
this.$set(param, 'organizationId', row.id);
|
||||
let path = "/user/special/org/member/list";
|
||||
this.result = this.$post(path + "/" + this.dialogCurrentPage + "/" + this.dialogPageSize, param, res => {
|
||||
let data = res.data;
|
||||
this.memberLineData = data.listObject;
|
||||
let url = "/userrole/list/org/" + row.id;
|
||||
for (let i = 0; i < this.memberLineData.length; i++) {
|
||||
this.$get(url + "/" + encodeURIComponent(this.memberLineData[i].id), response => {
|
||||
let roles = response.data;
|
||||
this.$set(this.memberLineData[i], "roles", roles);
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
type: 'info',
|
||||
message: this.$t('commons.delete_cancelled')
|
||||
});
|
||||
});
|
||||
},
|
||||
delMember(row) {
|
||||
this.$confirm(this.$t('member.remove_member'), '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
cancelButtonText: this.$t('commons.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.result = this.$get('/user/special/org/member/delete/' + this.currentRow.id + '/' + encodeURIComponent(row.id), () => {
|
||||
let sourceId = this.currentRow.id;
|
||||
let currentUser = getCurrentUser();
|
||||
let userId = row.id;
|
||||
if (currentUser.id === userId) {
|
||||
refreshSessionAndCookies(ORGANIZATION, sourceId);
|
||||
}
|
||||
this.dialogTotal = data.itemCount;
|
||||
this.$success(this.$t('commons.remove_success'))
|
||||
this.cellClick(this.currentRow);
|
||||
});
|
||||
},
|
||||
handleDelete(organization) {
|
||||
this.$refs.deleteConfirm.open(organization);
|
||||
},
|
||||
_handleDelete(organization) {
|
||||
this.$confirm(this.$t('organization.delete_confirm'), '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
cancelButtonText: this.$t('commons.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.result = this.$get(this.deletePath + organization.id, () => {
|
||||
let lastOrganizationId = getCurrentOrganizationId();
|
||||
let sourceId = organization.id;
|
||||
if (lastOrganizationId === sourceId) {
|
||||
let sign = DEFAULT;
|
||||
refreshSessionAndCookies(sign, sourceId);
|
||||
}
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
}).catch(() => {
|
||||
this.$info(this.$t('commons.remove_cancel'));
|
||||
});
|
||||
},
|
||||
createOrganization(createOrganizationForm) {
|
||||
this.$refs[createOrganizationForm].validate(valid => {
|
||||
if (valid) {
|
||||
this.result = this.$post(this.createPath, this.form, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.initTableData();
|
||||
this.dialogOrgAddVisible = false;
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
},
|
||||
updateOrganization(updateOrganizationForm) {
|
||||
this.$refs[updateOrganizationForm].validate(valid => {
|
||||
if (valid) {
|
||||
this.result = this.$post(this.updatePath, this.form, () => {
|
||||
this.$success(this.$t('commons.modify_success'));
|
||||
this.dialogOrgUpdateVisible = false;
|
||||
this.initTableData();
|
||||
});
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
type: 'info',
|
||||
message: this.$t('commons.delete_cancelled')
|
||||
});
|
||||
});
|
||||
},
|
||||
delMember(row) {
|
||||
this.$confirm(this.$t('member.remove_member'), '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
cancelButtonText: this.$t('commons.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.result = this.$get('/user/special/org/member/delete/' + this.currentRow.id + '/' + encodeURIComponent(row.id), () => {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
},
|
||||
initTableData() {
|
||||
this.result = this.$post(this.queryPath + "/" + this.currentPage + "/" + this.pageSize, this.condition, response => {
|
||||
let data = response.data;
|
||||
this.tableData = data.listObject;
|
||||
for (let i = 0; i < this.tableData.length; i++) {
|
||||
let param = {
|
||||
name: '',
|
||||
organizationId: this.tableData[i].id
|
||||
}
|
||||
let path = "user/special/org/member/list/all";
|
||||
this.$post(path, param, res => {
|
||||
let member = res.data;
|
||||
this.$set(this.tableData[i], "memberSize", member.length);
|
||||
})
|
||||
}
|
||||
this.total = data.itemCount;
|
||||
})
|
||||
},
|
||||
closeFunc() {
|
||||
this.memberLineData = [];
|
||||
this.initTableData();
|
||||
this.form = {};
|
||||
removeGoBackListener(this.closeFunc);
|
||||
this.dialogOrgAddVisible = false;
|
||||
this.dialogOrgUpdateVisible = false;
|
||||
this.dialogOrgMemberVisible = false;
|
||||
this.dialogOrgMemberAddVisible = false;
|
||||
this.dialogOrgMemberUpdateVisible = false;
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val;
|
||||
},
|
||||
submitForm(formName) {
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
let param = {
|
||||
userIds: this.memberForm.userIds,
|
||||
roleIds: this.memberForm.roleIds,
|
||||
organizationId: this.currentRow.id
|
||||
};
|
||||
this.result = this.$post("user/special/org/member/add", param, () => {
|
||||
let sign = "other";
|
||||
let sourceId = this.currentRow.id;
|
||||
let currentUser = getCurrentUser();
|
||||
let userId = row.id;
|
||||
if (currentUser.id === userId) {
|
||||
let sign = ORGANIZATION;
|
||||
refreshSessionAndCookies(sign, sourceId);
|
||||
}
|
||||
this.$success(this.$t('commons.remove_success'))
|
||||
refreshSessionAndCookies(sign, sourceId);
|
||||
this.cellClick(this.currentRow);
|
||||
this.dialogOrgMemberAddVisible = false;
|
||||
})
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
updateOrgMember(formName) {
|
||||
let param = {
|
||||
id: this.memberForm.id,
|
||||
name: this.memberForm.name,
|
||||
email: this.memberForm.email,
|
||||
phone: this.memberForm.phone,
|
||||
roleIds: this.memberForm.roleIds,
|
||||
organizationId: this.currentRow.id
|
||||
}
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
this.result = this.$post("/organization/member/update", param, () => {
|
||||
this.$success(this.$t('commons.modify_success'));
|
||||
this.dialogOrgMemberUpdateVisible = false;
|
||||
this.cellClick(this.currentRow);
|
||||
});
|
||||
}).catch(() => {
|
||||
this.$info(this.$t('commons.remove_cancel'));
|
||||
});
|
||||
},
|
||||
createOrganization(createOrganizationForm) {
|
||||
this.$refs[createOrganizationForm].validate(valid => {
|
||||
if (valid) {
|
||||
this.result = this.$post(this.createPath, this.form, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.initTableData();
|
||||
this.dialogOrgAddVisible = false;
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
},
|
||||
updateOrganization(updateOrganizationForm) {
|
||||
this.$refs[updateOrganizationForm].validate(valid => {
|
||||
if (valid) {
|
||||
this.result = this.$post(this.updatePath, this.form, () => {
|
||||
this.$success(this.$t('commons.modify_success'));
|
||||
this.dialogOrgUpdateVisible = false;
|
||||
this.initTableData();
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
},
|
||||
initTableData() {
|
||||
this.result = this.$post(this.queryPath + "/" + this.currentPage + "/" + this.pageSize, this.condition, response => {
|
||||
let data = response.data;
|
||||
this.tableData = data.listObject;
|
||||
for (let i = 0; i < this.tableData.length; i++) {
|
||||
let param = {
|
||||
name: '',
|
||||
organizationId: this.tableData[i].id
|
||||
}
|
||||
let path = "user/special/org/member/list/all";
|
||||
this.$post(path, param, res => {
|
||||
let member = res.data;
|
||||
this.$set(this.tableData[i], "memberSize", member.length);
|
||||
})
|
||||
}
|
||||
this.total = data.itemCount;
|
||||
})
|
||||
},
|
||||
closeFunc() {
|
||||
this.memberLineData = [];
|
||||
this.initTableData();
|
||||
this.form = {};
|
||||
removeGoBackListener(this.closeFunc);
|
||||
this.dialogOrgAddVisible = false;
|
||||
this.dialogOrgUpdateVisible = false;
|
||||
this.dialogOrgMemberVisible = false;
|
||||
this.dialogOrgMemberAddVisible = false;
|
||||
this.dialogOrgMemberUpdateVisible = false;
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val;
|
||||
},
|
||||
submitForm(formName) {
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
let param = {
|
||||
userIds: this.memberForm.userIds,
|
||||
roleIds: this.memberForm.roleIds,
|
||||
organizationId: this.currentRow.id
|
||||
};
|
||||
this.result = this.$post("user/special/org/member/add", param, () => {
|
||||
let sign = "other";
|
||||
let sourceId = this.currentRow.id;
|
||||
refreshSessionAndCookies(sign, sourceId);
|
||||
this.cellClick(this.currentRow);
|
||||
this.dialogOrgMemberAddVisible = false;
|
||||
})
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
updateOrgMember(formName) {
|
||||
let param = {
|
||||
id: this.memberForm.id,
|
||||
name: this.memberForm.name,
|
||||
email: this.memberForm.email,
|
||||
phone: this.memberForm.phone,
|
||||
roleIds: this.memberForm.roleIds,
|
||||
organizationId: this.currentRow.id
|
||||
}
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
this.result = this.$post("/organization/member/update", param, () => {
|
||||
this.$success(this.$t('commons.modify_success'));
|
||||
this.dialogOrgMemberUpdateVisible = false;
|
||||
this.cellClick(this.currentRow);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.member-size {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
.member-size {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.org-member-id {
|
||||
float: left;
|
||||
}
|
||||
.org-member-id {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.org-member-email {
|
||||
float: right;
|
||||
color: #8492a6;
|
||||
font-size: 13px;
|
||||
}
|
||||
.org-member-email {
|
||||
float: right;
|
||||
color: #8492a6;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.select-width {
|
||||
width: 100%;
|
||||
}
|
||||
.select-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dialog-css >>> .el-dialog__header {
|
||||
padding: 0px;
|
||||
}
|
||||
.dialog-css >>> .el-dialog__header {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
<el-table-column prop="organizationName" :label="$t('workspace.organization_name')"/>
|
||||
<el-table-column :label="$t('commons.member')">
|
||||
<template v-slot:default="scope">
|
||||
<el-button type="text" class="member-size" @click="cellClick(scope.row)">
|
||||
<el-link type="primary" class="member-size" @click="cellClick(scope.row)">
|
||||
{{scope.row.memberSize}}
|
||||
</el-button>
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.operating')">
|
||||
|
@ -200,12 +200,11 @@
|
|||
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
|
||||
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||
import {
|
||||
getCurrentOrganizationId,
|
||||
getCurrentUser,
|
||||
getCurrentWorkspaceId, listenGoBack,
|
||||
refreshSessionAndCookies, removeGoBackListener
|
||||
} from "../../../../common/js/utils";
|
||||
import {DEFAULT, WORKSPACE} from "../../../../common/js/constants";
|
||||
} from "@/common/js/utils";
|
||||
import {DEFAULT, WORKSPACE} from "@/common/js/constants";
|
||||
import MsDeleteConfirm from "../../common/components/MsDeleteConfirm";
|
||||
|
||||
export default {
|
||||
|
@ -537,7 +536,7 @@
|
|||
}
|
||||
|
||||
.dialog-css >>> .el-dialog__header {
|
||||
padding: 0px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -75,13 +75,13 @@
|
|||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item prop="port" label="Port" style="padding-left: 20px">
|
||||
<el-input-number v-model="item.port" :min="1" :max="9999"></el-input-number>
|
||||
<el-input-number v-model="item.port" :min="1" :max="65535"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item prop="maxConcurrency" :label="$t('test_resource_pool.max_threads')"
|
||||
style="padding-left: 20px">
|
||||
<el-input-number v-model="item.maxConcurrency" :min="1" :max="9999"></el-input-number>
|
||||
<el-input-number v-model="item.maxConcurrency" :min="1" :max="1000000000"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :offset="2" :span="2">
|
||||
|
@ -137,13 +137,13 @@
|
|||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item prop="port" label="Port" style="padding-left: 20px">
|
||||
<el-input-number v-model="item.port" :min="1" :max="9999"></el-input-number>
|
||||
<el-input-number v-model="item.port" :min="1" :max="65535"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item prop="maxConcurrency" :label="$t('test_resource_pool.max_threads')"
|
||||
style="padding-left: 20px">
|
||||
<el-input-number v-model="item.maxConcurrency" :min="1" :max="9999"></el-input-number>
|
||||
<el-input-number v-model="item.maxConcurrency" :min="1" :max="1000000000"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :offset="2" :span="2">
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
<div>
|
||||
|
||||
<el-dialog @close="close"
|
||||
:title="operationType == 'edit' ? ( readOnly ? $t('test_track.case.view_case') : $t('test_track.case.edit_case')) : $t('test_track.case.create')"
|
||||
:visible.sync="dialogFormVisible" width="65%">
|
||||
:title="operationType == 'edit' ? ( readOnly ? $t('test_track.case.view_case') : $t('test_track.case.edit_case')) : $t('test_track.case.create')"
|
||||
:visible.sync="dialogFormVisible" width="65%">
|
||||
|
||||
<el-form :model="form" :rules="rules" ref="caseFrom" v-loading="result.loading">
|
||||
|
||||
|
@ -92,7 +92,7 @@
|
|||
<el-row v-if="form.method && form.method == 'auto'">
|
||||
<el-col :span="9" :offset="1">
|
||||
<el-form-item :label="$t('test_track.case.relate_test')" :label-width="formLabelWidth" prop="testId">
|
||||
<el-select filterable :disabled="readOnly" v-model="form.testId"
|
||||
<el-select filterable :disabled="readOnly" v-model="form.testId"
|
||||
:placeholder="$t('test_track.case.input_type')">
|
||||
<el-option
|
||||
v-for="item in testOptions"
|
||||
|
@ -105,12 +105,12 @@
|
|||
</el-col>
|
||||
<el-col :span="9" :offset="1" v-if="form.testId=='other'">
|
||||
<el-form-item :label="$t('test_track.case.test_name')" :label-width="formLabelWidth" prop="testId">
|
||||
<el-input v-model="form.otherTestName" :placeholder="$t('test_track.case.input_test_case')" ></el-input>
|
||||
<el-input v-model="form.otherTestName" :placeholder="$t('test_track.case.input_test_case')"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row style="margin-top: 15px;">
|
||||
<el-col :offset="2">{{$t('test_track.case.prerequisite')}}:</el-col>
|
||||
<el-col :offset="2">{{ $t('test_track.case.prerequisite') }}:</el-col>
|
||||
</el-row>
|
||||
<el-row type="flex" justify="center" style="margin-top: 10px;">
|
||||
<el-col :span="20">
|
||||
|
@ -125,7 +125,7 @@
|
|||
</el-row>
|
||||
|
||||
<el-row v-if="form.method && form.method != 'auto'" style="margin-bottom: 10px">
|
||||
<el-col :offset="2">{{$t('test_track.case.steps')}}:</el-col>
|
||||
<el-col :offset="2">{{ $t('test_track.case.steps') }}:</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row v-if="form.method && form.method != 'auto'" type="flex" justify="center">
|
||||
|
@ -141,29 +141,29 @@
|
|||
<el-table-column :label="$t('test_track.case.step_desc')" prop="desc" min-width="35%">
|
||||
<template v-slot:default="scope">
|
||||
<el-input
|
||||
class="table-edit-input"
|
||||
size="mini"
|
||||
v-if="!readOnly"
|
||||
:disabled="readOnly"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 2, maxRows: 4}"
|
||||
:rows="2"
|
||||
v-model="scope.row.desc"
|
||||
:placeholder="$t('commons.input_content')"
|
||||
clearable></el-input>
|
||||
<pre>{{scope.row.desc}}</pre>
|
||||
clearable/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('test_track.case.expected_results')" prop="result" min-width="35%">
|
||||
<template v-slot:default="scope">
|
||||
<el-input
|
||||
class="table-edit-input"
|
||||
size="mini"
|
||||
v-if="!readOnly"
|
||||
:disabled="readOnly"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 2, maxRows: 4}"
|
||||
:rows="2"
|
||||
v-model="scope.row.result"
|
||||
:placeholder="$t('commons.input_content')"
|
||||
clearable></el-input>
|
||||
<pre>{{scope.row.result}}</pre>
|
||||
clearable/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.input_content')" min-width="15%">
|
||||
|
@ -187,7 +187,7 @@
|
|||
</el-row>
|
||||
|
||||
<el-row style="margin-top: 15px;margin-bottom: 10px">
|
||||
<el-col :offset="2">{{$t('commons.remark')}}:</el-col>
|
||||
<el-col :offset="2">{{ $t('commons.remark') }}:</el-col>
|
||||
</el-row>
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="20">
|
||||
|
@ -222,314 +222,305 @@
|
|||
|
||||
<script>
|
||||
|
||||
import {WORKSPACE_ID, TokenKey} from '../../../../../common/js/constants';
|
||||
import MsDialogFooter from '../../../common/components/MsDialogFooter'
|
||||
import {listenGoBack, removeGoBackListener, removeListenGoBack} from "../../../../../common/js/utils";
|
||||
import {TokenKey, WORKSPACE_ID} from '../../../../../common/js/constants';
|
||||
import MsDialogFooter from '../../../common/components/MsDialogFooter'
|
||||
import {listenGoBack, removeGoBackListener} from "../../../../../common/js/utils";
|
||||
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
|
||||
|
||||
export default {
|
||||
name: "TestCaseEdit",
|
||||
components: {MsDialogFooter},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
dialogFormVisible: false,
|
||||
form: {
|
||||
name: '',
|
||||
module: '',
|
||||
maintainer: '',
|
||||
priority: '',
|
||||
type: '',
|
||||
method: '',
|
||||
prerequisite: '',
|
||||
testId: '',
|
||||
otherTestName:'',
|
||||
steps: [{
|
||||
export default {
|
||||
name: "TestCaseEdit",
|
||||
components: {MsDialogFooter},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
dialogFormVisible: false,
|
||||
form: {
|
||||
name: '',
|
||||
module: '',
|
||||
maintainer: '',
|
||||
priority: '',
|
||||
type: '',
|
||||
method: '',
|
||||
prerequisite: '',
|
||||
testId: '',
|
||||
otherTestName: '',
|
||||
steps: [{
|
||||
num: 1,
|
||||
desc: '',
|
||||
result: ''
|
||||
}],
|
||||
remark: '',
|
||||
},
|
||||
moduleOptions: [],
|
||||
maintainerOptions: [],
|
||||
methodOptions: [],
|
||||
testOptions: [],
|
||||
workspaceId: '',
|
||||
rules: {
|
||||
name: [
|
||||
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
|
||||
{max: 50, message: this.$t('test_track.length_less_than') + '50', trigger: 'blur'}
|
||||
],
|
||||
module: [{required: true, message: this.$t('test_track.case.input_module'), trigger: 'change'}],
|
||||
maintainer: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
||||
priority: [{required: true, message: this.$t('test_track.case.input_priority'), trigger: 'change'}],
|
||||
type: [{required: true, message: this.$t('test_track.case.input_type'), trigger: 'change'}],
|
||||
testId: [{required: true, message: this.$t('commons.please_select'), trigger: 'change'}],
|
||||
method: [{required: true, message: this.$t('test_track.case.input_method'), trigger: 'change'}],
|
||||
prerequisite: [{max: 300, message: this.$t('test_track.length_less_than') + '300', trigger: 'blur'}],
|
||||
remark: [{max: 300, message: this.$t('test_track.length_less_than') + '300', trigger: 'blur'}]
|
||||
},
|
||||
formLabelWidth: "120px",
|
||||
operationType: '',
|
||||
isCreateContinue: false
|
||||
};
|
||||
},
|
||||
props: {
|
||||
treeNodes: {
|
||||
type: Array
|
||||
},
|
||||
readOnly: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
selectNode: {
|
||||
type: Object
|
||||
},
|
||||
currentProject: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getSelectOptions();
|
||||
},
|
||||
watch: {
|
||||
treeNodes() {
|
||||
this.getModuleOptions();
|
||||
},
|
||||
currentProject() {
|
||||
this.getTestOptions();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open(testCase) {
|
||||
this.resetForm();
|
||||
|
||||
if (window.history && window.history.pushState) {
|
||||
history.pushState(null, null, document.URL);
|
||||
window.addEventListener('popstate', this.close);
|
||||
}
|
||||
listenGoBack(this.close);
|
||||
this.operationType = 'add';
|
||||
if (testCase) {
|
||||
//修改
|
||||
this.operationType = 'edit';
|
||||
//复制
|
||||
if (testCase.name === '') {
|
||||
this.operationType = 'add';
|
||||
}
|
||||
let tmp = {};
|
||||
Object.assign(tmp, testCase);
|
||||
tmp.steps = JSON.parse(testCase.steps);
|
||||
Object.assign(this.form, tmp);
|
||||
this.form.module = testCase.nodeId;
|
||||
} else {
|
||||
if (this.selectNode.data) {
|
||||
this.form.module = this.selectNode.data.id;
|
||||
} else {
|
||||
if (this.moduleOptions.length > 0) {
|
||||
this.form.module = this.moduleOptions[0].id;
|
||||
}
|
||||
}
|
||||
let user = JSON.parse(localStorage.getItem(TokenKey));
|
||||
this.form.priority = 'P3';
|
||||
this.form.type = 'functional';
|
||||
this.form.method = 'manual';
|
||||
this.form.maintainer = user.id;
|
||||
}
|
||||
|
||||
this.getSelectOptions();
|
||||
this.dialogFormVisible = true;
|
||||
},
|
||||
handleAddStep(index, data) {
|
||||
let step = {};
|
||||
step.num = data.num + 1;
|
||||
step.desc = null;
|
||||
step.result = null;
|
||||
this.form.steps.forEach(step => {
|
||||
if (step.num > data.num) {
|
||||
step.num++;
|
||||
}
|
||||
});
|
||||
this.form.steps.splice(index + 1, 0, step);
|
||||
},
|
||||
handleDeleteStep(index, data) {
|
||||
this.form.steps.splice(index, 1);
|
||||
this.form.steps.forEach(step => {
|
||||
if (step.num > data.num) {
|
||||
step.num--;
|
||||
}
|
||||
});
|
||||
},
|
||||
close() {
|
||||
//移除监听,防止监听其他页面
|
||||
removeGoBackListener(this.close);
|
||||
this.dialogFormVisible = false;
|
||||
},
|
||||
saveCase() {
|
||||
this.$refs['caseFrom'].validate((valid) => {
|
||||
if (valid) {
|
||||
let param = this.buildParam();
|
||||
if (this.validate(param)) {
|
||||
this.result = this.$post('/test/case/' + this.operationType, param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
if (this.operationType == 'add' && this.isCreateContinue) {
|
||||
this.form.name = '';
|
||||
this.form.prerequisite = '';
|
||||
this.form.steps = [{
|
||||
num: 1,
|
||||
desc: '',
|
||||
result: ''
|
||||
}];
|
||||
this.form.remark = '';
|
||||
this.$emit("refresh");
|
||||
return;
|
||||
}
|
||||
this.dialogFormVisible = false;
|
||||
this.$emit("refresh");
|
||||
// 发送广播,刷新 head 上的最新列表
|
||||
TrackEvent.$emit(LIST_CHANGE);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
buildParam() {
|
||||
let param = {};
|
||||
Object.assign(param, this.form);
|
||||
param.steps = JSON.stringify(this.form.steps);
|
||||
param.nodeId = this.form.module;
|
||||
this.moduleOptions.forEach(item => {
|
||||
if (this.form.module === item.id) {
|
||||
param.nodePath = item.path;
|
||||
}
|
||||
});
|
||||
if (this.currentProject) {
|
||||
param.projectId = this.currentProject.id;
|
||||
}
|
||||
param.name = param.name.trim();
|
||||
if (param.method != 'auto') {
|
||||
param.testId = null;
|
||||
}
|
||||
return param;
|
||||
},
|
||||
validate(param) {
|
||||
for (let i = 0; i < param.steps.length; i++) {
|
||||
if ((param.steps[i].desc && param.steps[i].desc.length > 300) ||
|
||||
(param.steps[i].result && param.steps[i].result.length > 300)) {
|
||||
this.$warning(this.$t('test_track.case.step_desc') + ","
|
||||
+ this.$t('test_track.case.expected_results') + this.$t('test_track.length_less_than') + '300');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (param.name == '') {
|
||||
this.$warning(this.$t('test_track.case.input_name'));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
typeChange() {
|
||||
this.form.testId = '';
|
||||
this.getMethodOptions();
|
||||
this.getTestOptions()
|
||||
},
|
||||
getModuleOptions() {
|
||||
let moduleOptions = [];
|
||||
this.treeNodes.forEach(node => {
|
||||
this.buildNodePath(node, {path: ''}, moduleOptions);
|
||||
});
|
||||
this.moduleOptions = moduleOptions;
|
||||
},
|
||||
getMaintainerOptions() {
|
||||
let workspaceId = localStorage.getItem(WORKSPACE_ID);
|
||||
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
|
||||
this.maintainerOptions = response.data;
|
||||
});
|
||||
},
|
||||
getTestOptions() {
|
||||
this.testOptions = [];
|
||||
if (this.currentProject && this.form.type != '' && this.form.type != 'functional') {
|
||||
this.result = this.$get('/' + this.form.type + '/list/' + this.currentProject.id, response => {
|
||||
this.testOptions = response.data;
|
||||
this.testOptions.unshift({id: 'other', name: this.$t('test_track.case.other')})
|
||||
});
|
||||
}
|
||||
},
|
||||
getMethodOptions() {
|
||||
if (!this.form.type || this.form.type != 'functional') {
|
||||
this.methodOptions = [
|
||||
{value: 'auto', label: this.$t('test_track.case.auto')},
|
||||
{value: 'manual', label: this.$t('test_track.case.manual')}
|
||||
];
|
||||
} else {
|
||||
this.form.method = 'manual';
|
||||
this.methodOptions = [{value: 'manual', label: this.$t('test_track.case.manual')}]
|
||||
}
|
||||
},
|
||||
getSelectOptions() {
|
||||
this.getModuleOptions();
|
||||
this.getMaintainerOptions();
|
||||
this.getTestOptions();
|
||||
this.getMethodOptions();
|
||||
},
|
||||
buildNodePath(node, option, moduleOptions) {
|
||||
//递归构建节点路径
|
||||
option.id = node.id;
|
||||
option.path = option.path + '/' + node.name;
|
||||
moduleOptions.push(option);
|
||||
if (node.children) {
|
||||
for (let i = 0; i < node.children.length; i++) {
|
||||
this.buildNodePath(node.children[i], {path: option.path}, moduleOptions);
|
||||
}
|
||||
}
|
||||
},
|
||||
resetForm() {
|
||||
//防止点击修改后,点击新建触发校验
|
||||
if (this.$refs['caseFrom']) {
|
||||
this.$refs['caseFrom'].validate((valid) => {
|
||||
this.$refs['caseFrom'].resetFields();
|
||||
this.form.name = '';
|
||||
this.form.module = '';
|
||||
this.form.type = '';
|
||||
this.form.method = '';
|
||||
this.form.maintainer = '';
|
||||
this.form.priority = '';
|
||||
this.form.prerequisite = '';
|
||||
this.form.remark = '';
|
||||
this.form.testId = '';
|
||||
this.form.testName = '';
|
||||
this.form.steps = [{
|
||||
num: 1,
|
||||
desc: '',
|
||||
result: ''
|
||||
}],
|
||||
remark: '',
|
||||
},
|
||||
moduleOptions: [],
|
||||
maintainerOptions: [],
|
||||
methodOptions: [],
|
||||
testOptions: [],
|
||||
workspaceId: '',
|
||||
rules: {
|
||||
name: [
|
||||
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
|
||||
{max: 50, message: this.$t('test_track.length_less_than') + '50', trigger: 'blur'}
|
||||
],
|
||||
module: [{required: true, message: this.$t('test_track.case.input_module'), trigger: 'change'}],
|
||||
maintainer: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
||||
priority: [{required: true, message: this.$t('test_track.case.input_priority'), trigger: 'change'}],
|
||||
type: [{required: true, message: this.$t('test_track.case.input_type'), trigger: 'change'}],
|
||||
testId: [{required: true, message: this.$t('commons.please_select'), trigger: 'change'}],
|
||||
method: [{required: true, message: this.$t('test_track.case.input_method'), trigger: 'change'}],
|
||||
prerequisite: [{max: 300, message: this.$t('test_track.length_less_than') + '300', trigger: 'blur'}],
|
||||
remark: [{max: 300, message: this.$t('test_track.length_less_than') + '300', trigger: 'blur'}]
|
||||
},
|
||||
formLabelWidth: "120px",
|
||||
operationType: '',
|
||||
isCreateContinue: false
|
||||
};
|
||||
},
|
||||
props: {
|
||||
treeNodes: {
|
||||
type: Array
|
||||
},
|
||||
readOnly: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
selectNode: {
|
||||
type: Object
|
||||
},
|
||||
currentProject: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getSelectOptions();
|
||||
},
|
||||
watch: {
|
||||
treeNodes() {
|
||||
this.getModuleOptions();
|
||||
},
|
||||
currentProject() {
|
||||
this.getTestOptions();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open(testCase) {
|
||||
this.resetForm();
|
||||
|
||||
if (window.history && window.history.pushState) {
|
||||
history.pushState(null, null, document.URL);
|
||||
window.addEventListener('popstate', this.close);
|
||||
}
|
||||
listenGoBack(this.close);
|
||||
this.operationType = 'add';
|
||||
if (testCase) {
|
||||
//修改
|
||||
this.operationType = 'edit';
|
||||
//复制
|
||||
if (testCase.name === '') {
|
||||
this.operationType = 'add';
|
||||
}
|
||||
let tmp = {};
|
||||
Object.assign(tmp, testCase);
|
||||
tmp.steps = JSON.parse(testCase.steps);
|
||||
Object.assign(this.form, tmp);
|
||||
this.form.module = testCase.nodeId;
|
||||
} else {
|
||||
if (this.selectNode.data) {
|
||||
this.form.module = this.selectNode.data.id;
|
||||
} else {
|
||||
if (this.moduleOptions.length > 0) {
|
||||
this.form.module = this.moduleOptions[0].id;
|
||||
}
|
||||
}
|
||||
let user = JSON.parse(localStorage.getItem(TokenKey));
|
||||
this.form.priority = 'P3';
|
||||
this.form.type = 'functional';
|
||||
this.form.method = 'manual';
|
||||
this.form.maintainer = user.id;
|
||||
}
|
||||
|
||||
this.getSelectOptions();
|
||||
this.dialogFormVisible = true;
|
||||
},
|
||||
handleAddStep(index, data) {
|
||||
let step = {};
|
||||
step.num = data.num + 1;
|
||||
step.desc = null;
|
||||
step.result = null;
|
||||
this.form.steps.forEach(step => {
|
||||
if (step.num > data.num) {
|
||||
step.num++;
|
||||
}
|
||||
}];
|
||||
return true;
|
||||
});
|
||||
this.form.steps.splice(index + 1, 0, step);
|
||||
},
|
||||
handleDeleteStep(index, data) {
|
||||
this.form.steps.splice(index, 1);
|
||||
this.form.steps.forEach(step => {
|
||||
if (step.num > data.num) {
|
||||
step.num--;
|
||||
}
|
||||
});
|
||||
},
|
||||
close() {
|
||||
//移除监听,防止监听其他页面
|
||||
removeGoBackListener(this.close);
|
||||
this.dialogFormVisible = false;
|
||||
},
|
||||
saveCase() {
|
||||
this.$refs['caseFrom'].validate((valid) => {
|
||||
if (valid) {
|
||||
let param = this.buildParam();
|
||||
if (this.validate(param)) {
|
||||
this.result = this.$post('/test/case/' + this.operationType, param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
if (this.operationType == 'add' && this.isCreateContinue) {
|
||||
this.form.name = '';
|
||||
this.form.prerequisite = '';
|
||||
this.form.steps = [{
|
||||
num: 1,
|
||||
desc: '',
|
||||
result: ''
|
||||
}];
|
||||
this.form.remark = '';
|
||||
this.$emit("refresh");
|
||||
return;
|
||||
}
|
||||
this.dialogFormVisible = false;
|
||||
this.$emit("refresh");
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
buildParam() {
|
||||
let param = {};
|
||||
Object.assign(param, this.form);
|
||||
param.steps = JSON.stringify(this.form.steps);
|
||||
param.nodeId = this.form.module;
|
||||
this.moduleOptions.forEach(item => {
|
||||
if (this.form.module === item.id) {
|
||||
param.nodePath = item.path;
|
||||
}
|
||||
});
|
||||
if (this.currentProject) {
|
||||
param.projectId = this.currentProject.id;
|
||||
}
|
||||
param.name = param.name.trim();
|
||||
if (param.method != 'auto') {
|
||||
param.testId = null;
|
||||
}
|
||||
return param;
|
||||
},
|
||||
validate(param) {
|
||||
for (let i = 0; i < param.steps.length; i++) {
|
||||
if ((param.steps[i].desc && param.steps[i].desc.length > 300) ||
|
||||
(param.steps[i].result && param.steps[i].result.length > 300)) {
|
||||
this.$warning(this.$t('test_track.case.step_desc') + ","
|
||||
+ this.$t('test_track.case.expected_results') + this.$t('test_track.length_less_than') + '300');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (param.name == '') {
|
||||
this.$warning(this.$t('test_track.case.input_name'));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
typeChange() {
|
||||
this.form.testId = '';
|
||||
this.getMethodOptions();
|
||||
this.getTestOptions()
|
||||
},
|
||||
getModuleOptions() {
|
||||
let moduleOptions = [];
|
||||
this.treeNodes.forEach(node => {
|
||||
this.buildNodePath(node, {path: ''}, moduleOptions);
|
||||
});
|
||||
this.moduleOptions = moduleOptions;
|
||||
},
|
||||
getMaintainerOptions() {
|
||||
let workspaceId = localStorage.getItem(WORKSPACE_ID);
|
||||
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
|
||||
this.maintainerOptions = response.data;
|
||||
});
|
||||
},
|
||||
getTestOptions() {
|
||||
this.testOptions = [];
|
||||
if (this.currentProject && this.form.type != '' && this.form.type != 'functional') {
|
||||
this.result = this.$get('/' + this.form.type + '/list/' + this.currentProject.id, response => {
|
||||
this.testOptions = response.data;
|
||||
this.testOptions.unshift({id:'other',name:this.$t('test_track.case.other')})
|
||||
});
|
||||
}
|
||||
},
|
||||
getMethodOptions() {
|
||||
if (!this.form.type || this.form.type != 'functional') {
|
||||
this.methodOptions = [
|
||||
{value: 'auto', label: this.$t('test_track.case.auto')},
|
||||
{value: 'manual', label: this.$t('test_track.case.manual')}
|
||||
];
|
||||
} else {
|
||||
this.form.method = 'manual';
|
||||
this.methodOptions = [{value: 'manual', label: this.$t('test_track.case.manual')}]
|
||||
}
|
||||
},
|
||||
getSelectOptions() {
|
||||
this.getModuleOptions();
|
||||
this.getMaintainerOptions();
|
||||
this.getTestOptions();
|
||||
this.getMethodOptions();
|
||||
},
|
||||
buildNodePath(node, option, moduleOptions) {
|
||||
//递归构建节点路径
|
||||
option.id = node.id;
|
||||
option.path = option.path + '/' + node.name;
|
||||
moduleOptions.push(option);
|
||||
if (node.children) {
|
||||
for (let i = 0; i < node.children.length; i++) {
|
||||
this.buildNodePath(node.children[i], {path: option.path}, moduleOptions);
|
||||
}
|
||||
}
|
||||
},
|
||||
resetForm() {
|
||||
//防止点击修改后,点击新建触发校验
|
||||
if (this.$refs['caseFrom']) {
|
||||
this.$refs['caseFrom'].validate((valid) => {
|
||||
this.$refs['caseFrom'].resetFields();
|
||||
this.form.name = '';
|
||||
this.form.module = '';
|
||||
this.form.type = '';
|
||||
this.form.method = '';
|
||||
this.form.maintainer = '';
|
||||
this.form.priority = '';
|
||||
this.form.prerequisite = '';
|
||||
this.form.remark = '';
|
||||
this.form.testId = '';
|
||||
this.form.testName='';
|
||||
this.form.steps = [{
|
||||
num: 1,
|
||||
desc: '',
|
||||
result: ''
|
||||
}];
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.tb-edit .el-textarea {
|
||||
display: none;
|
||||
}
|
||||
.el-switch {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.tb-edit .current-row .el-textarea {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tb-edit .current-row .el-textarea + pre {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-switch {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.case-name {
|
||||
width: 194px;
|
||||
}
|
||||
.case-name {
|
||||
width: 194px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -108,7 +108,6 @@ export default {
|
|||
methods: {
|
||||
handleDragEnd(draggingNode, dropNode, dropType, ev) {
|
||||
let param = this.buildParam(draggingNode, dropNode, dropType);
|
||||
console.log(this.treeNodes);
|
||||
this.$post("/case/node/drag", param, () => {
|
||||
draggingNode.data.level = param.level;
|
||||
this.refreshTable();
|
||||
|
|
|
@ -92,12 +92,12 @@
|
|||
<div class="dialog-footer">
|
||||
<el-button
|
||||
@click="dialogFormVisible = false">
|
||||
{{$t('test_track.cancel')}}
|
||||
{{ $t('test_track.cancel') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="savePlan">
|
||||
{{$t('test_track.confirm')}}
|
||||
{{ $t('test_track.confirm') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -110,116 +110,119 @@
|
|||
|
||||
<script>
|
||||
|
||||
import {WORKSPACE_ID} from '../../../../../common/js/constants';
|
||||
import TestPlanStatusButton from "../common/TestPlanStatusButton";
|
||||
import {listenGoBack, removeGoBackListener} from "../../../../../common/js/utils";
|
||||
import {WORKSPACE_ID} from '../../../../../common/js/constants';
|
||||
import TestPlanStatusButton from "../common/TestPlanStatusButton";
|
||||
import {listenGoBack, removeGoBackListener} from "../../../../../common/js/utils";
|
||||
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
|
||||
|
||||
export default {
|
||||
name: "TestPlanEdit",
|
||||
components: {TestPlanStatusButton},
|
||||
data() {
|
||||
return {
|
||||
dialogFormVisible: false,
|
||||
form: {
|
||||
name: '',
|
||||
projectId: '',
|
||||
principal: '',
|
||||
stage: '',
|
||||
description: ''
|
||||
},
|
||||
rules:{
|
||||
name :[
|
||||
{required: true, message: this.$t('test_track.plan.input_plan_name'), trigger: 'blur'},
|
||||
{ max: 30, message: this.$t('test_track.length_less_than') + '30', trigger: 'blur' }
|
||||
],
|
||||
projectId :[{required: true, message: this.$t('test_track.plan.input_plan_project'), trigger: 'change'}],
|
||||
principal :[{required: true, message: this.$t('test_track.plan.input_plan_principal'), trigger: 'change'}],
|
||||
stage :[{required: true, message: this.$t('test_track.plan.input_plan_stage'), trigger: 'change'}],
|
||||
description :[{ max: 200, message: this.$t('test_track.length_less_than') + '200', trigger: 'blur'}]
|
||||
},
|
||||
formLabelWidth: "120px",
|
||||
operationType: '',
|
||||
projects: [],
|
||||
principalOptions: []
|
||||
};
|
||||
export default {
|
||||
name: "TestPlanEdit",
|
||||
components: {TestPlanStatusButton},
|
||||
data() {
|
||||
return {
|
||||
dialogFormVisible: false,
|
||||
form: {
|
||||
name: '',
|
||||
projectId: '',
|
||||
principal: '',
|
||||
stage: '',
|
||||
description: ''
|
||||
},
|
||||
methods: {
|
||||
openTestPlanEditDialog(testPlan) {
|
||||
this.resetForm();
|
||||
this.getProjects();
|
||||
this.setPrincipalOptions();
|
||||
this.operationType = 'add';
|
||||
if(testPlan){
|
||||
//修改
|
||||
this.operationType = 'edit';
|
||||
let tmp = {};
|
||||
Object.assign(tmp, testPlan);
|
||||
Object.assign(this.form, tmp);
|
||||
rules: {
|
||||
name: [
|
||||
{required: true, message: this.$t('test_track.plan.input_plan_name'), trigger: 'blur'},
|
||||
{max: 30, message: this.$t('test_track.length_less_than') + '30', trigger: 'blur'}
|
||||
],
|
||||
projectId: [{required: true, message: this.$t('test_track.plan.input_plan_project'), trigger: 'change'}],
|
||||
principal: [{required: true, message: this.$t('test_track.plan.input_plan_principal'), trigger: 'change'}],
|
||||
stage: [{required: true, message: this.$t('test_track.plan.input_plan_stage'), trigger: 'change'}],
|
||||
description: [{max: 200, message: this.$t('test_track.length_less_than') + '200', trigger: 'blur'}]
|
||||
},
|
||||
formLabelWidth: "120px",
|
||||
operationType: '',
|
||||
projects: [],
|
||||
principalOptions: []
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
openTestPlanEditDialog(testPlan) {
|
||||
this.resetForm();
|
||||
this.getProjects();
|
||||
this.setPrincipalOptions();
|
||||
this.operationType = 'add';
|
||||
if (testPlan) {
|
||||
//修改
|
||||
this.operationType = 'edit';
|
||||
let tmp = {};
|
||||
Object.assign(tmp, testPlan);
|
||||
Object.assign(this.form, tmp);
|
||||
}
|
||||
listenGoBack(this.close);
|
||||
this.dialogFormVisible = true;
|
||||
},
|
||||
savePlan() {
|
||||
this.$refs['planFrom'].validate((valid) => {
|
||||
if (valid) {
|
||||
let param = {};
|
||||
Object.assign(param, this.form);
|
||||
param.name = param.name.trim();
|
||||
if (param.name == '') {
|
||||
this.$warning(this.$t('test_track.plan.input_plan_name'));
|
||||
return;
|
||||
}
|
||||
listenGoBack(this.close);
|
||||
this.dialogFormVisible = true;
|
||||
},
|
||||
savePlan(){
|
||||
this.$refs['planFrom'].validate((valid) => {
|
||||
if (valid) {
|
||||
let param = {};
|
||||
Object.assign(param, this.form);
|
||||
param.name = param.name.trim();
|
||||
if (param.name == '') {
|
||||
this.$warning(this.$t('test_track.plan.input_plan_name'));
|
||||
return;
|
||||
}
|
||||
param.workspaceId = localStorage.getItem(WORKSPACE_ID);
|
||||
this.$post('/test/plan/' + this.operationType, param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.dialogFormVisible = false;
|
||||
this.$emit("refresh");
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
param.workspaceId = localStorage.getItem(WORKSPACE_ID);
|
||||
this.$post('/test/plan/' + this.operationType, param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.dialogFormVisible = false;
|
||||
this.$emit("refresh");
|
||||
// 发送广播,刷新 head 上的最新列表
|
||||
TrackEvent.$emit(LIST_CHANGE);
|
||||
});
|
||||
},
|
||||
getProjects() {
|
||||
this.$get("/project/listAll", (response) => {
|
||||
if (response.success) {
|
||||
this.projects = response.data;
|
||||
} else {
|
||||
this.$warning()(response.message);
|
||||
}
|
||||
});
|
||||
},
|
||||
setPrincipalOptions() {
|
||||
let workspaceId = localStorage.getItem(WORKSPACE_ID);
|
||||
this.$post('/user/ws/member/tester/list', {workspaceId:workspaceId}, response => {
|
||||
this.principalOptions = response.data;
|
||||
});
|
||||
},
|
||||
statusChange(status) {
|
||||
this.form.status = status;
|
||||
this.$forceUpdate();
|
||||
},
|
||||
close() {
|
||||
removeGoBackListener(this.close);
|
||||
this.dialogFormVisible = false;
|
||||
},
|
||||
resetForm() {
|
||||
//防止点击修改后,点击新建触发校验
|
||||
if (this.$refs['planFrom']) {
|
||||
this.$refs['planFrom'].validate((valid) => {
|
||||
this.$refs['planFrom'].resetFields();
|
||||
this.form.name = '';
|
||||
this.form.projectId = '';
|
||||
this.form.principal = '';
|
||||
this.form.stage = '';
|
||||
this.form.description = '';
|
||||
this.form.status = null;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
getProjects() {
|
||||
this.$get("/project/listAll", (response) => {
|
||||
if (response.success) {
|
||||
this.projects = response.data;
|
||||
} else {
|
||||
this.$warning()(response.message);
|
||||
}
|
||||
});
|
||||
},
|
||||
setPrincipalOptions() {
|
||||
let workspaceId = localStorage.getItem(WORKSPACE_ID);
|
||||
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
|
||||
this.principalOptions = response.data;
|
||||
});
|
||||
},
|
||||
statusChange(status) {
|
||||
this.form.status = status;
|
||||
this.$forceUpdate();
|
||||
},
|
||||
close() {
|
||||
removeGoBackListener(this.close);
|
||||
this.dialogFormVisible = false;
|
||||
},
|
||||
resetForm() {
|
||||
//防止点击修改后,点击新建触发校验
|
||||
if (this.$refs['planFrom']) {
|
||||
this.$refs['planFrom'].validate((valid) => {
|
||||
this.$refs['planFrom'].resetFields();
|
||||
this.form.name = '';
|
||||
this.form.projectId = '';
|
||||
this.form.principal = '';
|
||||
this.form.stage = '';
|
||||
this.form.description = '';
|
||||
this.form.status = null;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
@ -128,17 +128,30 @@
|
|||
|
||||
<el-table-column :label="$t('test_track.case.step_desc')" prop="desc" min-width="21%">
|
||||
<template v-slot:default="scope">
|
||||
<pre>{{scope.row.desc}}</pre>
|
||||
<el-input
|
||||
size="mini"
|
||||
class="border-hidden"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 1, maxRows: 4}"
|
||||
:disabled="true"
|
||||
v-model="scope.row.desc"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('test_track.case.expected_results')" prop="result" min-width="21%">
|
||||
<template v-slot:default="scope">
|
||||
<pre>{{scope.row.result}}</pre>
|
||||
<el-input
|
||||
size="mini"
|
||||
class="border-hidden"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 1, maxRows: 4}"
|
||||
:disabled="true"
|
||||
v-model="scope.row.result"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('test_track.plan_view.actual_result')" min-width="21%">
|
||||
<template v-slot:default="scope">
|
||||
<el-input
|
||||
class="table-edit-input"
|
||||
size="mini"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 2, maxRows: 4}"
|
||||
|
@ -146,8 +159,7 @@
|
|||
:disabled="isReadOnly"
|
||||
v-model="scope.row.actualResult"
|
||||
:placeholder="$t('commons.input_content')"
|
||||
clearable></el-input>
|
||||
<pre>{{scope.row.actualResult}}</pre>
|
||||
clearable/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('test_track.plan_view.step_result')" min-width="12%">
|
||||
|
@ -303,7 +315,7 @@
|
|||
readConfig: {toolbar: []},
|
||||
test: {},
|
||||
activeTab: 'detail',
|
||||
isFailure: false,
|
||||
isFailure: true,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
|
@ -482,7 +494,7 @@
|
|||
stepResultChange() {
|
||||
if (this.testCase.method == 'manual') {
|
||||
this.isFailure = this.testCase.steptResults.filter(s => {
|
||||
return !s.executeResult || s.executeResult === 'Failure' || s.executeResult === 'Blocking';
|
||||
return s.executeResult === 'Failure' || s.executeResult === 'Blocking';
|
||||
}).length > 0;
|
||||
}
|
||||
|
||||
|
@ -522,17 +534,10 @@
|
|||
|
||||
<style scoped>
|
||||
|
||||
|
||||
.tb-edit .el-textarea {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tb-edit .current-row .el-textarea {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tb-edit .current-row .el-textarea + pre {
|
||||
display: none;
|
||||
.border-hidden >>> .el-textarea__inner {
|
||||
border-style: hidden;
|
||||
background-color: white;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.cast_label {
|
||||
|
|
|
@ -358,12 +358,16 @@
|
|||
this.total = data.itemCount;
|
||||
this.tableData = data.listObject;
|
||||
for (let i = 0; i < this.tableData.length; i++) {
|
||||
this.$set(this.tableData[i], "issuesSize", 0);
|
||||
this.$get("/issues/get/" + this.tableData[i].caseId, response => {
|
||||
let issues = response.data;
|
||||
this.$set(this.tableData[i], "issuesSize", issues.length);
|
||||
this.$set(this.tableData[i], "issuesContent", issues);
|
||||
})
|
||||
if (this.tableData[i]) {
|
||||
this.$set(this.tableData[i], "issuesSize", 0);
|
||||
this.$get("/issues/get/" + this.tableData[i].caseId, response => {
|
||||
let issues = response.data;
|
||||
if (this.tableData[i]) {
|
||||
this.$set(this.tableData[i], "issuesSize", issues.length);
|
||||
this.$set(this.tableData[i], "issuesContent", issues);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// this.selectIds.clear();
|
||||
this.selectRows.clear();
|
||||
|
|
|
@ -75,3 +75,22 @@ body {
|
|||
background-color: #EBEEF5;
|
||||
}
|
||||
/* 表格拖拽表头调整宽度 --> */
|
||||
|
||||
/* <-- 表格 input 编辑效果*/
|
||||
.table-edit-input .el-textarea__inner {
|
||||
border-style: hidden;
|
||||
}
|
||||
.table-edit-input.is-disabled .el-textarea__inner {
|
||||
background-color: white;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.el-table .current-row .table-edit-input {
|
||||
border: 1px solid #DCDFE6;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.table-edit-input .el-textarea__inner:focus {
|
||||
border: 1px solid #409EFF;
|
||||
}
|
||||
/* 表格 input 编辑效果 --> */
|
||||
|
|
Loading…
Reference in New Issue