fix(测试计划): 修改测试计划已归档不能关联和编辑&补充测试计划报告分享无资源

This commit is contained in:
xinxin.wu 2024-05-22 10:53:05 +08:00 committed by 刘瑞斌
parent 846ea5bfba
commit a32ba8d291
7 changed files with 70 additions and 42 deletions

View File

@ -90,7 +90,7 @@
> >
<a-button <a-button
v-if="item.config" v-if="hasAnyPermission(['SYSTEM_SERVICE_INTEGRATION:READ+DELETE']) && item.config"
v-permission="['SYSTEM_SERVICE_INTEGRATION:READ+DELETE']" v-permission="['SYSTEM_SERVICE_INTEGRATION:READ+DELETE']"
type="outline" type="outline"
class="arco-btn-outline--secondary" class="arco-btn-outline--secondary"

View File

@ -160,7 +160,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { useEventListener } from '@vueuse/core'; import { useEventListener } from '@vueuse/core';
import { Message } from '@arco-design/web-vue'; import { Message } from '@arco-design/web-vue';
import { cloneDeep } from 'lodash-es'; import { cloneDeep } from 'lodash-es';
@ -187,6 +187,7 @@
import { PreviewEditorImageUrl } from '@/api/requrls/case-management/featureCase'; import { PreviewEditorImageUrl } from '@/api/requrls/case-management/featureCase';
import { defaultReportDetail, statusConfig } from '@/config/testPlan'; import { defaultReportDetail, statusConfig } from '@/config/testPlan';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { NOT_FOUND_RESOURCE } from '@/router/constants';
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import { addCommasToNumber } from '@/utils'; import { addCommasToNumber } from '@/utils';
import { hasAnyPermission } from '@/utils/permission'; import { hasAnyPermission } from '@/utils/permission';
@ -214,7 +215,7 @@
/** /**
* 分享share * 分享share
*/ */
const router = useRouter();
const shareLink = ref<string>(''); const shareLink = ref<string>('');
const shareId = ref<string>(route.query.shareId as string); const shareId = ref<string>(route.query.shareId as string);
const reportId = ref<string>(props.reportId); const reportId = ref<string>(props.reportId);
@ -395,7 +396,14 @@
async function getDetail() { async function getDetail() {
try { try {
if (shareId.value) { if (shareId.value) {
detail.value = await planReportShareDetail(shareId.value, reportId.value); const result = await planReportShareDetail(shareId.value, reportId.value);
if (result.deleted) {
router.push({
name: NOT_FOUND_RESOURCE,
});
} else {
detail.value = result;
}
} else { } else {
detail.value = await getReportDetail(reportId.value); detail.value = await getReportDetail(reportId.value);
} }
@ -445,16 +453,19 @@
]); ]);
watchEffect(async () => { watchEffect(async () => {
if (props.reportId) {
await getDetail();
initOptionsData();
}
});
onMounted(async () => {
nextTick(() => { nextTick(() => {
const editorContent = document.querySelector('.editor-content'); const editorContent = document.querySelector('.editor-content');
useEventListener(editorContent, 'click', () => { useEventListener(editorContent, 'click', () => {
showButton.value = true; showButton.value = true;
}); });
}); });
if (props.reportId) {
await getDetail();
initOptionsData();
}
}); });
</script> </script>
@ -497,4 +508,7 @@
} }
} }
} }
:deep(.rich-wrapper) .halo-rich-text-editor .ProseMirror {
height: 58px;
}
</style> </style>

View File

@ -184,33 +184,27 @@
<template #operation="{ record }"> <template #operation="{ record }">
<div class="flex items-center"> <div class="flex items-center">
<MsButton <div
v-if="record.functionalCaseCount > 0 && hasAnyPermission(['PROJECT_TEST_PLAN:READ+EXECUTE'])" v-if="record.functionalCaseCount > 0 && hasAnyPermission(['PROJECT_TEST_PLAN:READ+EXECUTE'])"
class="!mx-0" class="flex items-center"
@click="openDetail(record.id)"
>{{ t('testPlan.testPlanIndex.execution') }}</MsButton
> >
<a-divider <MsButton class="!mx-0" @click="openDetail(record.id)">{{ t('testPlan.testPlanIndex.execution') }}</MsButton>
v-if="record.functionalCaseCount > 0 && hasAnyPermission(['PROJECT_TEST_PLAN:READ+EXECUTE'])" <a-divider direction="vertical" :margin="8"></a-divider>
direction="vertical" </div>
:margin="8" <div
></a-divider> v-if="hasAnyPermission(['PROJECT_TEST_PLAN:READ+UPDATE']) && record.status !== 'ARCHIVED'"
class="flex items-center"
<MsButton
v-permission="['PROJECT_TEST_PLAN:READ+UPDATE']"
class="!mx-0"
@click="emit('editOrCopy', record.id, false)"
>{{ t('common.edit') }}</MsButton
> >
<a-divider direction="vertical" :margin="8"></a-divider> <MsButton class="!mx-0" @click="emit('editOrCopy', record.id, false)">{{ t('common.edit') }}</MsButton>
<MsButton <a-divider direction="vertical" :margin="8"></a-divider>
v-if="record.functionalCaseCount < 1" </div>
v-permission="['PROJECT_TEST_PLAN:READ+UPDATE']" <div
class="!mx-0" v-if="hasAnyPermission(['PROJECT_TEST_PLAN:READ+ADD']) && record.functionalCaseCount < 1"
@click="emit('editOrCopy', record.id, true)" class="flex items-center"
>{{ t('common.copy') }}</MsButton
> >
<a-divider v-if="record.functionalCaseCount < 1" direction="vertical" :margin="8"></a-divider> <MsButton class="!mx-0" @click="emit('editOrCopy', record.id, true)">{{ t('common.copy') }}</MsButton>
<a-divider v-if="record.functionalCaseCount < 1" direction="vertical" :margin="8"></a-divider>
</div>
<MsTableMoreAction <MsTableMoreAction
:list="getMoreActions(record.status, record.functionalCaseCount)" :list="getMoreActions(record.status, record.functionalCaseCount)"
@ -566,7 +560,7 @@
function getMoreActions(status: planStatusType, useCount: number) { function getMoreActions(status: planStatusType, useCount: number) {
// //
const copyAction = useCount > 0 ? copyActions : []; const copyAction = useCount > 0 && hasAnyPermission(['PROJECT_TEST_PLAN:READ+ADD']) ? copyActions : [];
// //
if (status === 'ARCHIVED' || status === 'PREPARED' || status === 'UNDERWAY') { if (status === 'ARCHIVED' || status === 'PREPARED' || status === 'UNDERWAY') {
return [ return [

View File

@ -4,7 +4,7 @@
v-model:focus-node-key="focusNodeKey" v-model:focus-node-key="focusNodeKey"
:selected-keys="props.selectedKeys" :selected-keys="props.selectedKeys"
:data="testPlanTree" :data="testPlanTree"
:keyword="groupKeyword" :keyword="moduleKeyword"
:node-more-actions="caseMoreActions" :node-more-actions="caseMoreActions"
:expand-all="props.isExpandAll" :expand-all="props.isExpandAll"
:empty-text="t('testPlan.testPlanIndex.planEmptyContent')" :empty-text="t('testPlan.testPlanIndex.planEmptyContent')"
@ -70,6 +70,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, onBeforeMount, ref, watch } from 'vue'; import { computed, onBeforeMount, ref, watch } from 'vue';
import { useVModel } from '@vueuse/core';
import { Message } from '@arco-design/web-vue'; import { Message } from '@arco-design/web-vue';
import MsButton from '@/components/pure/ms-button/index.vue'; import MsButton from '@/components/pure/ms-button/index.vue';
@ -106,13 +107,21 @@
isExpandAll: boolean; // isExpandAll: boolean; //
allNames?: string[]; // name allNames?: string[]; // name
modulesCount?: Record<string, number>; // modulesCount?: Record<string, number>; //
groupKeyword: string;
}>(); }>();
const emits = defineEmits(['update:selectedKeys', 'planTreeNodeSelect', 'init', 'dragUpdate', 'getNodeName']); const emits = defineEmits([
'update:selectedKeys',
'planTreeNodeSelect',
'init',
'dragUpdate',
'getNodeName',
'update:groupKeyword',
]);
const currentProjectId = computed(() => appStore.currentProjectId); const currentProjectId = computed(() => appStore.currentProjectId);
const groupKeyword = ref<string>(''); const moduleKeyword = useVModel(props, 'groupKeyword', emits);
const testPlanTree = ref<ModuleTreeNode[]>([]); const testPlanTree = ref<ModuleTreeNode[]>([]);

View File

@ -153,6 +153,7 @@
planId?: string; planId?: string;
moduleTree?: ModuleTreeNode[]; moduleTree?: ModuleTreeNode[];
isCopy: boolean; isCopy: boolean;
moduleId?: string;
}>(); }>();
const innerVisible = defineModel<boolean>('visible', { const innerVisible = defineModel<boolean>('visible', {
required: true, required: true,
@ -307,6 +308,9 @@
if (val) { if (val) {
form.value = cloneDeep(initForm); form.value = cloneDeep(initForm);
getDetail(); getDetail();
if (!props.planId && props.moduleId) {
form.value.moduleId = props.moduleId === 'all' ? 'root' : props.moduleId;
}
} }
} }
); );

View File

@ -18,16 +18,16 @@
</a-tooltip> </a-tooltip>
</template> </template>
<template #headerRight> <template #headerRight>
<MsButton v-permission="['PROJECT_TEST_PLAN:READ+ASSOCIATION']" type="button" status="default" @click="linkCase"> <MsButton
v-if="hasAnyPermission(['PROJECT_TEST_PLAN:READ+ASSOCIATION']) && detail.status !== 'ARCHIVED'"
type="button"
status="default"
@click="linkCase"
>
<MsIcon type="icon-icon_link-record_outlined1" class="mr-[8px]" /> <MsIcon type="icon-icon_link-record_outlined1" class="mr-[8px]" />
{{ t('ms.case.associate.title') }} {{ t('ms.case.associate.title') }}
</MsButton> </MsButton>
<MsButton <MsButton v-if="isEnableEdit" type="button" status="default" @click="editorCopyHandler(false)">
v-permission="['PROJECT_TEST_PLAN:READ+UPDATE']"
type="button"
status="default"
@click="editorCopyHandler(false)"
>
<MsIcon type="icon-icon_edit_outlined" class="mr-[8px]" /> <MsIcon type="icon-icon_edit_outlined" class="mr-[8px]" />
{{ t('common.edit') }} {{ t('common.edit') }}
</MsButton> </MsButton>
@ -162,6 +162,7 @@
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import useUserStore from '@/store/modules/user'; import useUserStore from '@/store/modules/user';
import { characterLimit } from '@/utils'; import { characterLimit } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import { ModuleTreeNode } from '@/models/common'; import { ModuleTreeNode } from '@/models/common';
import type { PassRateCountDetail, TestPlanDetail, TestPlanItem } from '@/models/testPlan/testPlan'; import type { PassRateCountDetail, TestPlanDetail, TestPlanItem } from '@/models/testPlan/testPlan';
@ -230,6 +231,10 @@
return fullActions.filter((e) => e.eventTag !== 'archive'); return fullActions.filter((e) => e.eventTag !== 'archive');
}); });
const isEnableEdit = computed(() => {
return hasAnyPermission(['PROJECT_TEST_PLAN:READ+UPDATE']) && detail.value.status !== 'ARCHIVED';
});
function getTabBadge(tabKey: string) { function getTabBadge(tabKey: string) {
switch (tabKey) { switch (tabKey) {
case 'featureCase': case 'featureCase':

View File

@ -62,6 +62,7 @@
<TestPlanTree <TestPlanTree
ref="planTreeRef" ref="planTreeRef"
v-model:selected-keys="selectedKeys" v-model:selected-keys="selectedKeys"
v-model:groupKeyword="groupKeyword"
:all-names="rootModulesName" :all-names="rootModulesName"
:active-folder="activeFolder" :active-folder="activeFolder"
:is-expand-all="isExpandAll" :is-expand-all="isExpandAll"
@ -92,6 +93,7 @@
<CreateAndEditPlanDrawer <CreateAndEditPlanDrawer
v-model:visible="showPlanDrawer" v-model:visible="showPlanDrawer"
:plan-id="planId" :plan-id="planId"
:module-id="selectedKeys[0]"
:module-tree="folderTree" :module-tree="folderTree"
:is-copy="isCopy" :is-copy="isCopy"
@close="resetPlanId" @close="resetPlanId"