feat(功能用例): 用例评审脑图操作-更多

This commit is contained in:
teukkk 2024-07-05 16:33:00 +08:00 committed by 刘瑞斌
parent 2510bcd24e
commit 07d1134f52
3 changed files with 125 additions and 61 deletions

View File

@ -65,7 +65,7 @@
</div>
<template #content>
<div
class="trigger-content rounded-[var(--border-radius-medium)] bg-white p-[6px] shadow-[0_-1px_4px_rgba(2,2,2,0.1)]"
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]">
@ -73,6 +73,7 @@
</div>
<ReviewResult :status="item.status" class="text-[12px]" :icon-size="12" />
</div>
<MsEmpty v-if="!reviewUserStatusList.length" />
</div>
</template>
</a-trigger>
@ -94,6 +95,7 @@
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 { MinderEvent } from '@/components/pure/ms-minder-editor/props';
@ -126,6 +128,10 @@
moduleTree: ModuleTreeNode[];
}>();
const emit = defineEmits<{
(e: 'operation', type: string, data: MinderJsonNodeData): void;
}>();
const route = useRoute();
const appStore = useAppStore();
const { t } = useI18n();
@ -348,7 +354,7 @@
}
const extraVisible = ref<boolean>(false);
const activeExtraKey = ref<'baseInfo' | 'attachment' | 'history'>('baseInfo');
const activeExtraKey = ref<'baseInfo' | 'attachment' | 'history'>('history');
const baseInfoLoading = ref(false);
const activeCaseInfo = ref<Record<string, any>>({});
const descriptions = ref<Description[]>([]);
@ -461,7 +467,7 @@
const node: MinderJsonNode = window.minder.getSelectedNode();
const { data } = node;
if (extraVisible.value && data?.resource?.includes(caseTag)) {
activeExtraKey.value = 'baseInfo';
activeExtraKey.value = 'history';
initCaseDetail(data);
initReviewHistoryList(data);
}
@ -470,35 +476,35 @@
const canShowFloatMenu = ref(false); //
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'));
const moreMenuOtherOperationList = ref();
function setMoreMenuOtherOperationList(data: MinderJsonNodeData) {
moreMenuOtherOperationList.value = [
{
value: 'changeReviewer',
label: t('caseManagement.caseReview.changeReviewer'),
permission: ['CASE_REVIEW:READ+UPDATE'],
onClick: () => {
emit('operation', 'changeReviewer', data);
},
},
},
{
value: 'reReview',
label: t('caseManagement.caseReview.reReview'),
permission: ['CASE_REVIEW:READ+UPDATE'],
onClick: () => {
// TODO
console.log('🤔️ =>', t('caseManagement.caseReview.reReview'));
{
value: 'reReview',
label: t('caseManagement.caseReview.reReview'),
permission: ['CASE_REVIEW:READ+UPDATE'],
onClick: () => {
emit('operation', 'reReview', data);
},
},
},
{
value: 'disassociate',
label: t('caseManagement.caseReview.disassociate'),
permission: ['CASE_REVIEW:READ+RELEVANCE'],
onClick: () => {
// TODO
console.log('🤔️ =>', t('caseManagement.caseReview.disassociate'));
{
value: 'disassociate',
label: t('caseManagement.caseReview.disassociate'),
permission: ['CASE_REVIEW:READ+RELEVANCE'],
onClick: () => {
emit('operation', 'disassociate', data);
},
},
},
];
];
}
/**
* 处理节点选中
@ -515,8 +521,8 @@
}
// :
if (
node?.data?.resource?.includes(caseTag) ||
(node?.data?.resource?.includes(moduleTag) && node.type !== 'root' && (node.children || []).length > 0)
node.data?.resource?.includes(caseTag) ||
(node.data?.resource?.includes(moduleTag) && node.type !== 'root' && (node.children || []).length > 0)
) {
canShowFloatMenu.value = true;
} else {
@ -532,6 +538,7 @@
if (data?.resource?.includes(caseTag)) {
showCaseMenu.value = true;
setMoreMenuOtherOperationList(node.data as MinderJsonNodeData);
if (extraVisible.value) {
toggleDetail(true);
}

View File

@ -87,6 +87,7 @@
</div>
</template>
</MsFileList>
<MsEmpty v-if="!fileList.length" />
</a-spin>
<LinkFileDrawer
v-model:visible="showLinkFileDrawer"
@ -103,6 +104,7 @@
import { Message } from '@arco-design/web-vue';
import MsButton from '@/components/pure/ms-button/index.vue';
import MsEmpty from '@/components/pure/ms-empty/index.vue';
import MsFileList from '@/components/pure/ms-upload/fileList.vue';
import { MsFileItem } from '@/components/pure/ms-upload/types';
import MsAddAttachment from '@/components/business/ms-add-attachment/index.vue';

View File

@ -11,7 +11,7 @@
:search-placeholder="t('caseManagement.caseReview.searchPlaceholder')"
@keyword-search="(val, filter) => searchCase(filter)"
@adv-search="searchCase"
@refresh="refresh"
@refresh="refresh()"
>
<template v-if="showType !== 'list'" #nameRight>
<div v-if="reviewPassRule === 'MULTIPLE'" class="ml-[16px]">
@ -142,6 +142,7 @@
:modules-count="props.modulesCount"
:review-progress="props.reviewProgress"
:review-pass-rule="props.reviewPassRule"
@operation="handleMinderOperation"
/>
</div>
<a-modal
@ -168,7 +169,7 @@
size="16"
/>
</a-tooltip>
<div class="ml-[8px] font-normal text-[var(--color-text-4)]">
<div v-show="showType === 'list'" class="ml-[8px] font-normal text-[var(--color-text-4)]">
({{ t('caseManagement.caseReview.selectedCase', { count: batchParams.currentSelectCount }) }})
</div>
</div>
@ -301,6 +302,7 @@
import { FilterFormItem, FilterResult, FilterType } from '@/components/pure/ms-advance-filter/type';
import MsButton from '@/components/pure/ms-button/index.vue';
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
import type { MinderJsonNodeData } from '@/components/pure/ms-minder-editor/props';
import MsPopconfirm from '@/components/pure/ms-popconfirm/index.vue';
import MsRichText from '@/components/pure/ms-rich-text/MsRichText.vue';
import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
@ -329,7 +331,7 @@
import useTableStore from '@/hooks/useTableStore';
import useAppStore from '@/store/modules/app';
import useUserStore from '@/store/modules/user';
import { findNodeByKey } from '@/utils';
import { characterLimit, findNodeByKey } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import { ReviewCaseItem, ReviewItem, ReviewPassRule, ReviewResult } from '@/models/caseManagement/caseReview';
@ -364,6 +366,7 @@
const { t } = useI18n();
const { openModal } = useModal();
const minderSelectData = ref(); //
const keyword = ref('');
const filterRowCount = ref(0);
const filterConfigList = ref<FilterFormItem[]>([]);
@ -522,6 +525,7 @@
: {},
};
setLoadListParams(tableParams.value);
resetSelector();
loadList();
emit('init', {
...tableParams.value,
@ -536,12 +540,28 @@
searchCase();
});
function refresh() {
/**
* 更新数据
* @param getCount 获取模块树数量
*/
function refresh(getCount = true) {
if (showType.value === 'list') {
searchCase();
if (getCount) {
searchCase();
} else {
resetSelector();
loadList();
}
} else {
msCaseReviewMinderRef.value?.initCaseTree();
emit('init', { moduleIds: [props.activeFolder], projectId: appStore.currentProjectId, pageSize: 10, current: 1 });
if (getCount) {
emit('init', {
moduleIds: [props.activeFolder],
projectId: appStore.currentProjectId,
pageSize: 10,
current: 1,
});
}
}
}
@ -669,9 +689,13 @@
//
function batchDisassociate() {
const batchDisassociateTitle =
showType.value === 'list'
? t('caseManagement.caseReview.disassociateConfirmTitle', { count: batchParams.value.currentSelectCount })
: t('testPlan.featureCase.disassociateTip', { name: characterLimit(minderSelectData.value?.text) });
openModal({
type: 'warning',
title: t('caseManagement.caseReview.disassociateConfirmTitle', { count: batchParams.value.currentSelectCount }),
title: batchDisassociateTitle,
content: t('caseManagement.caseReview.disassociateTipContent'),
okText: t('caseManagement.caseReview.disassociate'),
cancelText: t('common.cancel'),
@ -681,14 +705,21 @@
await batchDisassociateReviewCase({
reviewId: route.query.id as string,
userId: props.onlyMine ? userStore.id || '' : '',
moduleIds: props.activeFolder === 'all' ? [] : [props.activeFolder, ...props.offspringIds],
...batchParams.value,
...tableParams.value,
...(showType.value === 'list'
? {
moduleIds: props.activeFolder === 'all' ? [] : [props.activeFolder, ...props.offspringIds],
...batchParams.value,
...tableParams.value,
}
: {
selectIds: [minderSelectData.value.id],
selectAll: false,
condition: {},
}),
});
Message.success(t('common.updateSuccess'));
dialogLoading.value = false;
resetSelector();
loadList();
refresh();
emit('refresh', {
...tableParams.value,
current: propsRes.value.msPagination?.current,
@ -741,13 +772,21 @@
status: 'RE_REVIEWED',
content: dialogForm.value.reason,
notifier: dialogForm.value.commentIds.join(';'),
moduleIds: props.activeFolder === 'all' ? [] : [props.activeFolder, ...props.offspringIds],
...batchParams.value,
...tableParams.value,
...(showType.value === 'list'
? {
moduleIds: props.activeFolder === 'all' ? [] : [props.activeFolder, ...props.offspringIds],
...batchParams.value,
...tableParams.value,
}
: {
selectIds: [minderSelectData.value.id],
selectAll: false,
condition: {},
}),
});
Message.success(t('common.updateSuccess'));
dialogVisible.value = false;
resetSelector();
refresh(false);
emit('refresh', {
...tableParams.value,
current: propsRes.value.msPagination?.current,
@ -755,7 +794,6 @@
total: propsRes.value.msPagination?.total,
moduleIds: [],
});
loadList();
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
@ -775,15 +813,22 @@
userId: props.onlyMine ? userStore.id || '' : '',
reviewerId: dialogForm.value.reviewer.length > 0 ? dialogForm.value.reviewer : record.reviewers,
append: dialogForm.value.isAppend, //
moduleIds: props.activeFolder === 'all' ? [] : [props.activeFolder, ...props.offspringIds],
...batchParams.value,
...tableParams.value,
selectIds: batchParams.value.selectIds.length > 0 ? batchParams.value.selectIds : [record.id],
...(showType.value === 'list'
? {
moduleIds: props.activeFolder === 'all' ? [] : [props.activeFolder, ...props.offspringIds],
...batchParams.value,
...tableParams.value,
selectIds: batchParams.value.selectIds.length > 0 ? batchParams.value.selectIds : [record.id],
}
: {
selectIds: [minderSelectData.value.id],
selectAll: false,
condition: {},
}),
});
Message.success(t('common.updateSuccess'));
dialogVisible.value = false;
resetSelector();
loadList();
refresh();
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
@ -862,13 +907,8 @@
}
}
/**
* 处理表格选中后批量操作
* @param event 批量操作事件对象
*/
function handleTableBatch(event: BatchActionParams, params: BatchActionQueryParams) {
batchParams.value = { ...params, selectIds: params?.selectedIds || [], condition: {} };
switch (event.eventTag) {
function handleOperation(type?: string) {
switch (type) {
case 'review':
dialogVisible.value = true;
dialogShowType.value = 'review';
@ -890,6 +930,21 @@
}
}
//
function handleMinderOperation(type: string, data: MinderJsonNodeData) {
minderSelectData.value = data;
handleOperation(type);
}
/**
* 处理表格选中后批量操作
* @param event 批量操作事件对象
*/
function handleTableBatch(event: BatchActionParams, params: BatchActionQueryParams) {
batchParams.value = { ...params, selectIds: params?.selectedIds || [], condition: {} };
handleOperation(event.eventTag);
}
//
function review(record: ReviewCaseItem) {
router.push({