feat(测试用例): 用例评审-详情-多人评审的评审结果下拉

This commit is contained in:
teukkk 2024-07-25 15:23:28 +08:00 committed by 刘瑞斌
parent 134d8b09eb
commit 2de8b72aa4
3 changed files with 110 additions and 55 deletions

View File

@ -0,0 +1,76 @@
<template>
<a-trigger
v-model:popup-visible="statusVisible"
content-class="review-result-trigger-content"
trigger="click"
position="br"
:popup-translate="[0, 4]"
>
<div
:class="`overall-review-result flex cursor-pointer items-center rounded p-[4px] hover:bg-[var(--color-text-n9)]
${statusVisible ? 'bg-[var(--color-text-n9)]' : ''} `"
>
<ReviewResult :status="reviewHistoryStatus" :class="[`text-[${props.size}px]`]" :icon-size="props.size" />
<MsIcon type="icon-icon_expand-down_filled" :size="props.size" class="ml-[4px] text-[var(--color-text-4)]" />
</div>
<template #content>
<div v-for="item in reviewUserStatusList" :key="item.id" class="my-[4px] flex justify-between">
<div class="one-line-text max-w-[72px]">
{{ item.id }}
</div>
<ReviewResult
:status="item.name as ReviewResultStatus"
is-part
:class="[`text-[${props.size}px]`]"
:icon-size="props.size"
/>
</div>
<MsEmpty v-if="!reviewUserStatusList.length" />
</template>
</a-trigger>
</template>
<script setup lang="ts">
import MsEmpty from '@/components/pure/ms-empty/index.vue';
import ReviewResult from '@/views/case-management/caseReview/components/reviewResult.vue';
import { getReviewerAndStatus } from '@/api/modules/case-management/caseReview';
import { OptionItem } from '@/api/modules/message/index';
import { ReviewResult as ReviewResultStatus } from '@/models/caseManagement/caseReview';
const props = defineProps<{
size?: number;
}>();
const statusVisible = ref(false);
const reviewHistoryStatus = ref<ReviewResultStatus>();
const reviewUserStatusList = ref<OptionItem[]>([]); //
async function initReviewerAndStatus(reviewId: string, caseId: string) {
try {
const res = await getReviewerAndStatus(reviewId, caseId);
reviewUserStatusList.value = res.reviewerStatus;
reviewHistoryStatus.value = res.status as ReviewResultStatus;
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
}
defineExpose({
initReviewerAndStatus,
});
</script>
<style lang="less">
.review-result-trigger-content {
padding: 6px;
width: 150px;
max-height: 192px;
border-radius: var(--border-radius-medium);
box-shadow: 0 -1px 4px rgb(2 2 2 / 10%);
@apply overflow-y-auto overflow-x-hidden bg-white;
.ms-scroll-bar();
}
</style>

View File

@ -78,39 +78,13 @@
disabled
:active-case="activeCaseInfo"
/>
<div v-else class="pl-[16px]">
<div v-show="activeExtraKey === 'history'" class="pl-[16px]">
<div v-if="props.reviewPassRule === 'MULTIPLE'" class="mb-[8px] flex items-center justify-between">
<div class="text-[12px]">
<span class="text-[var(--color-text-4)]">{{ t('caseManagement.caseReview.progress') }}</span>
{{ props.reviewProgress }}
</div>
<a-trigger v-model:popup-visible="statusVisible" trigger="click" position="br" :popup-translate="[0, 4]">
<div
:class="`flex cursor-pointer items-center rounded p-[4px] hover:bg-[var(--color-text-n9)]
${statusVisible ? 'bg-[var(--color-text-n9)]' : ''} `"
>
<ReviewResult :status="reviewHistoryStatus" class="text-[12px]" :icon-size="12" />
<MsIcon type="icon-icon_expand-down_filled" size="12" class="ml-[4px] text-[var(--color-text-4)]" />
</div>
<template #content>
<div
class="trigger-content w-[150px] rounded-[var(--border-radius-medium)] bg-white p-[6px] shadow-[0_-1px_4px_rgba(2,2,2,0.1)]"
>
<div v-for="item in reviewUserStatusList" :key="item.id" class="my-[4px] flex justify-between">
<div class="one-line-text max-w-[80px]">
{{ item.id }}
</div>
<ReviewResult
:status="item.name as ReviewResultStatus"
is-part
class="text-[12px]"
:icon-size="12"
/>
</div>
<MsEmpty v-if="!reviewUserStatusList.length" />
</div>
</template>
</a-trigger>
<ReviewStatusTrigger ref="reviewStatusTriggerRef" :size="12" />
</div>
<ReviewCommentList
:review-comment-list="reviewHistoryList"
@ -128,7 +102,6 @@
import MsButton from '@/components/pure/ms-button/index.vue';
import MsDescription, { Description } from '@/components/pure/ms-description/index.vue';
import MsEmpty from '@/components/pure/ms-empty/index.vue';
import MsMinderEditor from '@/components/pure/ms-minder-editor/minderEditor.vue';
import type { MinderJson, MinderJsonNode, MinderJsonNodeData } from '@/components/pure/ms-minder-editor/props';
import {
@ -138,18 +111,16 @@
} from '@/components/pure/ms-minder-editor/script/tool/utils';
import { MsFileItem } from '@/components/pure/ms-upload/types';
import Attachment from '@/components/business/ms-minders/featureCaseMinder/attachment.vue';
import ReviewStatusTrigger from './components/reviewStatusTrigger.vue';
import ReviewCommentList from '@/views/case-management/caseManagementFeature/components/tabContent/tabComment/reviewCommentList.vue';
import ReviewResult from '@/views/case-management/caseReview/components/reviewResult.vue';
import ReviewSubmit from '@/views/case-management/caseReview/components/reviewSubmit.vue';
import {
getCaseReviewerList,
getCaseReviewHistoryList,
getCaseReviewMinder,
getReviewerAndStatus,
} from '@/api/modules/case-management/caseReview';
import { getCaseDetail } from '@/api/modules/case-management/featureCase';
import { OptionItem } from '@/api/modules/message/index';
import { useI18n } from '@/hooks/useI18n';
import { useUserStore } from '@/store';
import useAppStore from '@/store/modules/app';
@ -162,7 +133,6 @@
CaseReviewFunctionalCaseUserItem,
ReviewHistoryItem,
ReviewPassRule,
ReviewResult as ReviewResultStatus,
} from '@/models/caseManagement/caseReview';
import { ModuleTreeNode } from '@/models/common';
import { StartReviewStatus } from '@/enums/caseEnum';
@ -479,9 +449,6 @@
}
const reviewHistoryList = ref<ReviewHistoryItem[]>([]); //
const reviewHistoryStatus = ref<ReviewResultStatus>();
const reviewUserStatusList = ref<OptionItem[]>([]); //
const statusVisible = ref(false);
async function initReviewHistoryList(data: MinderJsonNodeData) {
try {
const res = await getCaseReviewHistoryList(route.query.id as string, data?.caseId || activeCaseInfo.value.caseId);
@ -491,20 +458,11 @@
console.log(error);
}
}
async function initReviewerAndStatus(data: MinderJsonNodeData) {
try {
const res = await getReviewerAndStatus(route.query.id as string, data?.caseId || activeCaseInfo.value.caseId);
reviewUserStatusList.value = res.reviewerStatus;
reviewHistoryStatus.value = res.status as ReviewResultStatus;
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
}
/**
* 切换用例详情显示
*/
const reviewStatusTriggerRef = ref<InstanceType<typeof ReviewStatusTrigger>>();
async function toggleDetail(val?: boolean) {
extraVisible.value = val !== undefined ? val : !extraVisible.value;
const node: MinderJsonNode = window.minder.getSelectedNode();
@ -513,7 +471,10 @@
activeExtraKey.value = 'history';
initCaseDetail(data);
initReviewHistoryList(data);
initReviewerAndStatus(data);
reviewStatusTriggerRef.value?.initReviewerAndStatus(
route.query.id as string,
data?.caseId || activeCaseInfo.value.caseId
);
}
}
@ -685,9 +646,4 @@
:deep(.comment-list-item-name) {
max-width: 200px;
}
.trigger-content {
max-height: 192px;
@apply overflow-y-auto overflow-x-hidden;
.ms-scroll-bar();
}
</style>

View File

@ -133,7 +133,11 @@
{{ t('caseManagement.caseReview.reviewResult') }}
</div>
<div class="case-detail-value">
<div v-if="reviewResultMap[activeCaseReviewStatus as ReviewResult]" class="flex items-center gap-[4px]">
<ReviewStatusTrigger v-if="reviewDetail.reviewPassRule === 'MULTIPLE'" ref="reviewStatusTriggerRef" />
<div
v-if="reviewResultMap[activeCaseReviewStatus as ReviewResult] && reviewDetail.reviewPassRule !== 'MULTIPLE'"
class="flex items-center gap-[4px]"
>
<MsIcon
:type="reviewResultMap[activeCaseReviewStatus as ReviewResult].icon"
:style="{
@ -289,6 +293,7 @@
import MsPagination from '@/components/pure/ms-pagination/index';
import caseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
import type { CaseLevel } from '@/components/business/ms-case-associate/types';
import ReviewStatusTrigger from '@/components/business/ms-minders/caseReviewMinder/components/reviewStatusTrigger.vue';
import caseTabDemand from '../caseManagementFeature/components/tabContent/tabDemand/associatedDemandTable.vue';
import caseTabDetail from '../caseManagementFeature/components/tabContent/tabDetail.vue';
import EditCaseDetailDrawer from './components/editCaseDetailDrawer.vue';
@ -511,10 +516,16 @@
}
}
const reviewStatusTriggerRef = ref<InstanceType<typeof ReviewStatusTrigger>>();
function initReviewerAndStatus() {
reviewStatusTriggerRef.value?.initReviewerAndStatus(reviewId.value, activeCaseId.value);
}
watch(
() => activeCaseId.value,
() => {
loadCaseDetail();
initReviewerAndStatus();
initReviewHistoryList();
}
);
@ -552,12 +563,14 @@
loadCaseDetail();
initReviewHistoryList();
loadCaseList();
initReviewerAndStatus();
}
} else {
//
loadCaseDetail();
initReviewHistoryList();
loadCaseList();
initReviewerAndStatus();
}
}
@ -568,7 +581,7 @@
loadCaseDetail();
}
onBeforeMount(() => {
onBeforeMount(async () => {
const lastPageParams = window.history.state.params ? JSON.parse(window.history.state.params) : null; //
if (lastPageParams) {
const {
@ -598,8 +611,9 @@
} else {
keyword.value = route.query.reviewId as string;
}
initDetail();
await initDetail();
loadCase();
initReviewerAndStatus();
if (showTab.value === 'detail') {
initReviewHistoryList();
}
@ -659,4 +673,13 @@
@apply inline-flex;
}
}
:deep(.overall-review-result) {
padding: 0;
}
</style>
<style lang="less">
.review-result-trigger-content {
width: 160px;
}
</style>