feat_功能用例_接口定义_用户离开页面提醒保存数据 --story=1002981 --user=王孝刚 9.所有页面点关闭时先判断页面是否有修改,有则提示用户是否需要保存 https://www.tapd.cn/55049933/s/1060185

This commit is contained in:
wxg0103 2021-10-27 17:56:43 +08:00 committed by 刘瑞斌
parent f8516212c9
commit e9664eddc0
9 changed files with 298 additions and 11 deletions

View File

@ -29,7 +29,7 @@
class="ms-api-button" class="ms-api-button"
ref="environmentSelect"/> ref="environmentSelect"/>
<!-- 主框架列表 --> <!-- 主框架列表 -->
<el-tabs v-model="apiDefaultTab" @edit="handleTabRemove" @tab-click="addTab"> <el-tabs v-model="apiDefaultTab" @edit="closeConfirm" @tab-click="addTab">
<el-tab-pane <el-tab-pane
name="trash" name="trash"
:label="$t('commons.trash')" v-if="trashEnable"> :label="$t('commons.trash')" v-if="trashEnable">
@ -527,9 +527,58 @@ export default {
}, },
handleTabClose() { handleTabClose() {
let tabs = this.apiTabs[0]; let tabs = this.apiTabs[0];
this.apiTabs = []; let message = "";
this.apiDefaultTab = tabs.name; let tab = this.apiTabs;
this.apiTabs.push(tabs); delete tab[0];
tab.forEach(t => {
if (t.api && this.$store.state.apiMap.has(t.api.id) && (this.$store.state.apiMap.get(t.api.id).get("responseChange") === true || this.$store.state.apiMap.get(t.api.id).get("requestChange") === true ||
this.$store.state.apiMap.get(t.api.id).get("fromChange") === true)) {
message += t.api.name + "";
}
})
if (message !== "") {
this.$alert("接口[ " + message.substr(0, message.length - 1) + " ]未保存,是否确认关闭全部?", '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
callback: (action) => {
if (action === 'confirm') {
this.$store.state.apiMap.clear();
this.apiTabs = [];
this.apiDefaultTab = tabs.name;
this.apiTabs.push(tabs);
}
}
});
} else {
this.apiTabs = [];
this.apiDefaultTab = tabs.name;
this.apiTabs.push(tabs);
}
},
closeConfirm(targetName) {
let tabs = this.apiTabs;
if(!tabs[1].api) {
this.handleTabRemove(targetName);
}
if (tabs[1].api && this.$store.state.apiMap.size > 0) {
if (this.$store.state.apiMap.get(tabs[1].api.id).get("responseChange") === true || this.$store.state.apiMap.get(tabs[1].api.id).get("requestChange") === true ||
this.$store.state.apiMap.get(tabs[1].api.id).get("fromChange") === true) {
this.$alert("接口[ " + tabs[1].api.name + " ]未保存,是否确认关闭?", '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
callback: (action) => {
if (action === 'confirm') {
this.$store.state.apiMap.delete(tabs[1].api.id);
this.handleTabRemove(targetName);
}
}
});
}
} else{
this.$store.state.apiMap.delete(tabs[1].api.id);
this.handleTabRemove(targetName);
}
}, },
handleTabRemove(targetName) { handleTabRemove(targetName) {
let tabs = this.apiTabs; let tabs = this.apiTabs;

View File

@ -51,6 +51,8 @@
config: {}, config: {},
response: {}, response: {},
maintainerOptions: [], maintainerOptions: [],
count: 0,
responseCount: 0,
} }
}, },
props: { props: {
@ -60,6 +62,28 @@
syncTabs: Array, syncTabs: Array,
projectId: String projectId: String
}, },
watch: {
request: {
handler(newObj, oldObj) {
this.count++
if (this.count > 2) {
this.$store.state.apiStatus.set("requestChange", true);
this.$store.state.apiMap.set(this.currentApi.id, this.$store.state.apiStatus);
}
},
deep: true
},
},
response: {
handler(newObj, oldObj) {
this.responseCount++;
if (this.responseCount > 1) {
this.$store.state.apiStatus.set("responseChange", true);
this.$store.state.apiMap.set(this.currentApi.id, this.$store.state.apiStatus);
}
},
deep: true
},
created() { created() {
this.getMaintainerOptions(); this.getMaintainerOptions();
switch (this.currentProtocol) { switch (this.currentProtocol) {
@ -78,6 +102,12 @@
} }
this.formatApi(); this.formatApi();
this.addListener(); this.addListener();
if (!(this.$store.state.apiMap instanceof Map)) {
this.$store.state.apiMap = new Map();
}
if (!(this.$store.state.apiStatus instanceof Map)) {
this.$store.state.apiStatus = new Map();
}
}, },
methods: { methods: {
changeTab(type){ changeTab(type){
@ -233,6 +263,7 @@
this.currentApi.isCopy = false; this.currentApi.isCopy = false;
this.$emit('saveApi', data); this.$emit('saveApi', data);
}); });
this.$store.state.apiMap.delete(this.currentApi.id);
}, },
handleSave() { handleSave() {
if (this.$refs.httpApi) { if (this.$refs.httpApi) {

View File

@ -92,6 +92,48 @@
moduleOptions: Array, moduleOptions: Array,
basisData: {}, basisData: {},
}, },
watch: {
'basicForm.name': {
handler(v, v1) {
if (v && v1 && v !== v1) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.basicForm.id, this.$store.state.apiStatus);
}
}
},
'basicForm.moduleId': {
handler(v, v1) {
if (v && v1 && v !== v1) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.basicForm.id, this.$store.state.apiStatus);
}
}
},
'basicForm.status': {
handler(v, v1) {
if (v && v1 && v !== v1) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.basicForm.id, this.$store.state.apiStatus);
}
}
},
'basicForm.follows': {
handler(v, v1) {
if (v && v1 && JSON.stringify(v) !== JSON.stringify(v1)) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.basicForm.id, this.$store.state.apiStatus);
}
}
},
'basicForm.description': {
handler(v, v1) {
if (v && v1 && v !== v1) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.basicForm.id, this.$store.state.apiStatus);
}
}
},
},
created() { created() {
this.getMaintainerOptions(); this.getMaintainerOptions();
this.basicForm = this.basisData; this.basicForm = this.basisData;

View File

@ -191,6 +191,62 @@
}, },
props: {moduleOptions: {}, request: {}, response: {}, basisData: {}, syncTabs: Array, projectId: String}, props: {moduleOptions: {}, request: {}, response: {}, basisData: {}, syncTabs: Array, projectId: String},
watch: { watch: {
'httpForm.name': {
handler(v, v1) {
if (v && v1 && v !== v1) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.httpForm.id, this.$store.state.apiStatus);
}
}
},
'httpForm.path': {
handler(v, v1) {
if (v && v1 && v !== v1) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.httpForm.id, this.$store.state.apiStatus);
}
}
},
'httpForm.userId': {
handler(v, v1) {
if (v && v1 && v !== v1) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.httpForm.id, this.$store.state.apiStatus);
}
}
},
'httpForm.moduleId': {
handler(v, v1) {
if (v && v1 && v !== v1) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.httpForm.id, this.$store.state.apiStatus);
}
}
},
'httpForm.status': {
handler(v, v1) {
if (v && v1 && v !== v1) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.httpForm.id, this.$store.state.apiStatus);
}
}
},
'httpForm.follows': {
handler(v, v1) {
if (v && v1 && JSON.stringify(v) !== JSON.stringify(v1)) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.httpForm.id, this.$store.state.apiStatus);
}
}
},
'httpForm.description': {
handler(v, v1) {
if (v && v1 && v !== v1) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.httpForm.id, this.$store.state.apiStatus);
}
}
},
syncTabs() { syncTabs() {
if (this.basisData && this.syncTabs && this.syncTabs.includes(this.basisData.id)) { if (this.basisData && this.syncTabs && this.syncTabs.includes(this.basisData.id)) {
// //

View File

@ -136,6 +136,56 @@
} }
}, },
watch: {
'basicForm.name': {
handler(v, v1) {
if (v && v1 && v !== v1) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.basicForm.id, this.$store.state.apiStatus);
}
}
},
'basicForm.userId': {
handler(v, v1) {
if (v && v1 && v !== v1) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.basicForm.id, this.$store.state.apiStatus);
}
}
},
'basicForm.moduleId': {
handler(v, v1) {
if (v && v1 && v !== v1) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.basicForm.id, this.$store.state.apiStatus);
}
}
},
'basicForm.status': {
handler(v, v1) {
if (v && v1 && v !== v1) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.basicForm.id, this.$store.state.apiStatus);
}
}
},
'basicForm.follows': {
handler(v, v1) {
if (v && v1 && JSON.stringify(v) !== JSON.stringify(v1)) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.basicForm.id, this.$store.state.apiStatus);
}
}
},
'basicForm.description': {
handler(v, v1) {
if (v && v1 && v !== v1) {
this.$store.state.apiStatus.set("fromChange", true);
this.$store.state.apiMap.set(this.basicForm.id, this.$store.state.apiStatus);
}
}
},
},
methods: { methods: {
getMaintainerOptions() { getMaintainerOptions() {
this.$post('/user/project/member/tester/list', {projectId: getCurrentProjectID()}, response => { this.$post('/user/project/member/tester/list', {projectId: getCurrentProjectID()}, response => {

View File

@ -19,7 +19,7 @@
</ms-aside-container> </ms-aside-container>
<ms-main-container> <ms-main-container>
<el-tabs v-model="activeName" @tab-click="addTab" @tab-remove="removeTab"> <el-tabs v-model="activeName" @tab-click="addTab" @tab-remove="closeConfirm">
<el-tab-pane name="trash" v-if="trashEnable" :label="$t('commons.trash')"> <el-tab-pane name="trash" v-if="trashEnable" :label="$t('commons.trash')">
<test-case-list <test-case-list
:checkRedirectID="checkRedirectID" :checkRedirectID="checkRedirectID"
@ -313,9 +313,48 @@ export default {
} }
}, },
handleTabClose() { handleTabClose() {
this.tabs = []; let message = "";
this.activeName = "default"; this.tabs.forEach(t => {
this.refresh(); if (t && this.$store.state.testCaseMap.has(t.testCaseInfo.id) && this.$store.state.testCaseMap.get(t.testCaseInfo.id) > 1) {
message += t.testCaseInfo.name + "";
}
})
if (message !== "") {
this.$alert("用例[ " + message.substr(0, message.length - 1) + " ]未保存,是否确认关闭全部?", '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
callback: (action) => {
if (action === 'confirm') {
this.$store.state.testCaseMap.clear();
this.tabs = [];
this.activeName = "default";
this.refresh();
}
}
});
} else {
this.tabs = [];
this.activeName = "default";
this.refresh();
}
},
closeConfirm(targetName) {
let t = this.tabs.filter(tab => tab.name === targetName);
if (t && this.$store.state.testCaseMap.has(t[0].testCaseInfo.id) && this.$store.state.testCaseMap.get(t[0].testCaseInfo.id) > 1) {
this.$alert("用例[ " + t[0].testCaseInfo.name + " ]未保存,是否确认关闭?", '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
callback: (action) => {
if (action === 'confirm') {
this.$store.state.testCaseMap.delete(t[0].testCaseInfo.id);
this.removeTab(targetName);
}
}
});
} else {
this.$store.state.testCaseMap.delete(t[0].testCaseInfo.id);
this.removeTab(targetName);
}
}, },
removeTab(targetName) { removeTab(targetName) {
this.tabs = this.tabs.filter(tab => tab.name !== targetName); this.tabs = this.tabs.filter(tab => tab.name !== targetName);

View File

@ -96,7 +96,7 @@ export default {
watch: { watch: {
treeNodes() { treeNodes() {
this.getModuleOptions(); this.getModuleOptions();
} },
}, },
computed: { computed: {
projectId() { projectId() {
@ -142,7 +142,7 @@ export default {
// this.treeNodes.forEach(node => { // this.treeNodes.forEach(node => {
// buildNodePath(node, {path: ''}, moduleOptions); // buildNodePath(node, {path: ''}, moduleOptions);
// }); // });
if(this.currentModule!==undefined){ if (this.currentModule !== undefined) {
this.moduleOptions.forEach(item => { this.moduleOptions.forEach(item => {
if (this.currentModule.id === item.id) { if (this.currentModule.id === item.id) {
this.currentModule.path = item.path; this.currentModule.path = item.path;

View File

@ -308,6 +308,18 @@
!hasPermission('PROJECT_TRACK_CASE:READ+EDIT'); !hasPermission('PROJECT_TRACK_CASE:READ+EDIT');
} }
}, },
watch: {
form: {
handler(val) {
if (this.$store.state.testCaseMap) {
let change = this.$store.state.testCaseMap.get(this.form.id);
change = change + 1;
this.$store.state.testCaseMap.set(this.form.id, change);
}
},
deep: true
}
},
mounted() { mounted() {
this.getSelectOptions(); this.getSelectOptions();
if (this.type === 'edit' || this.type === 'copy') { if (this.type === 'edit' || this.type === 'copy') {
@ -330,6 +342,10 @@
this.form.module = this.treeNodes[0].id; this.form.module = this.treeNodes[0].id;
this.form.nodePath = this.treeNodes[0].path; this.form.nodePath = this.treeNodes[0].path;
} }
if (!(this.$store.state.testCaseMap instanceof Map)) {
this.$store.state.testCaseMap = new Map();
}
this.$store.state.testCaseMap.set(this.form.id, 0);
}, },
created() { created() {
this.projectId = this.projectIds; this.projectId = this.projectIds;
@ -557,7 +573,7 @@
this.$nextTick(() => { this.$nextTick(() => {
this.showInputTag = true; this.showInputTag = true;
}); });
this.$store.state.testCaseMap.set(this.form.id, 0);
}); });
}, },
async setFormData(testCase) { async setFormData(testCase) {
@ -645,6 +661,7 @@
// //
this.$refs.otherInfo.getFileMetaData(this.form.id); this.$refs.otherInfo.getFileMetaData(this.form.id);
}); });
this.$store.state.testCaseMap.set(this.form.id, 0);
} }
}, },
buildParam() { buildParam() {

View File

@ -31,6 +31,9 @@ const state = {
currentProjectIsCustomNum: false, currentProjectIsCustomNum: false,
testCaseTemplate: {}, testCaseTemplate: {},
scenarioMap: new Map(), scenarioMap: new Map(),
apiMap: new Map(),
apiStatus: new Map(),
testCaseMap: new Map()
} }
const store = new Vuex.Store({ const store = new Vuex.Store({