This commit is contained in:
chenjianxing 2020-08-26 10:49:39 +08:00
commit 895c43bbaf
9 changed files with 1017 additions and 997 deletions

@ -1 +1 @@
Subproject commit b86032cbbda9a9e6028308aa95a887cff2192f1c
Subproject commit ecb30d83c575c6ed14adb1a1ebea389730f410a9

View File

@ -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>

View File

@ -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);
})
});
},

View File

@ -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>

View File

@ -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>

View File

@ -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">
@ -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,302 +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>
.el-switch {
margin-bottom: 10px;
}
.el-switch {
margin-bottom: 10px;
}
.case-name {
width: 194px;
}
.case-name {
width: 194px;
}
</style>

View File

@ -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>

View File

@ -414,6 +414,7 @@
},
openTestCaseEdit(testCase) {
this.showDialog = true;
this.issuesSwitch = false;
this.activeTab = 'detail';
listenGoBack(this.handleClose);
this.initData(testCase);
@ -471,18 +472,18 @@
}
},
issuesChange() {
// if (this.testCase.issues.hasIssues) {
// let desc = this.addPLabel('[' + this.$t('test_track.plan_view.operate_step') + ']');
// let result = this.addPLabel('[' + this.$t('test_track.case.expected_results') + ']');
// let executeResult = this.addPLabel('[' + this.$t('test_track.plan_view.actual_result') + ']');
// this.testCase.steps.forEach(step => {
// let stepPrefix = this.$t('test_track.plan_view.step') + step.num + ':';
// desc += this.addPLabel(stepPrefix + (step.desc == undefined ? '' : step.desc));
// result += this.addPLabel(stepPrefix + (step.result == undefined ? '' : step.result));
// executeResult += this.addPLabel(stepPrefix + (step.executeResult == undefined ? '' : step.executeResult));
// });
// this.testCase.issues.content = desc + this.addPLabel('') + result + this.addPLabel('') + executeResult + this.addPLabel('');
// }
if (this.issuesSwitch) {
let desc = this.addPLabel('[' + this.$t('test_track.plan_view.operate_step') + ']');
let result = this.addPLabel('[' + this.$t('test_track.case.expected_results') + ']');
let executeResult = this.addPLabel('[' + this.$t('test_track.plan_view.actual_result') + ']');
this.testCase.steps.forEach(step => {
let stepPrefix = this.$t('test_track.plan_view.step') + step.num + ':';
desc += this.addPLabel(stepPrefix + (step.desc == undefined ? '' : step.desc));
result += this.addPLabel(stepPrefix + (step.result == undefined ? '' : step.result));
executeResult += this.addPLabel(stepPrefix + (step.executeResult == undefined ? '' : step.executeResult));
});
this.testCase.issues.content = desc + this.addPLabel('') + result + this.addPLabel('') + executeResult + this.addPLabel('');
}
},
addPLabel(str) {
return "<p>" + str + "</p>";

@ -1 +1 @@
Subproject commit 7e4d80cc2b870a8cac6dbb9fe6711ab6041faf6d
Subproject commit 390943d21e7d0196e0d7d5faa66f0131cb631614