修复(权限管理):统一 PM 系统导航与权限校验

This commit is contained in:
Cheng Zhou
2026-07-10 22:12:59 +08:00
parent f11a5c84d9
commit f2fa10c178
47 changed files with 4071 additions and 1555 deletions
+112 -26
View File
@@ -79,16 +79,16 @@
</div>
</template>
</el-progress>
<div class="health-summary-copy">
<strong>{{ health.sample_sufficient ? "当前运行正常" : "等待业务样本" }}</strong>
<span v-if="health.sample_sufficient">评分由性能拒绝率缓存告警和组件状态共同计算</span>
<span v-else>组件在线不代表指标已完成评估</span>
<div class="health-summary-copy" :class="`is-${healthDisplayStatus}`">
<span class="health-summary-label">综合状态</span>
<strong>{{ health.sample_sufficient ? getHealthSummaryLabel(health.status) : "待评估" }}</strong>
</div>
</div>
<div v-if="health.sample_sufficient" class="health-signal-list">
<span v-for="item in healthScoreItems" :key="item.label" :class="{ 'is-warning': item.deduction }">
{{ item.label }}{{ item.deduction ? ` -${item.deduction}` : " 正常" }}
</span>
<div v-for="item in healthScoreItems" :key="item.label" class="health-signal-item" :class="{ 'is-warning': item.deduction }">
<span>{{ item.label }}</span>
<strong>{{ item.deduction ? `-${item.deduction}` : "正常" }}</strong>
</div>
</div>
<div v-else class="sample-warning">
1 小时仅 {{ health.last_hour.total_checks }} 次权限检查业务样本不足
@@ -195,7 +195,6 @@
<span class="empty-alert-icon"></span>
<div>
<strong>暂无活动告警</strong>
<small>最近一次检查未发现需要处理的问题</small>
</div>
</div>
<el-empty v-else description="告警数据尚未加载" :image-size="44" />
@@ -222,14 +221,14 @@
</div>
</el-tab-pane>
<el-tab-pane label="性能趋势" name="trends" lazy>
<el-tab-pane label="运行趋势" name="trends" lazy>
<template #label>
<span class="soybean-tab-label">
<component :is="IconActivity" />
<span>性能趋势</span>
<span>运行趋势</span>
</span>
</template>
<PermissionTrendCharts ref="trendChartsRef" />
<PermissionTrendCharts ref="trendChartsRef" @drilldown="openTrendDrilldown" />
</el-tab-pane>
<el-tab-pane v-if="props.isAdmin" label="安全中心" name="security" lazy>
@@ -364,6 +363,22 @@ type IpLocationsExpose = {
};
const ipLocationsRef = ref<IpLocationsExpose>();
interface TrendDrilldownPayload {
preset?: "24h" | "7d" | "30d";
startAt?: string;
endAt?: string;
allowed?: boolean;
role?: string;
clientType?: string;
keyword?: string;
}
const openTrendDrilldown = async (payload: TrendDrilldownPayload) => {
activeTab.value = "logs";
await nextTick();
await accessLogsRef.value?.applyTrendFilter(payload);
};
const securityCenterRef = ref<InstanceType<typeof SecurityCenter>>();
const formatTime = (timestamp: number): string => {
@@ -384,6 +399,11 @@ const getHealthLabel = (status: string) => {
return map[status] || status;
};
const getHealthSummaryLabel = (status: string) => {
const map: Record<string, string> = { healthy: "正常", degraded: "需关注", unhealthy: "异常" };
return map[status] || "待评估";
};
const getComponentStatusLabel = (status: string) => {
const map: Record<string, string> = { healthy: "正常", degraded: "降级", unhealthy: "异常", unknown: "未知" };
return map[status] || status;
@@ -593,6 +613,9 @@ defineExpose({ refresh });
}
.soybean-monitoring-tabs :deep(.el-tabs__header) {
position: relative;
z-index: 10;
flex: 0 0 52px;
height: 52px;
margin: 0 0 10px;
padding: 0 24px;
@@ -656,10 +679,14 @@ defineExpose({ refresh });
}
.soybean-monitoring-tabs :deep(.el-tabs__content) {
flex: 1 1 auto;
flex: 1 1 0;
height: auto;
min-height: 0;
padding: 0;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
overscroll-behavior: contain;
scrollbar-gutter: stable;
}
.permission-monitoring.is-source-tab .soybean-monitoring-tabs :deep(.el-tabs__content) {
@@ -671,8 +698,14 @@ defineExpose({ refresh });
}
.soybean-monitoring-tabs :deep(.el-tab-pane[aria-hidden="false"]) {
height: auto;
min-height: 100%;
}
.permission-monitoring.is-source-tab .soybean-monitoring-tabs :deep(.el-tab-pane[aria-hidden="false"]) {
height: 100%;
min-height: 0;
overflow: hidden;
}
.ip-locations-pane {
@@ -1314,26 +1347,58 @@ defineExpose({ refresh });
.health-summary {
display: flex;
align-items: center;
gap: 10px;
gap: 12px;
min-height: 96px;
}
.health-summary-copy {
display: flex;
flex-direction: column;
gap: 4px;
min-width: 0;
justify-content: center;
gap: 2px;
min-width: 92px;
padding: 9px 11px;
border: 1px solid #bbf7d0;
border-radius: 10px;
background: linear-gradient(145deg, #f0fdf4, #ecfdf5);
}
.health-summary-copy strong {
color: var(--mon-ink);
font-size: 13px;
color: #047857;
font-size: 17px;
line-height: 1.2;
}
.health-summary-copy span {
.health-summary-copy .health-summary-label {
color: var(--mon-muted);
font-size: 11px;
line-height: 1.45;
font-size: 10px;
}
.health-summary-copy.is-degraded {
border-color: #fde68a;
background: linear-gradient(145deg, #fffbeb, #fef3c7);
}
.health-summary-copy.is-degraded strong {
color: #b45309;
}
.health-summary-copy.is-unhealthy {
border-color: #fecaca;
background: linear-gradient(145deg, #fef2f2, #fee2e2);
}
.health-summary-copy.is-unhealthy strong {
color: #dc2626;
}
.health-summary-copy.is-unknown {
border-color: #dbe3ef;
background: #f8fafc;
}
.health-summary-copy.is-unknown strong {
color: #64748b;
}
.score-inner strong {
@@ -1348,16 +1413,36 @@ defineExpose({ refresh });
.health-signal-list {
display: flex;
flex-wrap: wrap;
gap: 4px 6px;
gap: 5px;
}
.health-signal-list span {
color: var(--mon-muted);
font-size: 11px;
.health-signal-item {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 3px 7px;
border: 1px solid #d1fae5;
border-radius: 999px;
background: #f0fdf4;
font-size: 10px;
white-space: nowrap;
}
.health-signal-list .is-warning {
.health-signal-item span {
color: var(--mon-muted);
}
.health-signal-item strong {
color: #047857;
font-size: 10px;
}
.health-signal-item.is-warning {
border-color: #fde68a;
background: #fffbeb;
}
.health-signal-item.is-warning strong {
color: #b45309;
}
@@ -1729,6 +1814,7 @@ defineExpose({ refresh });
}
.soybean-monitoring-tabs :deep(.el-tabs__header) {
flex-basis: 48px;
margin-bottom: 8px;
padding: 0 12px;
}