From 0dd098213ccc9d31a092d82bf43774faa6bb7ff6 Mon Sep 17 00:00:00 2001 From: hezhaohui Date: Fri, 17 Jul 2026 10:28:02 +0800 Subject: [PATCH 01/10] =?UTF-8?q?feat(header):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E4=B8=9A=E5=8A=A1=E7=BA=BF=E5=88=87=E6=8D=A2=E5=99=A8=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 stores/businessLine.ts:Pinia 状态管理,持久化到 localStorage - 新增 components/BusinessLineSwitcher.vue:企业微信式下拉切换器 - 修改 AppHeader.vue:在环境标签后集成切换器 - 预置 5 条业务线 mock 数据(LAS/Kodo/LTOKEN/灵矽/MAAS) - 更新 components.d.ts 自动类型声明 --- frontend/components.d.ts | 1 + .../src/components/BusinessLineSwitcher.vue | 230 ++++++++++++++++++ frontend/src/components/Layout/AppHeader.vue | 4 +- frontend/src/stores/businessLine.ts | 107 ++++++++ 4 files changed, 341 insertions(+), 1 deletion(-) create mode 100644 frontend/src/components/BusinessLineSwitcher.vue create mode 100644 frontend/src/stores/businessLine.ts diff --git a/frontend/components.d.ts b/frontend/components.d.ts index 6d63c3e..4380d44 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -11,6 +11,7 @@ declare module 'vue' { AppMain: typeof import('./src/components/Layout/AppMain.vue')['default'] AppSidebar: typeof import('./src/components/Layout/AppSidebar.vue')['default'] AuditLogTable: typeof import('./src/components/AuditLogTable.vue')['default'] + BusinessLineSwitcher: typeof import('./src/components/BusinessLineSwitcher.vue')['default'] ElButton: typeof import('element-plus/es')['ElButton'] ElIcon: typeof import('element-plus/es')['ElIcon'] ElInput: typeof import('element-plus/es')['ElInput'] diff --git a/frontend/src/components/BusinessLineSwitcher.vue b/frontend/src/components/BusinessLineSwitcher.vue new file mode 100644 index 0000000..c13e03e --- /dev/null +++ b/frontend/src/components/BusinessLineSwitcher.vue @@ -0,0 +1,230 @@ + + + + + diff --git a/frontend/src/components/Layout/AppHeader.vue b/frontend/src/components/Layout/AppHeader.vue index 3833271..41ca71d 100644 --- a/frontend/src/components/Layout/AppHeader.vue +++ b/frontend/src/components/Layout/AppHeader.vue @@ -5,6 +5,7 @@ xinfra 统一基础设施平台 ● 生产环境 +
@@ -36,6 +37,7 @@ import { useAuthStore } from '@/stores/auth' import { useTheme } from '@/composables/useTheme' import { useAuth } from '@/composables/useAuth' import { Moon, Sunny } from '@element-plus/icons-vue' +import BusinessLineSwitcher from '@/components/BusinessLineSwitcher.vue' const authStore = useAuthStore() const { logout } = useAuth() diff --git a/frontend/src/stores/businessLine.ts b/frontend/src/stores/businessLine.ts new file mode 100644 index 0000000..e7b69ab --- /dev/null +++ b/frontend/src/stores/businessLine.ts @@ -0,0 +1,107 @@ +import { defineStore } from 'pinia' +import { ref, computed } from 'vue' + +export interface BusinessLine { + id: string + name: string + ou: string + role: string + iconText: string + iconBg: string + iconColor: string + authorized: boolean +} + +const STORAGE_KEY = 'xinfra-current-bl' + +// TODO: 替换为真实 API 调用 +const MOCK_BUSINESS_LINES: BusinessLine[] = [ + { + id: 'las', + name: 'LAS 业务线', + ou: 'ou=las', + role: 'SRE', + iconText: 'LA', + iconBg: '#1A1430', + iconColor: '#C9A6FF', + authorized: true, + }, + { + id: 'kodo', + name: 'Kodo 业务线', + ou: 'ou=kodo', + role: '研发', + iconText: 'KO', + iconBg: '#0E1C2C', + iconColor: '#8EC8FF', + authorized: true, + }, + { + id: 'lingxi', + name: '灵矽 业务线', + ou: 'ou=lingxi', + role: '未授权', + iconText: 'LX', + iconBg: '#241B0A', + iconColor: '#FFC97A', + authorized: false, + }, + { + id: 'ltoken', + name: 'LTOKEN 业务线', + ou: 'ou=ltoken', + role: '研发', + iconText: 'LT', + iconBg: '#1A2A1A', + iconColor: '#A6FFB0', + authorized: true, + }, + { + id: 'maas', + name: 'MAAS 业务线', + ou: 'ou=maas', + role: '未授权', + iconText: 'MA', + iconBg: '#2A1A2A', + iconColor: '#FFB0E0', + authorized: false, + }, +] + +function loadSavedBL(): BusinessLine | null { + try { + const saved = localStorage.getItem(STORAGE_KEY) + if (saved) return JSON.parse(saved) + } catch { + // ignore + } + return null +} + +export const useBusinessLineStore = defineStore('businessLine', () => { + const businessLines = ref(MOCK_BUSINESS_LINES) + const currentBL = ref(loadSavedBL()) + + // 默认选中第一个已授权的业务线 + if (!currentBL.value) { + currentBL.value = businessLines.value.find((bl) => bl.authorized) || null + } + + const authorizedBLs = computed(() => + businessLines.value.filter((bl) => bl.authorized), + ) + + function switchBL(id: string) { + const bl = businessLines.value.find((b) => b.id === id) + if (!bl || !bl.authorized) return + currentBL.value = bl + localStorage.setItem(STORAGE_KEY, JSON.stringify(bl)) + } + + return { + businessLines, + currentBL, + authorizedBLs, + switchBL, + } +}) From f327f41733cf4ef8fd9fd0bd0a2ff7b07c343b34 Mon Sep 17 00:00:00 2001 From: hezhaohui Date: Fri, 17 Jul 2026 10:37:52 +0800 Subject: [PATCH 02/10] =?UTF-8?q?feat(service-catalog):=20=E5=AF=B9?= =?UTF-8?q?=E9=BD=90=E5=9F=BA=E7=A1=80=E6=9C=8D=E5=8A=A1=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E4=BA=A4=E4=BA=92=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新 6 张服务卡片数据(Wayne/MySQL/openresty/PgSQL/Redis/接入新服务) - 容器服务(Wayne)点击打开发布弹窗(业务线/命名空间/集群/规格/服务名) - MySQL 点击打开标准化交付弹窗(架构/规格/版本/实例名 + YAML 预览) - openresty 可点击但提示"功能对接中" - PgSQL/Redis 置灰不可点击,提示"功能规划中" - 接入新服务置灰(0.5)无响应 - 弹窗确认后 toast 提示并跳转任务中心 --- frontend/src/views/service/Catalog.vue | 460 ++++++++++++++++++++++++- 1 file changed, 442 insertions(+), 18 deletions(-) diff --git a/frontend/src/views/service/Catalog.vue b/frontend/src/views/service/Catalog.vue index 1be61fb..959574f 100644 --- a/frontend/src/views/service/Catalog.vue +++ b/frontend/src/views/service/Catalog.vue @@ -3,59 +3,304 @@

基础服务目录

-

点击卡片,通过封装好的 ansible-playbook 一键部署标准化基础服务

+

点击卡片,通过封装好的 ansible-playbook 一键标准化交付,完成后自动注册进对应子系统

-
+
{{ service.icon }}
-

{{ service.name }}

+

{{ service.name }}

{{ service.description }}
{{ service.playbook }} - {{ service.version }} + {{ service.version }}
+ + + +
+ +
+
+ + + +
+ +
+
From a185fac1b23bd7e0c707e65be066f09c3fda87c8 Mon Sep 17 00:00:00 2001 From: hezhaohui Date: Fri, 17 Jul 2026 10:53:08 +0800 Subject: [PATCH 03/10] =?UTF-8?q?feat(sidebar):=20=E9=87=8D=E7=BB=84?= =?UTF-8?q?=E4=BE=A7=E8=BE=B9=E6=A0=8F=E5=AF=BC=E8=88=AA=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 服务交付 → 业务交付:基础服务、任务中心 - 资源管理 → 资源纳管:资源管理(CMDB)、集群/容器池、业务线/配额 - 新增业务线/配额页面(Tenants.vue) - 集群页面标题对齐为「集群 / 容器池」 --- frontend/src/components/Layout/AppSidebar.vue | 35 ++--- frontend/src/router/index.ts | 8 +- frontend/src/views/cluster/ClusterList.vue | 4 +- frontend/src/views/resource/Tenants.vue | 122 ++++++++++++++++++ 4 files changed, 144 insertions(+), 25 deletions(-) create mode 100644 frontend/src/views/resource/Tenants.vue diff --git a/frontend/src/components/Layout/AppSidebar.vue b/frontend/src/components/Layout/AppSidebar.vue index d4111a5..573f92c 100644 --- a/frontend/src/components/Layout/AppSidebar.vue +++ b/frontend/src/components/Layout/AppSidebar.vue @@ -7,33 +7,24 @@ - - + -

{{ description }}

+

{{ system.description }}

{{ system.status === 'integrated' ? 'LDAP 原生配置接入 · 零代码' : 'LDAP 接入改造中' }} @@ -49,18 +49,6 @@ const iconColor = computed(() => { return colors[props.system.icon] || 'var(--text-mid)' }) -const description = computed(() => { - const descs: Record = { - Wayne: '业务容器发布、命名空间与配额管理,复用 Wayne 原生多租户能力。', - CloudDM: '数据库 SQL 上线统一审核,支持 LDAP 用户组到角色的自动映射。', - CacheCloud: 'Redis 实例全生命周期管理,登录与监控运维统一入口。', - Apollo: '统一配置管理,按机房 Cluster 隔离,支持灰度发布、版本回滚与变更审计。', - qpass: '夜莺、Zabbix、VictoriaMetrics 告警统一收敛与值班通知,按 P0/P1 分级推送。', - Grafana: '对接 VictoriaMetrics 数据源,K8s / 容器 / 业务指标统一仪表盘展示。', - } - return descs[props.system.name] || '' -}) - const handleClick = async () => { if (props.system.sso_enabled) { const { data } = await subsystemApi.getSSOUrl(props.system.id) diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index dd28c9e..3942ce2 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -34,6 +34,12 @@ const router = createRouter({ component: () => import('@/views/subsystem/Navigation.vue'), meta: { title: '子系统导航' }, }, + { + path: 'subsystem/detail/:name', + name: 'SubsystemDetail', + component: () => import('@/views/subsystem/SubsystemDetail.vue'), + meta: { title: '子系统详情' }, + }, { path: 'subsystem/authz', name: 'SubsystemAuthz', diff --git a/frontend/src/views/subsystem/SubsystemDetail.vue b/frontend/src/views/subsystem/SubsystemDetail.vue new file mode 100644 index 0000000..f5f49e8 --- /dev/null +++ b/frontend/src/views/subsystem/SubsystemDetail.vue @@ -0,0 +1,172 @@ + + + + + From 8fc4b0e0fbc64dedfca7d7850934dfb88170ee5f Mon Sep 17 00:00:00 2001 From: hezhaohui Date: Fri, 17 Jul 2026 11:23:41 +0800 Subject: [PATCH 05/10] =?UTF-8?q?refactor(resource):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=B5=84=E6=BA=90=E7=BA=B3=E7=AE=A1=E5=AD=90=20Tab=20=E5=91=BD?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 集群 / 容器池 → 集群与容器 - 业务线 / 配额 → 业务配额 - 同步更新侧边栏、路由 meta、页面标题 --- frontend/src/components/Layout/AppSidebar.vue | 4 ++-- frontend/src/router/index.ts | 4 ++-- frontend/src/views/cluster/ClusterList.vue | 2 +- frontend/src/views/resource/Tenants.vue | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/Layout/AppSidebar.vue b/frontend/src/components/Layout/AppSidebar.vue index d7d816a..49ca1e2 100644 --- a/frontend/src/components/Layout/AppSidebar.vue +++ b/frontend/src/components/Layout/AppSidebar.vue @@ -21,10 +21,10 @@ ▥资源管理CMDB - ◆集群 / 容器池3 + ◆集群与容器3 - ▦业务线 / 配额 + ▦业务配额