diff --git a/frontend/src/components/business/ms-minders/caseReviewMinder/utils.ts b/frontend/src/components/business/ms-minders/caseReviewMinder/utils.ts index 00ade35bc1..200c80441f 100644 --- a/frontend/src/components/business/ms-minders/caseReviewMinder/utils.ts +++ b/frontend/src/components/business/ms-minders/caseReviewMinder/utils.ts @@ -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: [], }; } diff --git a/frontend/src/store/modules/case/caseReview.ts b/frontend/src/store/modules/case/caseReview.ts index d109a554b2..81e7c28df2 100644 --- a/frontend/src/store/modules/case/caseReview.ts +++ b/frontend/src/store/modules/case/caseReview.ts @@ -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; // 用例树模块数量 + 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(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); diff --git a/frontend/src/views/case-management/caseReview/components/detail/caseTable.vue b/frontend/src/views/case-management/caseReview/components/detail/caseTable.vue index 943d466fda..214d8c7521 100644 --- a/frontend/src/views/case-management/caseReview/components/detail/caseTable.vue +++ b/frontend/src/views/case-management/caseReview/components/detail/caseTable.vue @@ -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>(); + 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>(props.moduleTree, props.activeFolder, 'id')?.name; + : findNodeByKey>(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 diff --git a/frontend/src/views/case-management/caseReview/components/detail/caseTree.vue b/frontend/src/views/case-management/caseReview/components/detail/caseTree.vue index 56265fa48d..d8493a4b67 100644 --- a/frontend/src/views/case-management/caseReview/components/detail/caseTree.vue +++ b/frontend/src/views/case-management/caseReview/components/detail/caseTree.vue @@ -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([]); - 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(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(folderTree.value, (node) => { + const tree = mapTree(folderTree.value, (node) => { return { ...node, count: obj?.[node.id] || 0, }; }); + caseReviewStore.setModulesTree(tree); allCount.value = obj?.all || 0; } ); defineExpose({ initModules, + selectParentNode, }); diff --git a/frontend/src/views/case-management/caseReview/components/reviewSubmit.vue b/frontend/src/views/case-management/caseReview/components/reviewSubmit.vue index 8c7943d989..62c21d2575 100644 --- a/frontend/src/views/case-management/caseReview/components/reviewSubmit.vue +++ b/frontend/src/views/case-management/caseReview/components/reviewSubmit.vue @@ -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<{ diff --git a/frontend/src/views/case-management/caseReview/detail.vue b/frontend/src/views/case-management/caseReview/detail.vue index ddcf2ee24c..56d9628d91 100644 --- a/frontend/src/views/case-management/caseReview/detail.vue +++ b/frontend/src/views/case-management/caseReview/detail.vue @@ -114,7 +114,6 @@ :modules-count="modulesCount" :selected-keys="selectedKeys" @folder-node-select="handleFolderNodeSelect" - @init="initModuleTree" /> @@ -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" > @@ -223,6 +222,10 @@ }); const caseTableRef = ref>(); + 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([]); - function initModuleTree(tree: ModuleTreeNode[]) { - moduleTree.value = unref(tree); - } - onMounted(() => { initDetail(); });