diff --git a/frontend/src/components/business/ms-tree/index.vue b/frontend/src/components/business/ms-tree/index.vue index 79c8b46f3a..07f7f90684 100644 --- a/frontend/src/components/business/ms-tree/index.vue +++ b/frontend/src/components/business/ms-tree/index.vue @@ -98,7 +98,7 @@ import type { ActionsItem } from '@/components/pure/ms-table-more-action/types'; import useContainerShadow from '@/hooks/useContainerShadow'; - import { mapTree } from '@/utils'; + import { mapTree, traverseTree } from '@/utils'; import type { MsTreeExpandedData, MsTreeFieldNames, MsTreeNodeData, MsTreeSelectedData } from './types'; import { VirtualListProps } from '@arco-design/web-vue/es/_components/virtual-list-v2/interface'; @@ -127,6 +127,9 @@ nodeHighlightClass?: string; // 节点高亮背景色 hideSwitcher?: boolean; // 隐藏展开折叠图标 handleDrop?: boolean; // 是否处理拖拽 + // 是否使用新的映射数据 + // (使用映射数据代表会根据传入的 data 深拷贝出新的 filterTreeData 树,此时针对 slot 传入的 node 节点的操作都不会影响data;不使用则代表 data 和 filterTreeData 节点数据是共用的,区别只在搜索展示数量不同) + useMapData?: boolean; titleTooltipPosition?: | 'top' | 'tl' @@ -156,6 +159,7 @@ isLeaf: 'isLeaf', }), disabledTitleTooltip: false, + useMapData: true, } ); @@ -260,10 +264,17 @@ () => data.value, debounce((val) => { if (!props.keyword) { - filterTreeData.value = mapTree(val, (node) => { - node.expanded = props.defaultExpandAll; - return node; - }); + if (props.useMapData) { + filterTreeData.value = mapTree(val, (node) => { + node.expanded = props.defaultExpandAll; + return node; + }); + } else { + traverseTree(val, (node) => { + node.expanded = props.defaultExpandAll; + }); + filterTreeData.value = val; + } if (props.defaultExpandAll && treeRef.value) { treeRef.value.expandAll(true); } @@ -281,7 +292,18 @@ () => props.keyword, (val) => { if (!val) { - filterTreeData.value = data.value; + if (props.useMapData) { + filterTreeData.value = mapTree(data.value, (node) => { + node.expanded = props.defaultExpandAll; + return node; + }); + } else { + traverseTree(data.value, (node) => { + node.expanded = props.defaultExpandAll; + }); + filterTreeData.value = data.value; + } + treeRef.value?.expandAll(false); } else { updateDebouncedSearch(); } @@ -409,7 +431,7 @@ (val) => { if (typeof val === 'boolean') { treeRef.value?.expandAll(val); - filterTreeData.value = mapTree(filterTreeData.value, (node) => { + traverseTree(filterTreeData.value, (node) => { node.expanded = val; return node; }); diff --git a/frontend/src/components/pure/ms-table/base-table.vue b/frontend/src/components/pure/ms-table/base-table.vue index da0c26ea27..e702d9d6a0 100644 --- a/frontend/src/components/pure/ms-table/base-table.vue +++ b/frontend/src/components/pure/ms-table/base-table.vue @@ -178,7 +178,7 @@ /> ( } return false; } - insertNodeInTree(treeArr); } diff --git a/frontend/src/views/api-test/scenario/components/scenarioModuleTree.vue b/frontend/src/views/api-test/scenario/components/scenarioModuleTree.vue index e8fe524446..44c05cd6c7 100644 --- a/frontend/src/views/api-test/scenario/components/scenarioModuleTree.vue +++ b/frontend/src/views/api-test/scenario/components/scenarioModuleTree.vue @@ -145,7 +145,7 @@ import { useI18n } from '@/hooks/useI18n'; import useModal from '@/hooks/useModal'; import useAppStore from '@/store/modules/app'; - import { mapTree } from '@/utils'; + import { characterLimit, mapTree } from '@/utils'; import { hasAnyPermission } from '@/utils/permission'; import { ApiScenarioGetModuleParams } from '@/models/apiTest/scenario'; @@ -341,7 +341,7 @@ function deleteFolder(node: MsTreeNodeData) { openModal({ type: 'error', - title: t('apiScenario.module.deleteTipTitle', { name: node.name }), + title: t('apiScenario.module.deleteTipTitle', { name: characterLimit(node.name) }), content: t('apiScenario.module.deleteTipContent'), okText: t('apiScenario.deleteConfirm'), okButtonProps: { diff --git a/frontend/src/views/api-test/scenario/components/step/stepTree.vue b/frontend/src/views/api-test/scenario/components/step/stepTree.vue index 10b2a80442..19c2343b83 100644 --- a/frontend/src/views/api-test/scenario/components/step/stepTree.vue +++ b/frontend/src/views/api-test/scenario/components/step/stepTree.vue @@ -21,6 +21,7 @@ title-class="step-tree-node-title" node-highlight-class="step-tree-node-focus" action-on-node-click="expand" + :use-map-data="false" disabled-title-tooltip checkable block-node diff --git a/frontend/src/views/api-test/scenario/components/step/useStepNodeEdit.ts b/frontend/src/views/api-test/scenario/components/step/useStepNodeEdit.ts index f44990962f..1a128aedd4 100644 --- a/frontend/src/views/api-test/scenario/components/step/useStepNodeEdit.ts +++ b/frontend/src/views/api-test/scenario/components/step/useStepNodeEdit.ts @@ -3,7 +3,7 @@ import { Message } from '@arco-design/web-vue'; import MsTree from '@/components/business/ms-tree/index.vue'; import { getScenarioDetail } from '@/api/modules/api-test/scenario'; -import { t } from '@/hooks/useI18n'; +import { useI18n } from '@/hooks/useI18n'; import { findNodeByKey, getGenerateId, mapTree } from '@/utils'; import type { Scenario, ScenarioStepConfig, ScenarioStepDetail, ScenarioStepItem } from '@/models/apiTest/scenario'; @@ -43,6 +43,8 @@ export default function useStepNodeEdit({ selectedKeys: Ref>; showScenarioConfig: Ref; }) { + const { t } = useI18n(); + /** * 打开快速输入 * @param dataKey 快速输入的数据 key diff --git a/frontend/src/views/api-test/scenario/recycle/recycleTable.vue b/frontend/src/views/api-test/scenario/recycle/recycleTable.vue index dcf22599ef..f918e1d407 100644 --- a/frontend/src/views/api-test/scenario/recycle/recycleTable.vue +++ b/frontend/src/views/api-test/scenario/recycle/recycleTable.vue @@ -107,6 +107,7 @@ import useTableStore from '@/hooks/useTableStore'; import useAppStore from '@/store/modules/app'; import { operationWidth } from '@/utils'; + import { hasAnyPermission } from '@/utils/permission'; import { ApiScenarioTableItem } from '@/models/apiTest/scenario'; import { ApiScenarioStatus } from '@/enums/apiEnum'; @@ -324,8 +325,8 @@ scroll: { x: '100%' }, tableKey: props.readOnly ? undefined : TableKeyEnum.API_SCENARIO, showSetting: !props.readOnly, - selectable: true, - showSelectAll: !props.readOnly, + selectable: hasAnyPermission(['PROJECT_API_SCENARIO:READ+DELETE']), + showSelectAll: hasAnyPermission(['PROJECT_API_SCENARIO:READ+DELETE']), draggable: undefined, heightUsed: 374, showSubdirectory: true, diff --git a/frontend/src/views/setting/system/user/index.vue b/frontend/src/views/setting/system/user/index.vue index 410c048ae8..9be6f93857 100644 --- a/frontend/src/views/setting/system/user/index.vue +++ b/frontend/src/views/setting/system/user/index.vue @@ -742,11 +742,9 @@ async function init() { try { - if (hasAnyPermission(['SYSTEM_USER_ROLE:READ'])) { - userGroupOptions.value = await getSystemRoles(); - if (userGroupOptions.value.length) { - userForm.value.userGroup = userGroupOptions.value.filter((e: SystemRole) => e.selected === true); - } + userGroupOptions.value = await getSystemRoles(); + if (userGroupOptions.value.length) { + userForm.value.userGroup = userGroupOptions.value.filter((e: SystemRole) => e.selected === true); } } catch (error) { // eslint-disable-next-line no-console