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
Hide 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'
...
@@ -6,7 +6,7 @@ import { opsAPI } from '@/api/admin/ops'
import
BaseDialog
from
'
@/components/common/BaseDialog.vue
'
import
BaseDialog
from
'
@/components/common/BaseDialog.vue
'
import
Select
from
'
@/components/common/Select.vue
'
import
Select
from
'
@/components/common/Select.vue
'
import
Toggle
from
'
@/components/common/Toggle.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
{
t
}
=
useI18n
()
const
appStore
=
useAppStore
()
const
appStore
=
useAppStore
()
...
@@ -29,19 +29,38 @@ const runtimeSettings = ref<OpsAlertRuntimeSettings | null>(null)
...
@@ -29,19 +29,38 @@ const runtimeSettings = ref<OpsAlertRuntimeSettings | null>(null)
const
emailConfig
=
ref
<
EmailNotificationConfig
|
null
>
(
null
)
const
emailConfig
=
ref
<
EmailNotificationConfig
|
null
>
(
null
)
// 高级设置
// 高级设置
const
advancedSettings
=
ref
<
OpsAdvancedSettings
|
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
()
{
async
function
loadAllSettings
()
{
loading
.
value
=
true
loading
.
value
=
true
try
{
try
{
const
[
runtime
,
email
,
advanced
]
=
await
Promise
.
all
([
const
[
runtime
,
email
,
advanced
,
thresholds
]
=
await
Promise
.
all
([
opsAPI
.
getAlertRuntimeSettings
(),
opsAPI
.
getAlertRuntimeSettings
(),
opsAPI
.
getEmailNotificationConfig
(),
opsAPI
.
getEmailNotificationConfig
(),
opsAPI
.
getAdvancedSettings
()
opsAPI
.
getAdvancedSettings
(),
opsAPI
.
getMetricThresholds
()
])
])
runtimeSettings
.
value
=
runtime
runtimeSettings
.
value
=
runtime
emailConfig
.
value
=
email
emailConfig
.
value
=
email
advancedSettings
.
value
=
advanced
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
)
{
}
catch
(
err
:
any
)
{
console
.
error
(
'
[OpsSettingsDialog] Failed to load settings
'
,
err
)
console
.
error
(
'
[OpsSettingsDialog] Failed to load settings
'
,
err
)
appStore
.
showError
(
err
?.
response
?.
data
?.
detail
||
t
(
'
admin.ops.settings.loadFailed
'
))
appStore
.
showError
(
err
?.
response
?.
data
?.
detail
||
t
(
'
admin.ops.settings.loadFailed
'
))
...
@@ -138,6 +157,23 @@ const validation = computed(() => {
...
@@ -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
}
return
{
valid
:
errors
.
length
===
0
,
errors
}
})
})
...
@@ -153,14 +189,15 @@ async function saveAllSettings() {
...
@@ -153,14 +189,15 @@ async function saveAllSettings() {
await
Promise
.
all
([
await
Promise
.
all
([
runtimeSettings
.
value
?
opsAPI
.
updateAlertRuntimeSettings
(
runtimeSettings
.
value
)
:
Promise
.
resolve
(),
runtimeSettings
.
value
?
opsAPI
.
updateAlertRuntimeSettings
(
runtimeSettings
.
value
)
:
Promise
.
resolve
(),
emailConfig
.
value
?
opsAPI
.
updateEmailNotificationConfig
(
emailConfig
.
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
'
))
appStore
.
showSuccess
(
t
(
'
admin.ops.settings.saveSuccess
'
))
emit
(
'
saved
'
)
emit
(
'
saved
'
)
emit
(
'
close
'
)
emit
(
'
close
'
)
}
catch
(
err
:
any
)
{
}
catch
(
err
:
any
)
{
console
.
error
(
'
[OpsSettingsDialog] Failed to save settings
'
,
err
)
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
{
}
finally
{
saving
.
value
=
false
saving
.
value
=
false
}
}
...
@@ -306,6 +343,77 @@ async function saveAllSettings() {
...
@@ -306,6 +343,77 @@ async function saveAllSettings() {
</div>
</div>
</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"
>
<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"
>
<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 {
...
@@ -14,6 +14,7 @@ export type {
EmailNotificationConfig
,
EmailNotificationConfig
,
OpsDistributedLockSettings
,
OpsDistributedLockSettings
,
OpsAlertRuntimeSettings
,
OpsAlertRuntimeSettings
,
OpsMetricThresholds
,
OpsAdvancedSettings
,
OpsAdvancedSettings
,
OpsDataRetentionSettings
,
OpsDataRetentionSettings
,
OpsAggregationSettings
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