feat(功能用例): 用例评审脑图右侧tab

This commit is contained in:
teukkk 2024-07-03 19:05:40 +08:00 committed by 刘瑞斌
parent 2fc5db0745
commit 3e49eab864
11 changed files with 93 additions and 40 deletions

View File

@ -1,4 +1,5 @@
@import url('./arco-reset.less');
@import url('@/components/business/ms-comment/style.less');
:root {
--border-radius-mini: 2px;
}

View File

@ -5,8 +5,8 @@
border-radius: 4px;
}
.markdown-body {
font-size: 14px;
line-height: 22px;
font-size: 14px !important;
line-height: 22px !important;
color: var(--color-text-2) !important;
ul {
list-style: disc !important;

View File

@ -8,22 +8,17 @@
:extract-content-tab-list="extractContentTabList"
:can-show-float-menu="canShowFloatMenu"
:can-show-priority-menu="false"
:can-show-more-menu="showCaseMenu"
:can-show-more-menu="canShowFloatMenu"
:can-show-enter-node="canShowEnterNode"
:can-show-more-menu-node-operation="false"
:more-menu-other-operation-list="moreMenuOtherOperationList"
:more-menu-other-operation-list="canShowEnterNode ? [] : moreMenuOtherOperationList"
disabled
single-tag
@node-select="handleNodeSelect"
>
<template #extractMenu>
<!-- 进入当前节点 -->
<template v-if="canShowEnterNode">
<MsButton type="text" class="!text-[var(--color-text-1)]" @click="handleEnterNode">
{{ t('minder.hotboxMenu.enterNode') }}
</MsButton>
</template>
<template v-if="showCaseMenu">
<!-- 评审 查看详情 更多 -->
<!-- 评审 查看详情 -->
<a-tooltip :content="t('caseManagement.caseReview.review')">
<MsButton type="icon" class="ms-minder-node-float-menu-icon-button">
<MsIcon type="icon-icon_audit" class="text-[var(--color-text-4)]" />
@ -46,6 +41,7 @@
:loading="baseInfoLoading"
:descriptions="descriptions"
label-width="90px"
class="pl-[16px]"
/>
<Attachment
v-else-if="activeExtraKey === 'attachment'"
@ -53,15 +49,20 @@
not-show-add-button
:active-case="activeCaseInfo"
/>
<div v-else>
<div v-if="props.reviewPassRule === 'MULTIPLE'" class="flex justify-between">
<div v-else class="pl-[16px]">
<div v-if="props.reviewPassRule === 'MULTIPLE'" class="mb-[8px] flex justify-between">
<div class="text-[12px]">
<span class="text-[var(--color-text-4)]">{{ t('caseManagement.caseReview.progress') }}</span>
{{ props.passRate }}
{{ props.reviewProgress }}
</div>
<!-- TODO 下拉 -->
<!-- TODO 总结果 hover展示单个 -->
<ReviewResult :status="activeCaseInfo.reviewStatus" />
</div>
<ReviewCommentList :review-comment-list="reviewHistoryList" active-comment="reviewComment" />
<ReviewCommentList
:review-comment-list="reviewHistoryList"
active-comment="reviewComment"
not-show-review-name
/>
</div>
</template>
</MsMinderEditor>
@ -80,6 +81,7 @@
import { MsFileItem } from '@/components/pure/ms-upload/types';
import Attachment from '@/components/business/ms-minders/featureCaseMinder/attachment.vue';
import ReviewCommentList from '@/views/case-management/caseManagementFeature/components/tabContent/tabComment/reviewCommentList.vue';
import ReviewResult from '@/views/case-management/caseReview/components/reviewResult.vue';
import { getCaseReviewHistoryList, getCaseReviewMinder } from '@/api/modules/case-management/caseReview';
import { getCaseDetail } from '@/api/modules/case-management/featureCase';
@ -99,7 +101,7 @@
modulesCount: Record<string, number>; //
viewFlag: boolean; //
viewStatusFlag: boolean; //
passRate: string;
reviewProgress: string;
reviewPassRule: ReviewPassRule; //
moduleTree: ModuleTreeNode[];
}>();
@ -345,7 +347,7 @@
async function initCaseDetail(data: MinderJsonNodeData) {
try {
baseInfoLoading.value = true;
const res = await getCaseDetail(data?.id || activeCaseInfo.value.id);
const res = await getCaseDetail(data?.caseId || activeCaseInfo.value.caseId);
activeCaseInfo.value = res;
//
descriptions.value = [
@ -401,7 +403,7 @@
const reviewHistoryList = ref<ReviewHistoryItem[]>([]);
async function initReviewHistoryList(data: MinderJsonNodeData) {
try {
const res = await getCaseReviewHistoryList(route.query.id as string, data?.id || activeCaseInfo.value.id);
const res = await getCaseReviewHistoryList(route.query.id as string, data?.caseId || activeCaseInfo.value.caseId);
reviewHistoryList.value = res;
} catch (error) {
// eslint-disable-next-line no-console
@ -505,14 +507,6 @@
setPriorityView(true, 'P');
}
/**
* 进入当前节点
*/
function handleEnterNode() {
const selectedNodes: MinderJsonNode[] = window.minder.getSelectedNodes();
minderStore.dispatchEvent(MinderEventName.ENTER_NODE, undefined, undefined, undefined, [selectedNodes[0]]);
}
defineExpose({
initNodeCases,
});

View File

@ -134,13 +134,13 @@
</MsButton>
</a-tooltip>
<template #content>
<a-doption v-if="props.canShowEnterNode" value="enterNode">
<div class="flex items-center">
<div>{{ t('minder.hotboxMenu.enterNode') }}</div>
<!-- <div class="ml-[4px] text-[var(--color-text-4)]">(Ctrl+ Enter)</div> -->
</div>
</a-doption>
<template v-if="props.canShowMoreMenuNodeOperation">
<a-doption v-if="props.canShowEnterNode" value="enterNode">
<div class="flex items-center">
<div>{{ t('minder.hotboxMenu.enterNode') }}</div>
<!-- <div class="ml-[4px] text-[var(--color-text-4)]">(Ctrl+ Enter)</div> -->
</div>
</a-doption>
<a-doption value="copy">
<div class="flex items-center">
<div>{{ t('minder.hotboxMenu.copy') }}</div>

View File

@ -163,6 +163,10 @@
width: 0;
transition: all 300ms ease-in-out;
:deep(.ms-tab--button-item) {
flex: 1;
text-align: center;
}
.ms-minder-editor-extra-content {
@apply relative flex-1 overflow-y-auto;
.ms-scroll-bar();

View File

@ -155,7 +155,7 @@ export const floatMenuProps = {
type: Boolean,
default: true,
},
// 是否显示更多菜单里的[进入、复制、粘贴、剪切、删除]操作
// 是否显示更多菜单里的[复制、粘贴、剪切、删除]操作
canShowMoreMenuNodeOperation: {
type: Boolean,
default: true,

View File

@ -37,7 +37,7 @@
{{ t('common.fail') }}
</div>
</div>
<div class="markdown-body" v-html="item.contentText"></div>
<div class="markdown-body mt-[4px]" v-html="item.contentText"></div>
<div class="mt-[8px] flex text-[12px] leading-[16px] text-[var(--color-text-4)]">
{{ dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss') }}
<div v-if="props.activeComment === 'reviewComment'">
@ -47,7 +47,7 @@
</span>
<span
v-else
v-if="!item.deleted && !props.notShowReviewName"
class="one-line-text ml-[16px] max-w-[300px] cursor-pointer break-words break-all text-[rgb(var(--primary-5))]"
@click="review(item)"
>
@ -94,6 +94,7 @@
const props = defineProps<{
reviewCommentList: any[];
activeComment: string;
notShowReviewName?: boolean;
}>();
const router = useRouter();

View File

@ -140,7 +140,7 @@
:view-status-flag="onlyMineStatus"
:module-tree="props.moduleTree"
:modules-count="props.modulesCount"
:pass-rate="props.passRate"
:review-progress="props.reviewProgress"
:review-pass-rule="props.reviewPassRule"
/>
</div>
@ -352,7 +352,7 @@
offspringIds: string[]; // id
moduleTree: ModuleTreeNode[];
modulesCount: Record<string, number>; //
passRate: string;
reviewProgress: string; //
}>();
const emit = defineEmits(['init', 'refresh', 'link']);

View File

@ -119,6 +119,10 @@
((props.reviewDetail.passCount + props.reviewDetail.unPassCount) / props.reviewDetail.caseCount) * 100;
return `${Number.isNaN(result) ? 0 : result.toFixed(2)}%`;
});
defineExpose({
progress,
});
</script>
<style lang="less" scoped>

View File

@ -0,0 +1,42 @@
<template>
<div v-if="props.status" class="flex items-center">
<MsIcon
:type="resultMap[props.status]?.icon || ''"
class="mr-[4px]"
:size="16"
:style="{ color: resultMap[props.status]?.color }"
></MsIcon>
{{ t(resultMap[props.status]?.label) }}
</div>
</template>
<script setup lang="ts">
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
import { reviewResultMap } from '@/config/caseManagement';
import { useI18n } from '@/hooks/useI18n';
import { ReviewResult } from '@/models/caseManagement/caseReview';
const { t } = useI18n();
const props = defineProps<{
status?: ReviewResult;
isPart?: boolean; // true'UNDER_REVIEWED'''
}>();
const resultMap = computed(() =>
props.isPart
? {
...reviewResultMap,
...{
UNDER_REVIEWED: {
label: 'caseManagement.caseReview.suggestion',
color: 'rgb(var(--warning-6))',
icon: 'icon-icon_warning_filled',
},
},
}
: reviewResultMap
);
</script>

View File

@ -89,7 +89,12 @@
</span>
</div>
</div>
<passRateLine :review-detail="reviewDetail" height="8px" radius="var(--border-radius-mini)" />
<passRateLine
ref="passRateLineRef"
:review-detail="reviewDetail"
height="8px"
radius="var(--border-radius-mini)"
/>
</div>
</template>
<!-- <div class="px-[24px]">
@ -121,7 +126,7 @@
:review-pass-rule="reviewDetail.reviewPassRule"
:offspring-ids="offspringIds"
:modules-count="modulesCount"
:pass-rate="reviewDetail.status === 'PREPARED' ? '-' : `${reviewDetail.passRate}%`"
:review-progress="reviewProgress"
:module-tree="moduleTree"
@init="initModulesCount"
@refresh="handleRefresh"
@ -191,6 +196,8 @@
...reviewDefaultDetail,
});
const reviewId = ref(route.query.id as string);
const passRateLineRef = ref<InstanceType<typeof passRateLine>>();
const reviewProgress = computed(() => passRateLineRef.value?.progress ?? '');
async function initDetail() {
try {