feat(功能用例): 用例评审-根节点取消关联后回到上一级模块

This commit is contained in:
teukkk 2024-07-09 19:43:51 +08:00 committed by Craftsman
parent 4df37e5a6f
commit 41816c034f
6 changed files with 95 additions and 54 deletions

View File

@ -3,9 +3,11 @@ import type { MinderJsonNode } from '@/components/pure/ms-minder-editor/props';
import { useI18n } from '@/hooks/useI18n';
import { mapTree } from '@/utils';
import { BatchApiParams } from '@/models/common';
const { t } = useI18n();
export function getMinderOffspringIds(node: MinderJsonNode) {
export function getMinderOffspringIds(node: MinderJsonNode): string[] {
const offspringIds: string[] = [];
mapTree(node.children || [], (e) => {
if (e.data.resource?.includes(t('common.module')) && e.data.id !== 'fakeNode') {
@ -20,7 +22,7 @@ export function getMinderOffspringIds(node: MinderJsonNode) {
*
* @param node
*/
export function getMinderOperationParams(node: MinderJsonNode) {
export function getMinderOperationParams(node: MinderJsonNode): BatchApiParams {
if (node.data?.resource?.includes(t('common.module'))) {
return {
selectIds: [],
@ -30,8 +32,9 @@ export function getMinderOperationParams(node: MinderJsonNode) {
};
}
return {
selectIds: [node.data?.caseId],
selectIds: [node.data?.id as string],
selectAll: false,
condition: {},
moduleIds: [],
};
}

View File

@ -1,16 +1,44 @@
import { defineStore } from 'pinia';
import { getReviewDetailModuleCount } from '@/api/modules/case-management/caseReview';
import { getReviewDetailModuleCount, getReviewDetailModuleTree } from '@/api/modules/case-management/caseReview';
import { mapTree } from '@/utils';
import type { ReviewDetailCaseListQueryParams } from '@/models/caseManagement/caseReview';
import { ModuleTreeNode } from '@/models/common';
const useCaseReviewStore = defineStore('caseReview', {
state: (): {
modulesCount: Record<string, any>; // 用例树模块数量
moduleTree: ModuleTreeNode[]; // 用例树
loading: boolean;
} => ({
modulesCount: {},
moduleTree: [],
loading: false,
}),
actions: {
// 初始化模块树
async initModules(id: string) {
try {
this.loading = true;
const res = await getReviewDetailModuleTree(id);
this.moduleTree = mapTree<ModuleTreeNode>(res, (node) => {
return {
...node,
count: this.modulesCount?.[node.id] || 0,
};
});
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
this.loading = false;
}
},
// 设置模块树
setModulesTree(tree: ModuleTreeNode[]) {
this.moduleTree = tree;
},
async getModuleCount(params: ReviewDetailCaseListQueryParams) {
try {
this.modulesCount = await getReviewDetailModuleCount(params);

View File

@ -138,7 +138,7 @@
:module-id="props.activeFolder"
:view-flag="props.onlyMine"
:view-status-flag="onlyMineStatus"
:module-tree="props.moduleTree"
:module-tree="moduleTree"
:review-progress="props.reviewProgress"
:review-pass-rule="props.reviewPassRule"
@operation="handleMinderOperation"
@ -337,7 +337,7 @@
import { hasAnyPermission } from '@/utils/permission';
import { ReviewCaseItem, ReviewItem, ReviewPassRule, ReviewResult } from '@/models/caseManagement/caseReview';
import { BatchApiParams, ModuleTreeNode, TableQueryParams } from '@/models/common';
import { BatchApiParams, TableQueryParams } from '@/models/common';
import { CaseManagementRouteEnum } from '@/enums/routeEnum';
import { TableKeyEnum } from '@/enums/tableEnum';
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
@ -354,10 +354,9 @@
onlyMine: boolean;
reviewPassRule: ReviewPassRule; //
offspringIds: string[]; // id
moduleTree: ModuleTreeNode[];
reviewProgress: string; //
}>();
const emit = defineEmits(['refresh', 'link']);
const emit = defineEmits(['refresh', 'link', 'selectParentNode']);
const router = useRouter();
const route = useRoute();
@ -378,10 +377,14 @@
const showType = ref<'list' | 'minder'>('list');
const msCaseReviewMinderRef = ref<InstanceType<typeof MsCaseReviewMinder>>();
const moduleTree = computed(() => unref(caseReviewStore.moduleTree));
async function initModules() {
await caseReviewStore.initModules(route.query.id as string);
}
const moduleNamePath = computed(() => {
return props.activeFolder === 'all'
? t('caseManagement.featureCase.allCase')
: findNodeByKey<Record<string, any>>(props.moduleTree, props.activeFolder, 'id')?.name;
: findNodeByKey<Record<string, any>>(moduleTree.value, props.activeFolder, 'id')?.name;
});
const hasOperationPermission = computed(() =>
@ -523,12 +526,16 @@
current: propsRes.value.msPagination?.current,
pageSize: propsRes.value.msPagination?.pageSize,
total: propsRes.value.msPagination?.total,
moduleIds: [],
};
} else {
params = { moduleIds: [props.activeFolder], projectId: appStore.currentProjectId, pageSize: 10, current: 1 };
params = { projectId: appStore.currentProjectId, pageSize: 10, current: 1 };
}
await caseReviewStore.getModuleCount({ ...params, viewFlag: props.onlyMine, reviewId: route.query.id as string });
await caseReviewStore.getModuleCount({
...params,
moduleIds: [],
viewFlag: props.onlyMine,
reviewId: route.query.id as string,
});
}
function searchCase(filter?: FilterResult) {
@ -650,6 +657,7 @@
try {
disassociateLoading.value = true;
await disassociateReviewCase(route.query.id as string, record.caseId);
initModules();
emit('refresh');
if (done) {
done();
@ -719,9 +727,16 @@
});
Message.success(t('common.updateSuccess'));
dialogLoading.value = false;
refresh();
const folderTree = cloneDeep(moduleTree.value);
emit('refresh');
// TODO:
await initModules();
await getModuleCount();
if (!Object.keys(modulesCount.value).includes(props.activeFolder)) {
//
emit('selectParentNode', folderTree);
} else {
refresh(false);
}
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
@ -809,6 +824,7 @@
});
Message.success(t('common.updateSuccess'));
dialogVisible.value = false;
emit('refresh');
refresh();
} catch (error) {
// eslint-disable-next-line no-console

View File

@ -54,8 +54,8 @@
import MsTree from '@/components/business/ms-tree/index.vue';
import type { MsTreeNodeData } from '@/components/business/ms-tree/types';
import { getReviewDetailModuleTree } from '@/api/modules/case-management/caseReview';
import { useI18n } from '@/hooks/useI18n';
import useCaseReviewStore from '@/store/modules/case/caseReview';
import { mapTree } from '@/utils';
import { ModuleTreeNode } from '@/models/common';
@ -66,10 +66,11 @@
isExpandAll?: boolean; //
selectedKeys: string[]; // key
}>();
const emit = defineEmits(['init', 'folderNodeSelect']);
const emit = defineEmits(['folderNodeSelect']);
const route = useRoute();
const { t } = useI18n();
const caseReviewStore = useCaseReviewStore();
const virtualListProps = computed(() => {
return {
@ -97,8 +98,8 @@
}
const moduleKeyword = ref('');
const folderTree = ref<ModuleTreeNode[]>([]);
const loading = ref(false);
const folderTree = computed(() => caseReviewStore.moduleTree);
const loading = computed(() => caseReviewStore.loading);
const selectedKeys = useVModel(props, 'selectedKeys', emit);
@ -106,22 +107,7 @@
* 初始化模块树
*/
async function initModules() {
try {
loading.value = true;
const res = await getReviewDetailModuleTree(route.query.id as string);
folderTree.value = mapTree<ModuleTreeNode>(res, (node) => {
return {
...node,
count: props.modulesCount?.[node.id] || 0,
};
});
emit('init', folderTree.value);
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
} finally {
loading.value = false;
}
await caseReviewStore.initModules(route.query.id as string);
}
/**
@ -137,6 +123,24 @@
emit('folderNodeSelect', _selectedKeys, offspringIds);
}
/**
* 选中父节点
* @param tree 原来的模块树
*/
function selectParentNode(tree: ModuleTreeNode[]) {
if (tree[0].parentId) {
mapTree(tree || [], (e) => {
if (e.id === selectedKeys.value[0]) {
selectedKeys.value = [e.parentId];
folderNodeSelect([e.parentId], e.parent);
}
return e;
});
} else {
setActiveFolder('all');
}
}
onBeforeMount(() => {
initModules();
});
@ -147,17 +151,19 @@
watch(
() => props.modulesCount,
(obj) => {
folderTree.value = mapTree<ModuleTreeNode>(folderTree.value, (node) => {
const tree = mapTree<ModuleTreeNode>(folderTree.value, (node) => {
return {
...node,
count: obj?.[node.id] || 0,
};
});
caseReviewStore.setModulesTree(tree);
allCount.value = obj?.all || 0;
}
);
defineExpose({
initModules,
selectParentNode,
});
</script>

View File

@ -42,12 +42,7 @@
import { useI18n } from '@/hooks/useI18n';
import useAppStore from '@/store/modules/app';
import {
BatchReviewCaseParams,
ReviewFormParams,
ReviewPassRule,
ReviewResult,
} from '@/models/caseManagement/caseReview';
import { BatchReviewCaseParams, ReviewFormParams, ReviewPassRule } from '@/models/caseManagement/caseReview';
import { StartReviewStatus } from '@/enums/caseEnum';
const props = defineProps<{

View File

@ -114,7 +114,6 @@
:modules-count="modulesCount"
:selected-keys="selectedKeys"
@folder-node-select="handleFolderNodeSelect"
@init="initModuleTree"
/>
</div>
</template>
@ -127,9 +126,9 @@
:offspring-ids="offspringIds"
:modules-count="modulesCount"
:review-progress="reviewProgress"
:module-tree="moduleTree"
@refresh="handleRefresh"
@refresh="initDetail()"
@link="associateDrawerVisible = true"
@select-parent-node="selectParentNode"
></CaseTable>
</template>
</MsSplitBox>
@ -223,6 +222,10 @@
});
const caseTableRef = ref<InstanceType<typeof CaseTable>>();
function selectParentNode(folderTree: ModuleTreeNode[]) {
folderTreeRef.value?.selectParentNode(folderTree);
}
function handleFolderNodeSelect(ids: string[], _offspringIds: string[]) {
[activeFolderId.value] = ids;
offspringIds.value = [..._offspringIds];
@ -370,16 +373,6 @@
});
}
function handleRefresh() {
initDetail();
folderTreeRef.value?.initModules();
}
const moduleTree = ref<ModuleTreeNode[]>([]);
function initModuleTree(tree: ModuleTreeNode[]) {
moduleTree.value = unref(tree);
}
onMounted(() => {
initDetail();
});