From a0fea7d0016a6d793d042bb267c1d228152a9797 Mon Sep 17 00:00:00 2001 From: zzh <1368735060@qq.com> Date: Mon, 14 Sep 2026 20:18:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E4=B8=8A=E4=B8=8B?= =?UTF-8?q?=E6=B8=B8=E6=8E=A5=E5=8F=A3=E6=98=8E=E7=BB=86=E4=BA=A4=E4=BA=92?= =?UTF-8?q?=E4=B8=8E=E5=B7=A6=E4=BE=A7=E6=A0=91=E5=B1=82=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 完善保存后引导发布、顶栏操作与参数区图标化,并区分分组与实体节点样式。 Co-authored-by: Cursor --- src/api/rbac/axios-config.ts | 5 +- src/components/CodeMirror/index.vue | 14 +- src/components/CustomLeftMenu/index.vue | 142 +++++- src/components/CustomLeftMenu/types.ts | 2 + src/components/InterfaceDetail/index.vue | 469 ++++++++++++------ src/locale/en-US.ts | 21 +- src/locale/zh-CN.ts | 21 +- src/store/modules/rbac-user.ts | 4 +- .../ServiceProviderInterfaceModal.vue | 13 +- .../comps/ReturnConfig.vue | 19 +- src/views/api/downstreamInterface/index.vue | 19 +- .../components/UpstreamInterfaceModal.vue | 10 +- src/views/api/upstreamInterface/index.vue | 33 +- src/views/channel/salesProducts/index.vue | 34 +- src/views/channel/serviceChannels/index.vue | 228 ++++++++- .../login/components/pwd-login/index.vue | 2 +- 16 files changed, 825 insertions(+), 211 deletions(-) diff --git a/src/api/rbac/axios-config.ts b/src/api/rbac/axios-config.ts index 157dac1..1a9b2ed 100644 --- a/src/api/rbac/axios-config.ts +++ b/src/api/rbac/axios-config.ts @@ -141,7 +141,10 @@ axiosInstance.interceptors.response.use( silentError?: boolean } const userStore = useRbacUserStore() - const silentError = Boolean(originalRequest?.silentError) + // 登录接口由页面内联 errorBox 展示,避免拦截器再弹 Message + const requestUrl = String(originalRequest?.url || '') + const isAuthLoginRequest = /\/rbac\/auth\/login(?:\?|$)/.test(requestUrl) + const silentError = Boolean(originalRequest?.silentError) || isAuthLoginRequest if (error.response) { const status = error.response.status diff --git a/src/components/CodeMirror/index.vue b/src/components/CodeMirror/index.vue index 93681f5..38ca9e2 100644 --- a/src/components/CodeMirror/index.vue +++ b/src/components/CodeMirror/index.vue @@ -73,8 +73,9 @@ function getLangSupport(lang: string) { const langSupport = computed(() => getLangSupport(props.language)) const scrollExtension = EditorView.theme({ - '.cm-editor': { height: '100%' }, - '.cm-scroller': { overflow: 'auto', minHeight: '100%' }, + '&': { height: '100%', maxHeight: '100%' }, + '.cm-scroller': { overflow: 'auto' }, + '.cm-content': { minHeight: '100%' }, }) const themeExtension = computed(() => { @@ -163,19 +164,24 @@ defineExpose({ .codemirror-container { width: 100%; height: 100%; - overflow: auto; + min-height: 0; + overflow: hidden; display: flex; flex-direction: column; + :deep(.vue-codemirror), :deep(.cm-editor) { + flex: 1; + width: 100%; height: 100%; min-height: 0; + overflow: hidden; font-size: 14px; } :deep(.cm-scroller) { font-family: 'Consolas', 'Monaco', 'Courier New', monospace; - overflow: auto; + overflow: auto !important; } } diff --git a/src/components/CustomLeftMenu/index.vue b/src/components/CustomLeftMenu/index.vue index c5f278e..15aca29 100644 --- a/src/components/CustomLeftMenu/index.vue +++ b/src/components/CustomLeftMenu/index.vue @@ -386,9 +386,10 @@ :class="{ selected: selectedKeysModel.includes(key), 'tree-node--hierarchical': hierarchical, - 'tree-node--branch': hierarchical && getNodeData(key)?.isLeaf !== true, + 'tree-node--branch': getNodeData(key)?.isLeaf !== true, + 'tree-node--leaf': getNodeData(key)?.isLeaf === true, 'tree-node--with-code': getNodeData(key)?.isLeaf && showNodeCode, - [`tree-node--depth-${getNodeData(key)?.depth || 1}`]: hierarchical, + [`tree-node--depth-${getNodeData(key)?.depth || (getNodeData(key)?.isLeaf ? 2 : 1)}`]: true, }" @click="hierarchical && selectTreeNode(key)" > @@ -856,11 +857,35 @@ min-height: var(--clm-node-height); } + &.tree-node--branch { + height: auto; + min-height: 34px; + max-height: none; + margin: 8px 0 2px; + padding: 6px 8px; + border-color: transparent; + background: transparent; + overflow: visible; + + .node-second-row-spacer-cell { + display: none; + } + } + + &.tree-node--leaf { + background: var(--color-fill-1); + } + &:hover { background: var(--clm-hover); border-color: rgba(15, 16, 17, 0.1); } + &.tree-node--branch:hover { + background: transparent; + border-color: transparent; + } + &.selected { background: var(--clm-selected) !important; border-color: var(--clm-selected-border) !important; @@ -876,16 +901,27 @@ color: var(--clm-muted) !important; } - &.tree-node--branch .node-title::before { - background: var(--clm-selected-text); + &.tree-node--branch { + background: transparent !important; + border-color: transparent !important; + + .node-title { + color: var(--clm-muted) !important; + font-weight: 600; + } + + .node-title::before { + background: var(--app-primary-color); + } } } } - .tree-node--depth-1 .node-title { + .tree-node--depth-1.tree-node--branch .node-title { font-size: 12px; - font-weight: 560; - letter-spacing: -0.01em; + font-weight: 600; + letter-spacing: 0.02em; + color: var(--clm-muted); } .tree-node--depth-2 .node-title { @@ -906,13 +942,12 @@ .tree-node--branch .node-title::before { content: ''; display: inline-block; - width: 5px; - height: 5px; - margin-right: 6px; - border-radius: 1.5px; - background: var(--clm-faint); - vertical-align: middle; - transform: translateY(-1px); + width: 3px; + height: 12px; + margin-right: 8px; + border-radius: 2px; + background: color-mix(in srgb, var(--app-primary-color) 55%, var(--clm-faint)); + vertical-align: -2px; } .node-subtitle { @@ -1062,6 +1097,81 @@ min-height: var(--clm-node-height); } + /* 分组头:轻量、矮一些,和可点击实体卡片拉开层级 */ + &.tree-node--branch { + height: auto; + min-height: 34px; + max-height: none; + margin: 10px 0 4px; + padding: 6px 8px; + border-color: transparent; + background: transparent; + cursor: default; + overflow: visible; + + .node-title { + font-size: 12px; + font-weight: 600; + color: var(--clm-muted); + letter-spacing: 0.02em; + } + + .node-title::before { + content: ''; + display: inline-block; + width: 3px; + height: 12px; + margin-right: 8px; + border-radius: 2px; + background: color-mix(in srgb, var(--app-primary-color) 55%, var(--clm-faint)); + vertical-align: -2px; + } + + .node-subtitle { + color: var(--clm-faint); + font-size: 11px; + } + + .node-second-row-spacer-cell { + display: none; + } + + .node-subtitle-cell { + padding-top: 2px; + padding-left: 11px; + } + + &:hover { + background: transparent; + border-color: transparent; + } + + &.selected { + background: transparent !important; + border-color: transparent !important; + box-shadow: none !important; + + .node-title { + color: var(--clm-muted) !important; + font-weight: 600; + } + + .node-subtitle { + color: var(--clm-faint) !important; + } + + .node-title::before { + background: var(--app-primary-color); + } + } + } + + /* 实体叶子:保持卡片感 */ + &.tree-node--leaf { + background: var(--color-fill-1); + border-color: rgba(15, 16, 17, 0.07); + } + &:hover { background: var(--clm-hover); border-color: rgba(15, 16, 17, 0.1); @@ -1073,6 +1183,10 @@ opacity: 1; } } + + &.tree-node--leaf:hover { + background: var(--clm-hover); + } } .tree-node.selected { diff --git a/src/components/CustomLeftMenu/types.ts b/src/components/CustomLeftMenu/types.ts index e637f59..59bfa70 100644 --- a/src/components/CustomLeftMenu/types.ts +++ b/src/components/CustomLeftMenu/types.ts @@ -15,6 +15,8 @@ export interface CustomLeftMenuTreeNode { method?: string; /** 分组等非叶子节点第二行副标题 */ subtitle?: string; + /** 树深度:1 分组 / 2+ 实体等 */ + depth?: number; [key: string]: any; } diff --git a/src/components/InterfaceDetail/index.vue b/src/components/InterfaceDetail/index.vue index 5eaf70e..78af87e 100644 --- a/src/components/InterfaceDetail/index.vue +++ b/src/components/InterfaceDetail/index.vue @@ -1,6 +1,6 @@