From 0b3213f38765f85b395c025f35752ea5d99b4dae Mon Sep 17 00:00:00 2001 From: "xinxin.wu" Date: Wed, 17 Jul 2024 14:45:38 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=85=B3=E8=81=94=E7=94=A8=E4=BE=8B=E5=85=A5?= =?UTF-8?q?=E5=8F=82=E5=92=8C=E8=A1=A5=E5=85=85=E8=B0=83=E6=95=B4=E9=83=A8?= =?UTF-8?q?=E5=88=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ms-associate-case/apiCaseTable.vue | 36 ++++- .../business/ms-associate-case/apiTable.vue | 36 ++++- .../business/ms-associate-case/caseTable.vue | 28 +++- .../ms-associate-case/scenarioCaseTable.vue | 28 +++- .../ms-associate-case/useModuleSelection.ts | 151 +++++++++++++----- .../ms-associate-case/useTreeSelection.ts | 18 +-- .../components/pure/ms-table/base-table.vue | 5 +- 7 files changed, 229 insertions(+), 73 deletions(-) diff --git a/frontend/src/components/business/ms-associate-case/apiCaseTable.vue b/frontend/src/components/business/ms-associate-case/apiCaseTable.vue index ab829feec1..efe3b023f8 100644 --- a/frontend/src/components/business/ms-associate-case/apiCaseTable.vue +++ b/frontend/src/components/business/ms-associate-case/apiCaseTable.vue @@ -7,6 +7,7 @@ baseAction: [], moreAction: [], }" + always-show-selected-count v-on="propsEvent" @row-select-change="rowSelectChange" @select-all-change="selectAllChange" @@ -344,25 +345,44 @@ }); } - const { rowSelectChange, selectAllChange, clearSelector, setModuleInfo } = useModuleSelection( + const tableSelectedProps = ref({ + modulesTree: props.moduleTree, + moduleCount: props.modulesCount, + }); + const { rowSelectChange, selectAllChange, clearSelector } = useModuleSelection( innerSelectedModulesMaps.value, - propsRes.value + propsRes.value, + tableSelectedProps.value ); - onMounted(() => { - loadCaseList(); - }); - watch( - [() => props.moduleTree, () => props.modulesCount], + () => props.moduleTree, (val) => { - setModuleInfo(val); + if (val) { + tableSelectedProps.value.modulesTree = val; + } }, { immediate: true, } ); + watch( + () => props.modulesCount, + (val) => { + if (val) { + tableSelectedProps.value.moduleCount = val; + } + }, + { + immediate: true, + } + ); + + onMounted(() => { + loadCaseList(); + }); + defineExpose({ getApiCaseSaveParams, loadCaseList, diff --git a/frontend/src/components/business/ms-associate-case/apiTable.vue b/frontend/src/components/business/ms-associate-case/apiTable.vue index 0efe29e485..5faf5b6d32 100644 --- a/frontend/src/components/business/ms-associate-case/apiTable.vue +++ b/frontend/src/components/business/ms-associate-case/apiTable.vue @@ -8,6 +8,7 @@ baseAction: [], moreAction: [], }" + always-show-selected-count v-on="propsEvent" @filter-change="getModuleCount" @row-select-change="rowSelectChange" @@ -304,25 +305,44 @@ }); } - const { rowSelectChange, selectAllChange, clearSelector, setModuleInfo } = useModuleSelection( + const tableSelectedProps = ref({ + modulesTree: props.moduleTree, + moduleCount: props.modulesCount, + }); + const { rowSelectChange, selectAllChange, clearSelector } = useModuleSelection( innerSelectedModulesMaps.value, - propsRes.value + propsRes.value, + tableSelectedProps.value ); - onMounted(() => { - loadApiList(); - }); - watch( - [() => props.moduleTree, () => props.modulesCount], + () => props.moduleTree, (val) => { - setModuleInfo(val); + if (val) { + tableSelectedProps.value.modulesTree = val; + } }, { immediate: true, } ); + watch( + () => props.modulesCount, + (val) => { + if (val) { + tableSelectedProps.value.moduleCount = val; + } + }, + { + immediate: true, + } + ); + + onMounted(() => { + loadApiList(); + }); + defineExpose({ getApiSaveParams, loadApiList, diff --git a/frontend/src/components/business/ms-associate-case/caseTable.vue b/frontend/src/components/business/ms-associate-case/caseTable.vue index b0640c9cdd..b25c275a30 100644 --- a/frontend/src/components/business/ms-associate-case/caseTable.vue +++ b/frontend/src/components/business/ms-associate-case/caseTable.vue @@ -7,6 +7,7 @@ baseAction: [], moreAction: [], }" + always-show-selected-count v-on="propsEvent" @filter-change="getModuleCount" @row-select-change="rowSelectChange" @@ -317,15 +318,34 @@ return [...propsRes.value.selectedKeys]; }); - const { rowSelectChange, selectAllChange, clearSelector, setModuleInfo } = useModuleSelection( + const tableSelectedProps = ref({ + modulesTree: props.moduleTree, + moduleCount: props.modulesCount, + }); + const { rowSelectChange, selectAllChange, clearSelector } = useModuleSelection( innerSelectedModulesMaps.value, - propsRes.value + propsRes.value, + tableSelectedProps.value ); watch( - [() => props.moduleTree, () => props.modulesCount], + () => props.moduleTree, (val) => { - setModuleInfo(val); + if (val) { + tableSelectedProps.value.modulesTree = val; + } + }, + { + immediate: true, + } + ); + + watch( + () => props.modulesCount, + (val) => { + if (val) { + tableSelectedProps.value.moduleCount = val; + } }, { immediate: true, diff --git a/frontend/src/components/business/ms-associate-case/scenarioCaseTable.vue b/frontend/src/components/business/ms-associate-case/scenarioCaseTable.vue index 93e0b9d1db..2ed3616b80 100644 --- a/frontend/src/components/business/ms-associate-case/scenarioCaseTable.vue +++ b/frontend/src/components/business/ms-associate-case/scenarioCaseTable.vue @@ -7,6 +7,7 @@ baseAction: [], moreAction: [], }" + always-show-selected-count v-on="propsEvent" @filter-change="getModuleCount" @row-select-change="rowSelectChange" @@ -283,15 +284,34 @@ }; } - const { rowSelectChange, selectAllChange, clearSelector, setModuleInfo } = useModuleSelection( + const tableSelectedProps = ref({ + modulesTree: props.moduleTree, + moduleCount: props.modulesCount, + }); + const { rowSelectChange, selectAllChange, clearSelector } = useModuleSelection( innerSelectedModulesMaps.value, - propsRes.value + propsRes.value, + tableSelectedProps.value ); watch( - [() => props.moduleTree, () => props.modulesCount], + () => props.moduleTree, (val) => { - setModuleInfo(val); + if (val) { + tableSelectedProps.value.modulesTree = val; + } + }, + { + immediate: true, + } + ); + + watch( + () => props.modulesCount, + (val) => { + if (val) { + tableSelectedProps.value.moduleCount = val; + } }, { immediate: true, diff --git a/frontend/src/components/business/ms-associate-case/useModuleSelection.ts b/frontend/src/components/business/ms-associate-case/useModuleSelection.ts index 47342f9bd8..320cca8c7a 100644 --- a/frontend/src/components/business/ms-associate-case/useModuleSelection.ts +++ b/frontend/src/components/business/ms-associate-case/useModuleSelection.ts @@ -9,34 +9,76 @@ import { SelectAllEnum } from '@/enums/tableEnum'; import type { moduleKeysType } from './types'; +export interface SelectedModuleProps { + modulesTree: MsTreeNodeData[]; + moduleCount: Record; +} + export default function useModuleSelections( innerSelectedModulesMaps: Record, - propsRes: MsTableProps + propsRes: MsTableProps, + tableSelectedProps: SelectedModuleProps ) { const moduleSelectedMap = ref>({}); + const { modulesTree, moduleCount } = tableSelectedProps; + const moduleTree = ref(modulesTree); + const allModuleTotal = ref>(moduleCount); - const moduleTree = ref([]); - const allModuleTotal = ref>({}); + // 初始化节点,防止选择时报错 + function setUnSelectNode(moduleId: string, key = 'id') { + if (!innerSelectedModulesMaps[moduleId]) { + const node = findNodeByKey(moduleTree.value, moduleId, key); + innerSelectedModulesMaps[moduleId] = { + selectAll: false, + selectIds: new Set(), + excludeIds: new Set(), + count: moduleId === 'all' ? allModuleTotal.value.all : node?.count ?? 0, + }; + } + } // 初始化表格数据的选择 function initTableDataSelected() { propsRes.selectedKeys = new Set([]); propsRes.excludeKeys = new Set([]); const allSelectIds: Set = new Set(); + if (!innerSelectedModulesMaps.all) { + setUnSelectNode('all'); + } propsRes.data.forEach((item: any) => { const selectAllProps = innerSelectedModulesMaps[item.moduleId]; + // 首次上来默认全选则追加moduleSelectedMap里边所对应moduleId所有的Ids if ( selectAllProps && selectAllProps.selectAll && !selectAllProps.selectIds.size && !selectAllProps.excludeIds.size ) { - (moduleSelectedMap.value[item.moduleId] || []).forEach((id) => allSelectIds.add(id)); - } else if (selectAllProps && !selectAllProps.selectAll && selectAllProps.selectIds.size) { + (moduleSelectedMap.value[item.moduleId] || []).forEach((id) => { + allSelectIds.add(id); + innerSelectedModulesMaps.all.selectIds.add(id); + innerSelectedModulesMaps.all.excludeIds.delete(id); + }); + } + // 有选择则从选择里边的去回显选项项 + if (selectAllProps && selectAllProps.selectIds.size) { selectAllProps.selectIds.forEach((id) => allSelectIds.add(id)); } + // 有排除的则从全部的里边排除掉排除的进行回显选择项 + // 确保单独更新行选中或者取消能精确判断是否已经选中或排除 + if (selectAllProps && selectAllProps.excludeIds.size) { + (moduleSelectedMap.value[item.moduleId] || []).forEach((id) => { + if (!selectAllProps.excludeIds.has(id)) { + allSelectIds.add(id); + innerSelectedModulesMaps[item.moduleId].selectIds.add(id); + innerSelectedModulesMaps.all.selectIds.add(id); + } else { + innerSelectedModulesMaps[item.moduleId].excludeIds.add(id); + innerSelectedModulesMaps.all.excludeIds.add(id); + } + }); + } }); - propsRes.selectedKeys = new Set([...allSelectIds]); } @@ -72,39 +114,27 @@ export default function useModuleSelections( } } - // 初始化节点,防止选择时报错 - function setUnSelectNode(moduleId: string, key = 'id') { - if (!innerSelectedModulesMaps[moduleId]) { - const node = findNodeByKey(moduleTree.value, moduleId, key); - innerSelectedModulesMaps[moduleId] = { - selectAll: false, - selectIds: new Set(), - excludeIds: new Set(), - count: moduleId === 'all' ? allModuleTotal.value.all : node?.count ?? 0, - }; - } - } - // 设置最新状态 function setSelectedModuleStatus(moduleId: string) { const selectedProps = innerSelectedModulesMaps[moduleId]; if (selectedProps) { - const { selectIds: selectModuleIds, count, excludeIds } = selectedProps; - - if (excludeIds.size) { - selectedProps.selectAll = false; - } + const { selectIds: selectModuleIds, count, excludeIds, selectAll } = selectedProps; + // 如果排除的数量等于总count则置为false且清空 if (excludeIds.size === count) { resetModule(moduleId, false); } - + // 如果选中的数量等于总count则置为true且清空 if (selectModuleIds.size === count) { - if (moduleId === 'all') { - resetModule(moduleId, true); - } else { - setSelectedAll(moduleId); - } + resetModule(moduleId, true); + } + // 全选无排除则全选为了上来全选取消一条再选择则为全选 + if (selectAll && !excludeIds.size) { + resetModule(moduleId, true); + } + // 右侧表格选择后再排除此刻设置为false且清空已选项 + if (!selectAll && !selectModuleIds.size) { + resetModule(moduleId, false); } } } @@ -112,6 +142,8 @@ export default function useModuleSelections( // 更新选择数据 function updateSelectModule(moduleId: string, id: string) { const selectedProps = innerSelectedModulesMaps[moduleId]; + console.log(222); + if (selectedProps) { const selectedSet = selectedProps.selectIds; const excludedSet = selectedProps.excludeIds; @@ -140,7 +172,6 @@ export default function useModuleSelections( } else if (!selectedSet.has(id) && !excludedSet.has(id)) { selectedProps.selectIds.add(id); } - innerSelectedModulesMaps[moduleId] = selectedProps; setSelectedModuleStatus(moduleId); } @@ -149,7 +180,6 @@ export default function useModuleSelections( function rowSelectChange(record: Record) { const { moduleId } = record; setUnSelectNode(moduleId); - setUnSelectNode('all'); updateSelectModule(moduleId, record.id); updateSelectModule('all', record.id); } @@ -162,7 +192,8 @@ export default function useModuleSelections( const { moduleId } = item; setUnSelectNode(moduleId); const lastSelectedProps = innerSelectedModulesMaps[moduleId]; - if (!lastSelectedProps.selectAll) { + // 数据为data当前分页的数据 + if (lastSelectedProps) { innerSelectedModulesMaps[moduleId].selectIds.add(item.id); innerSelectedModulesMaps[moduleId].excludeIds.delete(item.id); setSelectedModuleStatus(moduleId); @@ -175,15 +206,20 @@ export default function useModuleSelections( setUnSelectNode(moduleId); innerSelectedModulesMaps[item.moduleId].selectIds.delete(item.id); innerSelectedModulesMaps[item.moduleId].excludeIds.add(item.id); + const selectedProps = innerSelectedModulesMaps[moduleId]; + if (selectedProps) { + const resultIds = (moduleSelectedMap.value[moduleId] || []).filter((id) => !selectedProps.excludeIds.has(id)); + // 取消加了排除ids此刻全选状态为false,并且排除当前页ids,则从所有列表里边收集到模块ids + resultIds.forEach((e) => { + innerSelectedModulesMaps[moduleId].selectIds.add(e); + innerSelectedModulesMaps[moduleId].excludeIds.delete(e); + }); + } setSelectedModuleStatus(moduleId); updateSelectModule('all', item.id); }); } } - function setModuleInfo([tree, count]: [MsTreeNodeData[], Record]) { - moduleTree.value = tree; - allModuleTotal.value = count; - } function clearSelector() { Object.keys(innerSelectedModulesMaps).forEach((key) => { @@ -213,6 +249,46 @@ export default function useModuleSelections( } ); + // 设置模块树 + function setModuleTree(tree: MsTreeNodeData[]) { + moduleTree.value = tree; + } + + // 设置模块 + function setModuleCount(count: Record) { + allModuleTotal.value = count; + } + + watch( + () => tableSelectedProps.modulesTree, + (val) => { + setModuleTree(val); + }, + { + immediate: true, + deep: true, + } + ); + + watch( + () => tableSelectedProps.moduleCount, + (val) => { + if (val) { + setModuleCount(val); + innerSelectedModulesMaps.all = { + selectAll: false, + selectIds: new Set(), + excludeIds: new Set(), + count: val.all || 0, + }; + } + }, + { + immediate: true, + deep: true, + } + ); + return { moduleSelectedMap, rowSelectChange, @@ -224,6 +300,5 @@ export default function useModuleSelections( setSelectedAll, updateSelectModule, clearSelector, - setModuleInfo, }; } diff --git a/frontend/src/components/business/ms-associate-case/useTreeSelection.ts b/frontend/src/components/business/ms-associate-case/useTreeSelection.ts index e01a35327e..a6b81af6f4 100644 --- a/frontend/src/components/business/ms-associate-case/useTreeSelection.ts +++ b/frontend/src/components/business/ms-associate-case/useTreeSelection.ts @@ -83,14 +83,14 @@ export default function useTreeSelection(selectedModuleProps: SelectedModuleProp return Object.keys(selectedModulesMaps.value).reduce((total, key) => { const module = selectedModulesMaps.value[key]; if (key !== 'all') { - // 未全选存在排除则要 count总-排除掉的 = 已选 - if (module.excludeIds.size && !module.selectAll) { - total += module.count - module.excludeIds.size; - // 已全选未排除则要+count - } else if (module.selectAll && !module.excludeIds.size) { + // 全选 + if (module.selectAll && !module.excludeIds.size && !module.selectIds.size) { total += module.count; - // 未全选则 + 选择的id集合 - } else if (!module.selectAll && module.selectIds.size) { + // 具有排除项则半选 + } else if (module.selectAll && module.excludeIds.size) { + total += module.count - module.excludeIds.size; + // 初始化上来选择右侧列表计算selectIds.size为和 + } else if (!module.selectAll) { total += module.selectIds.size; } } @@ -114,8 +114,8 @@ export default function useTreeSelection(selectedModuleProps: SelectedModuleProp Object.entries(val).forEach(([moduleId, selectedProps]) => { const { selectAll: selectIdsAll, selectIds, count, excludeIds } = selectedProps; if (selectedProps) { - // 全选和取消全选 - if (selectIdsAll) { + // 全选状态则其他参数的size都为0 + if (selectIdsAll && !selectIds.size && !excludeIds.size) { checkedKeysSet.add(moduleId); } else { checkedKeysSet.delete(moduleId); diff --git a/frontend/src/components/pure/ms-table/base-table.vue b/frontend/src/components/pure/ms-table/base-table.vue index 35f922e324..c5717f276c 100644 --- a/frontend/src/components/pure/ms-table/base-table.vue +++ b/frontend/src/components/pure/ms-table/base-table.vue @@ -244,7 +244,7 @@