fix(工作台): 修复没有项目权限的用户进入工作台会报错的问题

--bug=1024743 --user=宋天阳
【工作台】github#22990,工作台-我的待办、我的关注、我的创建
https://www.tapd.cn/55049933/s/1355563
This commit is contained in:
song-tianyang 2023-03-24 15:07:50 +08:00 committed by fit2-zhao
parent 0e46093380
commit 4d251ef8d3
1 changed files with 260 additions and 188 deletions

View File

@ -17,15 +17,16 @@
:fields.sync="fields"
:field-key="tableHeaderKey"
@refresh="initTableData"
ref="table">
ref="table"
>
<ms-table-column
prop="deleteTime"
sortable
v-if="this.trashEnable"
:fields-width="fieldsWidth"
:label="$t('commons.delete_time')"
min-width="150px">
min-width="150px"
>
<template v-slot:default="scope">
<span>{{ scope.row.deleteTime | datetimeFormat }}</span>
</template>
@ -36,7 +37,8 @@
:fields-width="fieldsWidth"
v-if="this.trashEnable"
:label="$t('commons.delete_user')"
min-width="120"/>
min-width="120"
/>
<span v-for="item in fields" :key="item.key">
<ms-table-column
@ -46,7 +48,8 @@
prop="num"
sortable
:label="$t('commons.id')"
min-width="80"/>
min-width="80"
/>
<ms-table-column
v-if="item.id === 'num' && customNum"
@ -54,7 +57,8 @@
prop="customNum"
sortable
:label="$t('commons.id')"
min-width="80"/>
min-width="80"
/>
<ms-table-column
prop="name"
@ -70,7 +74,8 @@
v-if="isShowAllColumn"
:fields-width="fieldsWidth"
:label="$t('test_track.case.module')"
min-width="150px">
min-width="150px"
>
</ms-table-column>
<ms-table-column
@ -79,7 +84,8 @@
v-if="!isShowAllColumn"
:fields-width="fieldsWidth"
:label="$t('report.project_name')"
min-width="150px">
min-width="150px"
>
</ms-table-column>
<ms-table-column
@ -87,16 +93,26 @@
:field="item"
:fields-width="fieldsWidth"
min-width="100px"
prop="versionId">
prop="versionId"
>
<template v-slot:default="scope">
<span>{{ scope.row.versionName }}</span>
</template>
</ms-table-column>
<ms-table-column :label="$t('test_track.case.case_desc')" prop="desc" :field="item" min-width="120px"
v-if="isShowAllColumn">
<ms-table-column
:label="$t('test_track.case.case_desc')"
prop="desc"
:field="item"
min-width="120px"
v-if="isShowAllColumn"
>
<template v-slot:default="scope">
<el-link @click.stop="getCase(scope.row.id)" style="color:#783887;">{{ $t('commons.preview') }}</el-link>
<el-link
@click.stop="getCase(scope.row.id)"
style="color: #783887"
>{{ $t("commons.preview") }}</el-link
>
</template>
</ms-table-column>
@ -107,7 +123,8 @@
:field="item"
:fields-width="fieldsWidth"
:label="$t('commons.create_user')"
:filters="userFilter">
:filters="userFilter"
>
<template v-slot:default="scope">
{{ getCreateUserName(scope.row.createUser) }}
</template>
@ -115,24 +132,35 @@
<test-case-review-status-table-item
:field="item"
:fields-width="fieldsWidth"/>
:fields-width="fieldsWidth"
/>
<test-plan-case-status-table-item
prop="lastExecuteResult"
:field="item"
:fields-width="fieldsWidth"/>
:fields-width="fieldsWidth"
/>
<ms-table-column
prop="tags"
:field="item"
:fields-width="fieldsWidth"
:label="$t('commons.tag')"
min-width="80">
min-width="80"
>
<template v-slot:default="scope">
<ms-tag v-for="(itemName,index) in scope.row.tags" :key="index" type="success" effect="plain"
:show-tooltip="scope.row.tags.length===1&&itemName.length*12<=80"
:content="itemName" style="margin-left: 0px; margin-right: 2px"/>
<span/>
<ms-tag
v-for="(itemName, index) in scope.row.tags"
:key="index"
type="success"
effect="plain"
:show-tooltip="
scope.row.tags.length === 1 && itemName.length * 12 <= 80
"
:content="itemName"
style="margin-left: 0px; margin-right: 2px"
/>
<span />
</template>
</ms-table-column>
@ -143,94 +171,117 @@
:field="item"
:fields-width="fieldsWidth"
:label="$t('commons.update_time')"
min-width="150px">
min-width="150px"
>
<template v-slot:default="scope">
<span>{{ scope.row.updateTime | datetimeFormat }}</span>
</template>
</ms-table-column>
<ms-table-column prop="createTime"
<ms-table-column
prop="createTime"
:field="item"
:fields-width="fieldsWidth"
:label="$t('commons.create_time')"
sortable
min-width="150px">
min-width="150px"
>
<template v-slot:default="scope">
<span>{{ scope.row.createTime | datetimeFormat }}</span>
</template>
</ms-table-column>
<ms-table-column v-for="field in testCaseTemplate.customFields" :key="field.id"
<ms-table-column
v-for="field in testCaseTemplate.customFields"
:key="field.id"
:filters="getCustomFieldFilter(field)"
:field="item"
:fields-width="fieldsWidth"
:label="field.system ? $t(systemFiledMap[field.name]) :field.name"
:label="field.system ? $t(systemFiledMap[field.name]) : field.name"
:min-width="120"
:prop="field.name">
:prop="field.name"
>
<template v-slot="scope">
<span v-if="field.name === '用例等级'">
<priority-table-item
:value="getCustomFieldValue(scope.row, field) ? getCustomFieldValue(scope.row, field) : scope.row.priority"/>
:value="
getCustomFieldValue(scope.row, field)
? getCustomFieldValue(scope.row, field)
: scope.row.priority
"
/>
</span>
<span v-else>
{{ getCustomFieldValue(scope.row, field) }}
</span>
</template>
</ms-table-column>
</span>
</ms-table>
<ms-table-pagination :change="initTableData" :current-page.sync="page.currentPage" :page-size.sync="page.pageSize"
:total="page.total"/>
<ms-table-pagination
:change="initTableData"
:current-page.sync="page.currentPage"
:page-size.sync="page.pageSize"
:total="page.total"
/>
<test-case-preview ref="testCasePreview" :loading="rowCaseResult.loading"/>
<test-case-preview ref="testCasePreview" :loading="rowCaseResult.loading" />
</div>
</template>
<script>
import {TEST_CASE_LIST} from "metersphere-frontend/src/utils/constants";
import { TEST_CASE_LIST } from "metersphere-frontend/src/utils/constants";
import {
getCustomFieldFilter,
getCustomFieldValue, getCustomTableHeader,
getCustomFieldValue,
getCustomTableHeader,
getCustomTableWidth,
getLastTableSortField,
getPageInfo, getTableHeaderWithCustomFields,
initCondition, parseCustomFilesForList,
getPageInfo,
getTableHeaderWithCustomFields,
initCondition,
parseCustomFilesForList,
} from "metersphere-frontend/src/utils/tableUtils";
import HeaderLabelOperate from "metersphere-frontend/src/components/head/HeaderLabelOperate";
import {getCurrentProjectID, getCurrentUserId, getCurrentWorkspaceId} from "metersphere-frontend/src/utils/token";
import {
getCurrentProjectID,
getCurrentUserId,
getCurrentWorkspaceId,
} from "metersphere-frontend/src/utils/token";
import {getProjectMember, getProjectMemberUserFilter} from "@/api/user";
import { getProjectMember, getProjectMemberUserFilter } from "@/api/user";
import MsTable from "metersphere-frontend/src/components/table/MsTable";
import MsTableColumn from "metersphere-frontend/src/components/table/MsTableColumn";
import {SYSTEM_FIELD_NAME_MAP} from "metersphere-frontend/src/utils/table-constants";
import {editTestCaseOrder, getTestCaseListById, getTestCasePages, getTestCaseStep, testCaseList} from "@/api/test-case";
import MsTablePagination from 'metersphere-frontend/src/components/pagination/TablePagination';
import {TEST_CASE_CONFIGS} from "metersphere-frontend/src/components/search/search-components";
import { SYSTEM_FIELD_NAME_MAP } from "metersphere-frontend/src/utils/table-constants";
import {
editTestCaseOrder,
getTestCaseListById,
getTestCasePages,
getTestCaseStep,
testCaseList,
} from "@/api/test-case";
import MsTablePagination from "metersphere-frontend/src/components/pagination/TablePagination";
import { TEST_CASE_CONFIGS } from "metersphere-frontend/src/components/search/search-components";
import PriorityTableItem from "@/business/module/track/PriorityTableItem";
import StatusTableItem from "@/business/module/track/StatusTableItem";
import MsTag from "metersphere-frontend/src/components/MsTag";
import {hasLicense} from "metersphere-frontend/src/utils/permission";
import {getProject} from "@/api/project";
import {getProjectVersions} from "metersphere-frontend/src/api/version";
import useStore, {useApiStore} from "@/store";
import {getTestTemplate} from "metersphere-frontend/src/api/custom-field-template";
import {getAdvSearchCustomField} from "metersphere-frontend/src/components/search/custom-component";
import { hasLicense } from "metersphere-frontend/src/utils/permission";
import { getProject } from "@/api/project";
import { getProjectVersions } from "metersphere-frontend/src/api/version";
import useStore, { useApiStore } from "@/store";
import { getTestTemplate } from "metersphere-frontend/src/api/custom-field-template";
import { getAdvSearchCustomField } from "metersphere-frontend/src/components/search/custom-component";
import TestCaseReviewStatusTableItem from "@/business/othermodule/track/TestCaseReviewStatusTableItem";
import TestPlanCaseStatusTableItem from "@/business/othermodule/track/TestPlanCaseStatusTableItem";
import TestCasePreview from "@/business/othermodule/track/TestCasePreview";
import {getUUID, parseTag} from "metersphere-frontend/src/utils";
import {uuid} from "@/model/ApiTestModel";
import { getUUID, parseTag } from "metersphere-frontend/src/utils";
import { uuid } from "@/model/ApiTestModel";
import {
getCustomFieldValueForTrack,
getCustomTableHeaderByXpack,
getTableHeaderWithCustomFieldsByXpack
getTableHeaderWithCustomFieldsByXpack,
} from "@/business/component/js/table-head-util";
export default {
@ -245,7 +296,7 @@ export default {
MsTag,
TestCaseReviewStatusTableItem,
TestPlanCaseStatusTableItem,
TestCasePreview
TestCasePreview,
},
data() {
return {
@ -259,20 +310,23 @@ export default {
creator: {
operator: "current user",
value: "current user",
}
}
},
},
},
versionFilters: [],
statusFilters: [
{text: this.$t('test_track.case.status_prepare'), value: 'Prepare'},
{text: this.$t('test_track.case.status_running'), value: 'Underway'},
{text: this.$t('test_track.case.status_finished'), value: 'Completed'},
{ text: this.$t("test_track.case.status_prepare"), value: "Prepare" },
{ text: this.$t("test_track.case.status_running"), value: "Underway" },
{
text: this.$t("test_track.case.status_finished"),
value: "Completed",
},
],
priorityFilters: [
{text: 'P0', value: 'P0'},
{text: 'P1', value: 'P1'},
{text: 'P2', value: 'P2'},
{text: 'P3', value: 'P3'}
{ text: "P0", value: "P0" },
{ text: "P1", value: "P1" },
{ text: "P2", value: "P2" },
{ text: "P3", value: "P3" },
],
typeArr: [],
valueArr: {},
@ -280,18 +334,18 @@ export default {
testCaseTemplate: {},
members: [],
page: getPageInfo(),
fields: getCustomTableHeader('TRACK_TEST_CASE'),
fieldsWidth: getCustomTableWidth('TRACK_TEST_CASE'),
fields: getCustomTableHeader("TRACK_TEST_CASE"),
fieldsWidth: getCustomTableWidth("TRACK_TEST_CASE"),
memberMap: new Map(),
rowCase: {},
rowCaseResult: {},
store:{},
userFilter:[]
store: {},
userFilter: [],
};
},
props: {
treeNodes: {
type: Array
type: Array,
},
trashEnable: {
type: Boolean,
@ -317,8 +371,8 @@ export default {
screenHeight: {
type: [Number, String],
default() {
return 'calc(100vh - 218px)';
}
return "calc(100vh - 218px)";
},
}, //
},
computed: {
@ -341,41 +395,43 @@ export default {
return this.store.currentProjectIsCustomNum;
},
},
created () {
created() {
getProjectMemberUserFilter((data) => {
this.userFilter = data;
});
if (this.isFocus) {
if (this.condition.filters) {
delete this.condition.filters['user_id']
delete this.condition.filters["user_id"];
}
if (this.condition.userId) {
delete this.condition.userId
delete this.condition.userId;
}
this.condition.combine = {followPeople: {operator: "current user", value: "current user",}}
this.condition.combine = {
followPeople: { operator: "current user", value: "current user" },
};
} else if (this.isCreation) {
if (this.condition.filters) {
delete this.condition.filters['user_id']
delete this.condition.filters["user_id"];
}
this.condition.userId = getCurrentUserId();
}
this.getTemplateField();
this.store = useApiStore();
this.$emit('setCondition', this.condition);
this.$emit("setCondition", this.condition);
if (this.trashEnable) {
if (this.condition.filters) {
this.condition.filters.status = ["Trash"];
} else {
this.condition.filters = {status: ["Trash"]};
this.condition.filters = { status: ["Trash"] };
}
} else {
if (this.condition.filters) {
this.condition.filters.review_status = ["Prepare", "Pass", "UnPass"];
} else {
this.condition.filters = {review_status: ["Prepare", "Pass", "UnPass"]};
this.condition.filters = {
review_status: ["Prepare", "Pass", "UnPass"],
};
}
}
this.condition.versionId = this.currentVersion;
this.initTableData();
@ -392,7 +448,7 @@ export default {
if (this.condition.filters) {
this.condition.filters.review_status = ["Prepare", "Pass", "UnPass"];
} else {
this.condition.filters = {review_status: ["Prepare", "Pass", "UnPass"]};
this.condition.filters = { review_status: ["Prepare", "Pass", "UnPass"] };
}
let ids = this.$route.params.ids;
if (ids) {
@ -400,7 +456,6 @@ export default {
}
this.initTableData();
this.condition.ids = null;
},
watch: {
selectNodeIds() {
@ -409,23 +464,22 @@ export default {
if (this.condition.filters) {
this.condition.filters.status = [];
} else {
this.condition.filters = {status: []}
this.condition.filters = { status: [] };
}
}
initCondition(this.condition, false);
this.initTableData();
},
condition() {
this.$emit('setCondition', this.condition);
this.$emit("setCondition", this.condition);
},
trashEnable() {
if (this.trashEnable) {
//
if (this.condition.filters) {
this.condition.filters.status = ["Trash"];
} else {
this.condition.filters = {status: ["Trash"]}
this.condition.filters = { status: ["Trash"] };
}
this.condition.moduleIds = [];
initCondition(this.condition, false);
@ -434,7 +488,7 @@ export default {
if (this.condition.filters) {
this.condition.filters.status = [];
} else {
this.condition.filters = {status: []}
this.condition.filters = { status: [] };
}
}
},
@ -446,14 +500,14 @@ export default {
},
methods: {
getCreateUserName(userId) {
let user = this.userFilter.filter(item => item.value === userId);
let user = this.userFilter.filter((item) => item.value === userId);
return user.length > 0 ? user[0].text : "";
},
getTemplateField() {
this.loading = true;
let p1 = getProjectMember((data) => {
this.members = data;
this.members.forEach(item => {
this.members.forEach((item) => {
this.memberMap.set(item.id, item.name);
});
});
@ -461,30 +515,44 @@ export default {
Promise.all([p1, p2]).then((data) => {
let template = data[1];
this.testCaseTemplate = template;
this.fields = getTableHeaderWithCustomFields(this.tableHeaderKey, this.testCaseTemplate.customFields, this.members);
this.fields = getTableHeaderWithCustomFields(
this.tableHeaderKey,
this.testCaseTemplate.customFields,
this.members
);
// todo
this.condition.components = this.condition.components.filter(item => item.custom !== true);
let comp = getAdvSearchCustomField(this.condition, this.testCaseTemplate.customFields);
this.condition.components = this.condition.components.filter(
(item) => item.custom !== true
);
let comp = getAdvSearchCustomField(
this.condition,
this.testCaseTemplate.customFields
);
//
comp.filter(element => {
if (element.label === '责任人') {
element.label = this.$t('custom_field.case_maintainer')
comp.filter((element) => {
if (element.label === "责任人") {
element.label = this.$t("custom_field.case_maintainer");
}
if (element.label === '用例等级') {
element.label = this.$t('custom_field.case_priority')
if (element.label === "用例等级") {
element.label = this.$t("custom_field.case_priority");
}
if (element.label === '用例状态') {
element.label = this.$t('custom_field.case_status')
if (element.label === "用例状态") {
element.label = this.$t("custom_field.case_status");
// TAB
if (this.trashEnable) {
element.options = [{text: this.$t('test_track.plan.plan_status_trash'), value: 'Trash'}];
element.options = [
{
text: this.$t("test_track.plan.plan_status_trash"),
value: "Trash",
},
];
} else {
element.options.forEach(option => {
element.options.forEach((option) => {
option.text = this.$t(option.text);
});
}
}
})
});
this.condition.components.push(...comp);
this.setTestCaseDefaultValue(template);
this.$nextTick(() => {
@ -497,7 +565,7 @@ export default {
},
setTestCaseDefaultValue(template) {
let testCaseDefaultValue = {};
template.customFields.forEach(item => {
template.customFields.forEach((item) => {
if (item.system) {
if (item.defaultValue) {
testCaseDefaultValue[item.name] = JSON.parse(item.defaultValue);
@ -505,12 +573,12 @@ export default {
testCaseDefaultValue[item.name] = "";
}
}
if (item.name === '用例等级') {
item.columnKey = 'priority';
} else if (item.name === '责任人') {
item.columnKey = 'maintainer';
} else if (item.name === '用例状态') {
item.columnKey = 'status';
if (item.name === "用例等级") {
item.columnKey = "priority";
} else if (item.name === "责任人") {
item.columnKey = "maintainer";
} else if (item.name === "用例状态") {
item.columnKey = "status";
}
});
useStore().testCaseDefaultValue = testCaseDefaultValue;
@ -519,28 +587,28 @@ export default {
getCustomFieldValue(row, field) {
let value = getCustomFieldValueForTrack(row, field, this.members);
if (!value) {
if (field.name === '用例等级') {
if (field.name === "用例等级") {
return row.priority;
}
if (field.name === '责任人') {
if (field.name === "责任人") {
return row.maintainerName;
}
if (field.name === '用例状态') {
if (field.name === "用例状态") {
return row.status;
}
}
return value;
},
getCustomFieldFilter(field) {
if (field.name === '用例状态') {
if (field.name === "用例状态") {
let option = null;
if (!this.trashEnable) {
option = [];
field.options.forEach((item) => {
option.push({
text: this.$t(item.text),
value: item.value
})
value: item.value,
});
});
}
return option;
@ -549,15 +617,15 @@ export default {
},
checkRedirectEditPage(redirectParam) {
if (redirectParam != null) {
getTestCaseListById(id).then(response => {
getTestCaseListById(id).then((response) => {
let testCase = response.data;
testCase.label = "redirect";
this.$emit('testCaseEdit', testCase);
this.$emit("testCaseEdit", testCase);
});
}
},
getProjectName() {
getProject(this.projectId).then(response => {
getProject(this.projectId).then((response) => {
let project = response.data;
if (project) {
this.projectName = project.name;
@ -567,7 +635,7 @@ export default {
getSelectDataRange() {
let dataRange = this.$route.params.dataSelectRange;
let dataType = this.$route.params.dataType;
this.selectDataRange = dataType === 'case' ? dataRange : 'all';
this.selectDataRange = dataType === "case" ? dataRange : "all";
},
initTableData() {
this.condition.planId = "";
@ -596,26 +664,26 @@ export default {
this.condition.caseCoverage = null;
this.condition.filters.review_status = ["Prepare", "Pass", "UnPass"];
switch (this.selectDataRange) {
case 'thisWeekCount':
case "thisWeekCount":
this.condition.selectThisWeedData = true;
break;
case 'thisWeekRelevanceCount':
case "thisWeekRelevanceCount":
this.condition.selectThisWeedRelevanceData = true;
break;
case 'uncoverage':
this.condition.caseCoverage = 'uncoverage';
case "uncoverage":
this.condition.caseCoverage = "uncoverage";
break;
case 'coverage':
this.condition.caseCoverage = 'coverage';
case "coverage":
this.condition.caseCoverage = "coverage";
break;
case 'notReviewed':
this.condition.filters.review_status = ['Prepare'];
case "notReviewed":
this.condition.filters.review_status = ["Prepare"];
break;
case 'reviewSuccess':
this.condition.filters.review_status = ['Pass'];
case "reviewSuccess":
this.condition.filters.review_status = ["Pass"];
break;
case 'reviewFail':
this.condition.filters.review_status = ['UnPass'];
case "reviewFail":
this.condition.filters.review_status = ["UnPass"];
break;
}
if (this.trashEnable) {
@ -626,25 +694,30 @@ export default {
this.condition.filters.version_id = versionIds;
}
}
if (this.projectId) {
if (this.projectId && this.projectId !== "no_such_project") {
this.condition.projectId = this.projectId;
this.$emit('setCondition', this.condition);
this.$emit("setCondition", this.condition);
this.loading = true;
testCaseList({pageNum: this.page.currentPage, pageSize: this.page.pageSize}, this.condition)
.then(response => {
testCaseList(
{ pageNum: this.page.currentPage, pageSize: this.page.pageSize },
this.condition
).then((response) => {
this.loading = false;
let data = response.data;
this.page.total = data.itemCount;
this.page.data = data.listObject;
parseCustomFilesForList(this.page.data);
parseTag(this.page.data);
this.page.data.forEach(item => {
this.page.data.forEach((item) => {
let nodePath = item.nodePath;
if (item.customFields) {
item.customFields = JSON.parse(item.customFields);
}
if (nodePath.startsWith("/未规划用例", "0")) {
item.nodePath = nodePath.replaceAll("/未规划用例", "/" + this.$t('api_test.unplanned_case'));
item.nodePath = nodePath.replaceAll(
"/未规划用例",
"/" + this.$t("api_test.unplanned_case")
);
}
});
});
@ -655,37 +728,38 @@ export default {
},
handleEdit(testCase, column) {
let query = {
projectId: testCase.projectId
projectId: testCase.projectId,
};
let path = '/track/case/edit/' + testCase.id;
let path = "/track/case/edit/" + testCase.id;
let TestCaseData = this.$router.resolve({
path,
query,
});
window.open(TestCaseData.href, '_blank');
window.open(TestCaseData.href, "_blank");
},
refresh() {
this.$refs.table.clear();
this.$emit('refresh');
this.$emit("refresh");
},
refreshAll() {
this.$refs.table.clear();
this.$emit('refreshAll');
this.$emit("refreshAll");
},
getCase(id) {
this.$refs.testCasePreview.open();
this.rowCaseResult.loading = true;
getTestCaseStep(id)
.then(response => {
getTestCaseStep(id).then((response) => {
this.rowCase = response.data;
this.rowCase.steps = JSON.parse(this.rowCase.steps);
if (!this.rowCase.steps || this.rowCase.length < 1) {
this.rowCase.steps = [{
this.rowCase.steps = [
{
num: 1,
desc: '',
result: ''
}];
desc: "",
result: "",
},
];
}
if (!this.rowCase.stepModel) {
this.rowCase.stepModel = "STEP";
@ -695,22 +769,20 @@ export default {
},
getVersionOptions() {
if (hasLicense()) {
getProjectVersions(getCurrentProjectID()).then(response => {
this.versionFilters = response.data.map(u => {
return {text: u.name, value: u.id};
getProjectVersions(getCurrentProjectID()).then((response) => {
this.versionFilters = response.data.map((u) => {
return { text: u.name, value: u.id };
});
});
}
},
}
},
};
</script>
<style scoped>
.operate-button > div {
display: inline-block;
margin-left: 10px;
}
</style>