refactor(功能用例): 优化用例评审脑图查看
This commit is contained in:
parent
43b19e4f03
commit
34ebcd8371
|
@ -5,16 +5,13 @@
|
||||||
v-model:extra-visible="extraVisible"
|
v-model:extra-visible="extraVisible"
|
||||||
v-model:loading="loading"
|
v-model:loading="loading"
|
||||||
v-model:import-json="importJson"
|
v-model:import-json="importJson"
|
||||||
:show-save-button="false"
|
|
||||||
:extract-content-tab-list="extractContentTabList"
|
:extract-content-tab-list="extractContentTabList"
|
||||||
:priority-tooltip="t('caseManagement.caseReview.caseLevel')"
|
:can-show-float-menu="canShowFloatMenu"
|
||||||
:priority-disable-check="priorityDisableCheck"
|
:can-show-priority-menu="false"
|
||||||
:can-show-float-menu="canShowFloatMenu()"
|
|
||||||
:can-show-priority-menu="canShowPriorityMenu()"
|
|
||||||
:can-show-more-menu="showCaseMenu"
|
:can-show-more-menu="showCaseMenu"
|
||||||
:can-show-more-menu-node-operation="false"
|
:can-show-more-menu-node-operation="false"
|
||||||
:more-menu-other-operation-list="moreMenuOtherOperationList"
|
:more-menu-other-operation-list="moreMenuOtherOperationList"
|
||||||
:disabled="!hasEditPermission"
|
disabled
|
||||||
single-tag
|
single-tag
|
||||||
@node-select="handleNodeSelect"
|
@node-select="handleNodeSelect"
|
||||||
>
|
>
|
||||||
|
@ -79,9 +76,9 @@
|
||||||
import MsDescription, { Description } from '@/components/pure/ms-description/index.vue';
|
import MsDescription, { Description } from '@/components/pure/ms-description/index.vue';
|
||||||
import MsMinderEditor from '@/components/pure/ms-minder-editor/minderEditor.vue';
|
import MsMinderEditor from '@/components/pure/ms-minder-editor/minderEditor.vue';
|
||||||
import type { MinderJson, MinderJsonNode, MinderJsonNodeData } from '@/components/pure/ms-minder-editor/props';
|
import type { MinderJson, MinderJsonNode, MinderJsonNodeData } from '@/components/pure/ms-minder-editor/props';
|
||||||
|
import { setPriorityView } from '@/components/pure/ms-minder-editor/script/tool/utils';
|
||||||
import { MsFileItem } from '@/components/pure/ms-upload/types';
|
import { MsFileItem } from '@/components/pure/ms-upload/types';
|
||||||
import Attachment from '@/components/business/ms-minders/featureCaseMinder/attachment.vue';
|
import Attachment from '@/components/business/ms-minders/featureCaseMinder/attachment.vue';
|
||||||
import useMinderBaseApi from '@/components/business/ms-minders/featureCaseMinder/useMinderBaseApi';
|
|
||||||
import ReviewCommentList from '@/views/case-management/caseManagementFeature/components/tabContent/tabComment/reviewCommentList.vue';
|
import ReviewCommentList from '@/views/case-management/caseManagementFeature/components/tabContent/tabComment/reviewCommentList.vue';
|
||||||
|
|
||||||
import { getCaseReviewHistoryList, getCaseReviewMinder } from '@/api/modules/case-management/caseReview';
|
import { getCaseReviewHistoryList, getCaseReviewMinder } from '@/api/modules/case-management/caseReview';
|
||||||
|
@ -90,7 +87,6 @@
|
||||||
import useAppStore from '@/store/modules/app';
|
import useAppStore from '@/store/modules/app';
|
||||||
import useMinderStore from '@/store/modules/components/minder-editor/index';
|
import useMinderStore from '@/store/modules/components/minder-editor/index';
|
||||||
import { findNodeByKey, mapTree, replaceNodeInTree } from '@/utils';
|
import { findNodeByKey, mapTree, replaceNodeInTree } from '@/utils';
|
||||||
import { hasAnyPermission } from '@/utils/permission';
|
|
||||||
|
|
||||||
import { ReviewHistoryItem, ReviewPassRule } from '@/models/caseManagement/caseReview';
|
import { ReviewHistoryItem, ReviewPassRule } from '@/models/caseManagement/caseReview';
|
||||||
import { ModuleTreeNode } from '@/models/common';
|
import { ModuleTreeNode } from '@/models/common';
|
||||||
|
@ -113,10 +109,8 @@
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const minderStore = useMinderStore();
|
const minderStore = useMinderStore();
|
||||||
|
|
||||||
const hasEditPermission = hasAnyPermission(['FUNCTIONAL_CASE:READ+MINDER']);
|
const caseTag = t('common.case');
|
||||||
const { caseTag, moduleTag, canShowPriorityMenu, priorityDisableCheck } = useMinderBaseApi({
|
const moduleTag = t('common.module');
|
||||||
hasEditPermission,
|
|
||||||
});
|
|
||||||
const importJson = ref<MinderJson>({
|
const importJson = ref<MinderJson>({
|
||||||
root: {} as MinderJsonNode,
|
root: {} as MinderJsonNode,
|
||||||
template: 'default',
|
template: 'default',
|
||||||
|
@ -137,8 +131,6 @@
|
||||||
resource: props.modulesCount[e.id] !== undefined ? [moduleTag] : e.data?.resource,
|
resource: props.modulesCount[e.id] !== undefined ? [moduleTag] : e.data?.resource,
|
||||||
expandState: e.level === 0 ? 'expand' : 'collapse',
|
expandState: e.level === 0 ? 'expand' : 'collapse',
|
||||||
count: props.modulesCount[e.id],
|
count: props.modulesCount[e.id],
|
||||||
isNew: false,
|
|
||||||
changed: false,
|
|
||||||
},
|
},
|
||||||
children:
|
children:
|
||||||
props.modulesCount[e.id] > 0 && !e.children?.length
|
props.modulesCount[e.id] > 0 && !e.children?.length
|
||||||
|
@ -148,8 +140,6 @@
|
||||||
id: 'fakeNode',
|
id: 'fakeNode',
|
||||||
text: 'fakeNode',
|
text: 'fakeNode',
|
||||||
resource: ['fakeNode'],
|
resource: ['fakeNode'],
|
||||||
isNew: false,
|
|
||||||
changed: false,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -217,6 +207,37 @@
|
||||||
data.isLoaded = true;
|
data.isLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建节点
|
||||||
|
* @param data 节点数据
|
||||||
|
* @param parentNode 父节点
|
||||||
|
*/
|
||||||
|
function createNode(data?: MinderJsonNodeData, parentNode?: MinderJsonNode) {
|
||||||
|
return window.minder.createNode(
|
||||||
|
{
|
||||||
|
...data,
|
||||||
|
expandState: 'collapse',
|
||||||
|
},
|
||||||
|
parentNode
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归渲染子节点及其子节点
|
||||||
|
* @param parentNode - 父节点
|
||||||
|
* @param children - 子节点数组
|
||||||
|
*/
|
||||||
|
function renderSubNodes(parentNode: MinderJsonNode, children?: MinderJsonNode[]) {
|
||||||
|
return (
|
||||||
|
children?.map((item: MinderJsonNode) => {
|
||||||
|
const grandChild = createNode(item.data, parentNode);
|
||||||
|
const greatGrandChildren = renderSubNodes(grandChild, item.children);
|
||||||
|
window.minder.renderNodeBatch(greatGrandChildren);
|
||||||
|
return grandChild;
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载模块节点下的用例节点
|
* 加载模块节点下的用例节点
|
||||||
* @param selectedNode 选中节点
|
* @param selectedNode 选中节点
|
||||||
|
@ -245,53 +266,23 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 渲染节点
|
||||||
let waitingRenderNodes: MinderJsonNode[] = [];
|
let waitingRenderNodes: MinderJsonNode[] = [];
|
||||||
list.forEach((e) => {
|
list.forEach((e) => {
|
||||||
// 用例节点
|
// 用例节点
|
||||||
const child = window.minder.createNode(
|
const child = createNode(e.data, node);
|
||||||
{
|
|
||||||
...e.data,
|
|
||||||
expandState: 'collapse',
|
|
||||||
isNew: false,
|
|
||||||
},
|
|
||||||
node
|
|
||||||
);
|
|
||||||
waitingRenderNodes.push(child);
|
waitingRenderNodes.push(child);
|
||||||
const grandChildren: MinderJsonNode[] = [];
|
// 前置/步骤/备注/预期结果节点
|
||||||
e.children?.forEach((item) => {
|
const grandChildren = renderSubNodes(child, e.children);
|
||||||
// 前置/步骤/备注节点
|
|
||||||
const grandChild = window.minder.createNode(
|
|
||||||
{
|
|
||||||
...item.data,
|
|
||||||
expandState: 'collapse',
|
|
||||||
isNew: false,
|
|
||||||
},
|
|
||||||
child
|
|
||||||
);
|
|
||||||
grandChildren.push(grandChild);
|
|
||||||
const greatGrandChildren: MinderJsonNode[] = [];
|
|
||||||
item.children?.forEach((subItem) => {
|
|
||||||
// 预期结果节点
|
|
||||||
const greatGrandChild = window.minder.createNode(
|
|
||||||
{
|
|
||||||
...subItem.data,
|
|
||||||
expandState: 'collapse',
|
|
||||||
isNew: false,
|
|
||||||
},
|
|
||||||
grandChild
|
|
||||||
);
|
|
||||||
greatGrandChildren.push(greatGrandChild);
|
|
||||||
});
|
|
||||||
window.minder.renderNodeBatch(greatGrandChildren);
|
|
||||||
});
|
|
||||||
window.minder.renderNodeBatch(grandChildren);
|
window.minder.renderNodeBatch(grandChildren);
|
||||||
});
|
});
|
||||||
|
|
||||||
node.expand();
|
node.expand();
|
||||||
if (node.children && node.children.length > 0) {
|
if (node.children && node.children.length > 0) {
|
||||||
waitingRenderNodes = waitingRenderNodes.concat(node.children);
|
waitingRenderNodes = waitingRenderNodes.concat(node.children);
|
||||||
}
|
}
|
||||||
|
// 更多用例节点
|
||||||
if (total > list.length * (loadMoreCurrent || 1)) {
|
if (total > list.length * (loadMoreCurrent || 1)) {
|
||||||
// 有更多用例
|
|
||||||
const moreNode = window.minder.createNode(
|
const moreNode = window.minder.createNode(
|
||||||
{
|
{
|
||||||
id: `tmp-${data.id}`,
|
id: `tmp-${data.id}`,
|
||||||
|
@ -347,38 +338,6 @@
|
||||||
fileList.value = [];
|
fileList.value = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const canShowEnterNode = ref(false);
|
|
||||||
const showCaseMenu = ref(false);
|
|
||||||
const moreMenuOtherOperationList = [
|
|
||||||
{
|
|
||||||
value: 'changeReviewer',
|
|
||||||
label: t('caseManagement.caseReview.changeReviewer'),
|
|
||||||
permission: ['CASE_REVIEW:READ+UPDATE'],
|
|
||||||
onClick: () => {
|
|
||||||
// TODO 操作
|
|
||||||
console.log('🤔️ =>', t('caseManagement.caseReview.changeReviewer'));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'reReview',
|
|
||||||
label: t('caseManagement.caseReview.reReview'),
|
|
||||||
permission: ['CASE_REVIEW:READ+UPDATE'],
|
|
||||||
onClick: () => {
|
|
||||||
// TODO 操作
|
|
||||||
console.log('🤔️ =>', t('caseManagement.caseReview.reReview'));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: 'disassociate',
|
|
||||||
label: t('caseManagement.caseReview.disassociate'),
|
|
||||||
permission: ['CASE_REVIEW:READ+RELEVANCE'],
|
|
||||||
onClick: () => {
|
|
||||||
// TODO 操作
|
|
||||||
console.log('🤔️ =>', t('caseManagement.caseReview.disassociate'));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化用例详情
|
* 初始化用例详情
|
||||||
* @param data 节点数据
|
* @param data 节点数据
|
||||||
|
@ -464,26 +423,38 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
const canShowFloatMenu = ref(false); // 是否展示浮动菜单
|
||||||
* 是否可展示浮动菜单
|
const canShowEnterNode = ref(false);
|
||||||
*/
|
const showCaseMenu = ref(false);
|
||||||
function canShowFloatMenu() {
|
const moreMenuOtherOperationList = [
|
||||||
if (window.minder) {
|
{
|
||||||
const node: MinderJsonNode = window.minder.getSelectedNode();
|
value: 'changeReviewer',
|
||||||
// TODO 当前根节点不展示浮动菜单
|
label: t('caseManagement.caseReview.changeReviewer'),
|
||||||
if (node?.data?.type === 'tmp') {
|
permission: ['CASE_REVIEW:READ+UPDATE'],
|
||||||
return false;
|
onClick: () => {
|
||||||
}
|
// TODO 操作
|
||||||
if (!hasEditPermission) {
|
console.log('🤔️ =>', t('caseManagement.caseReview.changeReviewer'));
|
||||||
if (node?.data?.resource?.includes(caseTag)) {
|
},
|
||||||
// 没有编辑权限情况下,用例节点可展示浮动菜单(需要展示详情按钮)
|
},
|
||||||
return true;
|
{
|
||||||
}
|
value: 'reReview',
|
||||||
return false;
|
label: t('caseManagement.caseReview.reReview'),
|
||||||
}
|
permission: ['CASE_REVIEW:READ+UPDATE'],
|
||||||
}
|
onClick: () => {
|
||||||
return true;
|
// TODO 操作
|
||||||
}
|
console.log('🤔️ =>', t('caseManagement.caseReview.reReview'));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'disassociate',
|
||||||
|
label: t('caseManagement.caseReview.disassociate'),
|
||||||
|
permission: ['CASE_REVIEW:READ+RELEVANCE'],
|
||||||
|
onClick: () => {
|
||||||
|
// TODO 操作
|
||||||
|
console.log('🤔️ =>', t('caseManagement.caseReview.disassociate'));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理节点选中
|
* 处理节点选中
|
||||||
|
@ -493,11 +464,23 @@
|
||||||
const { data } = node;
|
const { data } = node;
|
||||||
// 点击更多节点,加载更多用例
|
// 点击更多节点,加载更多用例
|
||||||
if (data?.type === 'tmp' && node.parent?.data?.resource?.includes(moduleTag)) {
|
if (data?.type === 'tmp' && node.parent?.data?.resource?.includes(moduleTag)) {
|
||||||
|
canShowFloatMenu.value = false;
|
||||||
await initNodeCases(node.parent, data.current);
|
await initNodeCases(node.parent, data.current);
|
||||||
|
setPriorityView(true, 'P');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 模块节点且有子节点且非根节点,可展示进入节点菜单
|
// 展示浮动菜单: 模块节点且非根节点、用例节点
|
||||||
if (data?.resource?.includes(moduleTag) && (node.children || []).length > 0 && node.type !== 'root') {
|
if (
|
||||||
|
node?.data?.resource?.includes(caseTag) ||
|
||||||
|
(node?.data?.resource?.includes(moduleTag) && node.type !== 'root')
|
||||||
|
) {
|
||||||
|
canShowFloatMenu.value = true;
|
||||||
|
} else {
|
||||||
|
canShowFloatMenu.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 展示进入节点菜单: 模块节点且有子节点且非根节点
|
||||||
|
if (data?.resource?.includes(moduleTag) && (node.children || []).length > 0) {
|
||||||
canShowEnterNode.value = true;
|
canShowEnterNode.value = true;
|
||||||
} else {
|
} else {
|
||||||
canShowEnterNode.value = false;
|
canShowEnterNode.value = false;
|
||||||
|
@ -519,6 +502,7 @@
|
||||||
resetExtractInfo();
|
resetExtractInfo();
|
||||||
removeFakeNode(node, 'fakeNode');
|
removeFakeNode(node, 'fakeNode');
|
||||||
}
|
}
|
||||||
|
setPriorityView(true, 'P');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -14,14 +14,7 @@
|
||||||
<MsIcon type="icon-icon_full_screen_one" class="text-[var(--color-text-4)]" />
|
<MsIcon type="icon-icon_full_screen_one" class="text-[var(--color-text-4)]" />
|
||||||
</MsButton>
|
</MsButton>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-button
|
<a-button v-if="!props.disabled" type="outline" class="px-[8px] py-[2px] text-[12px]" size="small" @click="save">
|
||||||
v-if="props.showSaveButton"
|
|
||||||
type="outline"
|
|
||||||
:disabled="props.disabled"
|
|
||||||
class="px-[8px] py-[2px] text-[12px]"
|
|
||||||
size="small"
|
|
||||||
@click="save"
|
|
||||||
>
|
|
||||||
{{ t('minder.main.main.save') }}
|
{{ t('minder.main.main.save') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -39,7 +32,6 @@
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
iconButtons?: MinderIconButtonItem[];
|
iconButtons?: MinderIconButtonItem[];
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
showSaveButton?: boolean;
|
|
||||||
}>();
|
}>();
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'click', eventTag: string): void;
|
(e: 'click', eventTag: string): void;
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div ref="mec" class="ms-minder-container">
|
<div ref="mec" class="ms-minder-container">
|
||||||
<minderHeader
|
<minderHeader :icon-buttons="props.iconButtons" :disabled="props.disabled" @save="save" />
|
||||||
:icon-buttons="props.iconButtons"
|
|
||||||
:disabled="props.disabled"
|
|
||||||
:show-save-button="props.showSaveButton"
|
|
||||||
@save="save"
|
|
||||||
/>
|
|
||||||
<Navigator />
|
<Navigator />
|
||||||
<div
|
<div
|
||||||
v-if="currentTreePath?.length > 0"
|
v-if="currentTreePath?.length > 0"
|
||||||
|
|
|
@ -66,11 +66,6 @@ export const headerProps = {
|
||||||
iconButtons: {
|
iconButtons: {
|
||||||
type: [] as PropType<MinderIconButtonItem[]>,
|
type: [] as PropType<MinderIconButtonItem[]>,
|
||||||
},
|
},
|
||||||
// 是否显示保存按钮
|
|
||||||
showSaveButton: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const priorityProps = {
|
export const priorityProps = {
|
||||||
|
|
Loading…
Reference in New Issue