Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
b588ea19
Unverified
Commit
b588ea19
authored
Jan 12, 2026
by
Wesley Liddick
Committed by
GitHub
Jan 12, 2026
Browse files
Merge pull request #251 from IanShaw027/fix/ops-bugs
feat(ops): 运维看板功能增强 - 实时流量监控与指标阈值配置
parents
465ba767
e0cccf6e
Changes
22
Show whitespace changes
Inline
Side-by-side
frontend/src/views/admin/ops/components/OpsSettingsDialog.vue
View file @
b588ea19
...
...
@@ -6,7 +6,7 @@ import { opsAPI } from '@/api/admin/ops'
import
BaseDialog
from
'
@/components/common/BaseDialog.vue
'
import
Select
from
'
@/components/common/Select.vue
'
import
Toggle
from
'
@/components/common/Toggle.vue
'
import
type
{
OpsAlertRuntimeSettings
,
EmailNotificationConfig
,
AlertSeverity
,
OpsAdvancedSettings
}
from
'
../types
'
import
type
{
OpsAlertRuntimeSettings
,
EmailNotificationConfig
,
AlertSeverity
,
OpsAdvancedSettings
,
OpsMetricThresholds
}
from
'
../types
'
const
{
t
}
=
useI18n
()
const
appStore
=
useAppStore
()
...
...
@@ -29,19 +29,38 @@ const runtimeSettings = ref<OpsAlertRuntimeSettings | null>(null)
const
emailConfig
=
ref
<
EmailNotificationConfig
|
null
>
(
null
)
// 高级设置
const
advancedSettings
=
ref
<
OpsAdvancedSettings
|
null
>
(
null
)
// 指标阈值配置
const
metricThresholds
=
ref
<
OpsMetricThresholds
>
({
sla_percent_min
:
99.5
,
latency_p99_ms_max
:
2000
,
ttft_p99_ms_max
:
500
,
request_error_rate_percent_max
:
5
,
upstream_error_rate_percent_max
:
5
})
// 加载所有配置
async
function
loadAllSettings
()
{
loading
.
value
=
true
try
{
const
[
runtime
,
email
,
advanced
]
=
await
Promise
.
all
([
const
[
runtime
,
email
,
advanced
,
thresholds
]
=
await
Promise
.
all
([
opsAPI
.
getAlertRuntimeSettings
(),
opsAPI
.
getEmailNotificationConfig
(),
opsAPI
.
getAdvancedSettings
()
opsAPI
.
getAdvancedSettings
(),
opsAPI
.
getMetricThresholds
()
])
runtimeSettings
.
value
=
runtime
emailConfig
.
value
=
email
advancedSettings
.
value
=
advanced
// 如果后端返回了阈值,使用后端的值;否则保持默认值
if
(
thresholds
&&
Object
.
keys
(
thresholds
).
length
>
0
)
{
metricThresholds
.
value
=
{
sla_percent_min
:
thresholds
.
sla_percent_min
??
99.5
,
latency_p99_ms_max
:
thresholds
.
latency_p99_ms_max
??
2000
,
ttft_p99_ms_max
:
thresholds
.
ttft_p99_ms_max
??
500
,
request_error_rate_percent_max
:
thresholds
.
request_error_rate_percent_max
??
5
,
upstream_error_rate_percent_max
:
thresholds
.
upstream_error_rate_percent_max
??
5
}
}
}
catch
(
err
:
any
)
{
console
.
error
(
'
[OpsSettingsDialog] Failed to load settings
'
,
err
)
appStore
.
showError
(
err
?.
response
?.
data
?.
detail
||
t
(
'
admin.ops.settings.loadFailed
'
))
...
...
@@ -138,6 +157,23 @@ const validation = computed(() => {
}
}
// 验证指标阈值
if
(
metricThresholds
.
value
.
sla_percent_min
!=
null
&&
(
metricThresholds
.
value
.
sla_percent_min
<
0
||
metricThresholds
.
value
.
sla_percent_min
>
100
))
{
errors
.
push
(
'
SLA最低百分比必须在0-100之间
'
)
}
if
(
metricThresholds
.
value
.
latency_p99_ms_max
!=
null
&&
metricThresholds
.
value
.
latency_p99_ms_max
<
0
)
{
errors
.
push
(
'
延迟P99最大值必须大于等于0
'
)
}
if
(
metricThresholds
.
value
.
ttft_p99_ms_max
!=
null
&&
metricThresholds
.
value
.
ttft_p99_ms_max
<
0
)
{
errors
.
push
(
'
TTFT P99最大值必须大于等于0
'
)
}
if
(
metricThresholds
.
value
.
request_error_rate_percent_max
!=
null
&&
(
metricThresholds
.
value
.
request_error_rate_percent_max
<
0
||
metricThresholds
.
value
.
request_error_rate_percent_max
>
100
))
{
errors
.
push
(
'
请求错误率最大值必须在0-100之间
'
)
}
if
(
metricThresholds
.
value
.
upstream_error_rate_percent_max
!=
null
&&
(
metricThresholds
.
value
.
upstream_error_rate_percent_max
<
0
||
metricThresholds
.
value
.
upstream_error_rate_percent_max
>
100
))
{
errors
.
push
(
'
上游错误率最大值必须在0-100之间
'
)
}
return
{
valid
:
errors
.
length
===
0
,
errors
}
})
...
...
@@ -153,14 +189,15 @@ async function saveAllSettings() {
await
Promise
.
all
([
runtimeSettings
.
value
?
opsAPI
.
updateAlertRuntimeSettings
(
runtimeSettings
.
value
)
:
Promise
.
resolve
(),
emailConfig
.
value
?
opsAPI
.
updateEmailNotificationConfig
(
emailConfig
.
value
)
:
Promise
.
resolve
(),
advancedSettings
.
value
?
opsAPI
.
updateAdvancedSettings
(
advancedSettings
.
value
)
:
Promise
.
resolve
()
advancedSettings
.
value
?
opsAPI
.
updateAdvancedSettings
(
advancedSettings
.
value
)
:
Promise
.
resolve
(),
opsAPI
.
updateMetricThresholds
(
metricThresholds
.
value
)
])
appStore
.
showSuccess
(
t
(
'
admin.ops.settings.saveSuccess
'
))
emit
(
'
saved
'
)
emit
(
'
close
'
)
}
catch
(
err
:
any
)
{
console
.
error
(
'
[OpsSettingsDialog] Failed to save settings
'
,
err
)
appStore
.
showError
(
err
?.
response
?.
data
?.
detail
||
t
(
'
admin.ops.settings.saveFailed
'
))
appStore
.
showError
(
err
?.
response
?.
data
?.
message
||
err
?.
response
?.
data
?.
detail
||
t
(
'
admin.ops.settings.saveFailed
'
))
}
finally
{
saving
.
value
=
false
}
...
...
@@ -306,6 +343,77 @@ async function saveAllSettings() {
</div>
</div>
<!-- 指标阈值配置 -->
<div
class=
"rounded-2xl bg-gray-50 p-4 dark:bg-dark-700/50"
>
<h4
class=
"mb-3 text-sm font-semibold text-gray-900 dark:text-white"
>
{{
t
(
'
admin.ops.settings.metricThresholds
'
)
}}
</h4>
<p
class=
"mb-4 text-xs text-gray-500 dark:text-gray-400"
>
{{
t
(
'
admin.ops.settings.metricThresholdsHint
'
)
}}
</p>
<div
class=
"space-y-4"
>
<div>
<label
class=
"input-label"
>
{{
t
(
'
admin.ops.settings.slaMinPercent
'
)
}}
</label>
<input
v-model.number=
"metricThresholds.sla_percent_min"
type=
"number"
min=
"0"
max=
"100"
step=
"0.1"
class=
"input"
/>
<p
class=
"mt-1 text-xs text-gray-500"
>
{{
t
(
'
admin.ops.settings.slaMinPercentHint
'
)
}}
</p>
</div>
<div>
<label
class=
"input-label"
>
{{
t
(
'
admin.ops.settings.latencyP99MaxMs
'
)
}}
</label>
<input
v-model.number=
"metricThresholds.latency_p99_ms_max"
type=
"number"
min=
"0"
step=
"100"
class=
"input"
/>
<p
class=
"mt-1 text-xs text-gray-500"
>
{{
t
(
'
admin.ops.settings.latencyP99MaxMsHint
'
)
}}
</p>
</div>
<div>
<label
class=
"input-label"
>
{{
t
(
'
admin.ops.settings.ttftP99MaxMs
'
)
}}
</label>
<input
v-model.number=
"metricThresholds.ttft_p99_ms_max"
type=
"number"
min=
"0"
step=
"50"
class=
"input"
/>
<p
class=
"mt-1 text-xs text-gray-500"
>
{{
t
(
'
admin.ops.settings.ttftP99MaxMsHint
'
)
}}
</p>
</div>
<div>
<label
class=
"input-label"
>
{{
t
(
'
admin.ops.settings.requestErrorRateMaxPercent
'
)
}}
</label>
<input
v-model.number=
"metricThresholds.request_error_rate_percent_max"
type=
"number"
min=
"0"
max=
"100"
step=
"0.1"
class=
"input"
/>
<p
class=
"mt-1 text-xs text-gray-500"
>
{{
t
(
'
admin.ops.settings.requestErrorRateMaxPercentHint
'
)
}}
</p>
</div>
<div>
<label
class=
"input-label"
>
{{
t
(
'
admin.ops.settings.upstreamErrorRateMaxPercent
'
)
}}
</label>
<input
v-model.number=
"metricThresholds.upstream_error_rate_percent_max"
type=
"number"
min=
"0"
max=
"100"
step=
"0.1"
class=
"input"
/>
<p
class=
"mt-1 text-xs text-gray-500"
>
{{
t
(
'
admin.ops.settings.upstreamErrorRateMaxPercentHint
'
)
}}
</p>
</div>
</div>
</div>
<!-- 高级设置 -->
<details
class=
"rounded-2xl bg-gray-50 dark:bg-dark-700/50"
>
<summary
class=
"cursor-pointer p-4 text-sm font-semibold text-gray-900 dark:text-white"
>
...
...
frontend/src/views/admin/ops/types.ts
View file @
b588ea19
...
...
@@ -14,6 +14,7 @@ export type {
EmailNotificationConfig
,
OpsDistributedLockSettings
,
OpsAlertRuntimeSettings
,
OpsMetricThresholds
,
OpsAdvancedSettings
,
OpsDataRetentionSettings
,
OpsAggregationSettings
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment