diff --git a/frontend/src/pages/Resource/Server/List/components/AlertRuleFormDialog.tsx b/frontend/src/pages/Resource/Server/List/components/AlertRuleFormDialog.tsx index 7929e02d..58f5aa6f 100644 --- a/frontend/src/pages/Resource/Server/List/components/AlertRuleFormDialog.tsx +++ b/frontend/src/pages/Resource/Server/List/components/AlertRuleFormDialog.tsx @@ -382,6 +382,8 @@ export const AlertRuleFormDialog: React.FC = ({ render={({ field }) => { const currentAlertType = form.watch('alertType'); const isServerStatus = currentAlertType === AlertType.SERVER_STATUS; + const isNetworkType = currentAlertType === AlertType.NETWORK; + const maxValue = isNetworkType ? 10000 : 100; const [localValue, setLocalValue] = React.useState( field.value?.toString() ?? '' ); @@ -401,7 +403,7 @@ export const AlertRuleFormDialog: React.FC = ({ { @@ -440,6 +442,8 @@ export const AlertRuleFormDialog: React.FC = ({ render={({ field }) => { const currentAlertType = form.watch('alertType'); const isServerStatus = currentAlertType === AlertType.SERVER_STATUS; + const isNetworkType = currentAlertType === AlertType.NETWORK; + const maxValue = isNetworkType ? 10000 : 100; const [localValue, setLocalValue] = React.useState( field.value?.toString() ?? '' ); @@ -459,7 +463,7 @@ export const AlertRuleFormDialog: React.FC = ({ { diff --git a/frontend/src/pages/Resource/Server/List/schema.ts b/frontend/src/pages/Resource/Server/List/schema.ts index 4bab13f5..8e4d89f9 100644 --- a/frontend/src/pages/Resource/Server/List/schema.ts +++ b/frontend/src/pages/Resource/Server/List/schema.ts @@ -82,17 +82,51 @@ export const alertRuleFormSchema = z.object({ alertType: z.nativeEnum(AlertType, { errorMap: () => ({ message: '请选择告警类型' }) }), - warningThreshold: z.number() - .min(0, '警告阈值不能小于0') - .max(100, '警告阈值不能大于100'), - criticalThreshold: z.number() - .min(0, '严重阈值不能小于0') - .max(100, '严重阈值不能大于100'), + warningThreshold: z.number().min(0, '警告阈值不能小于0'), + criticalThreshold: z.number().min(0, '严重阈值不能小于0'), durationMinutes: z.number() .min(1, '持续时长至少为1分钟'), enabled: z.boolean().default(true), description: z.string().max(500, '描述不能超过500个字符').optional(), }).superRefine((data, ctx) => { + // 根据告警类型验证阈值范围 + const isPercentageType = [AlertType.CPU, AlertType.MEMORY, AlertType.DISK].includes(data.alertType); + const isNetworkType = data.alertType === AlertType.NETWORK; + + if (isPercentageType) { + // CPU/内存/磁盘使用率:0-100 + if (data.warningThreshold > 100) { + ctx.addIssue({ + code: 'custom', + message: '警告阈值不能大于100', + path: ['warningThreshold'], + }); + } + if (data.criticalThreshold > 100) { + ctx.addIssue({ + code: 'custom', + message: '严重阈值不能大于100', + path: ['criticalThreshold'], + }); + } + } else if (isNetworkType) { + // 网络流量:0-10000 MB/s + if (data.warningThreshold > 10000) { + ctx.addIssue({ + code: 'custom', + message: '警告阈值不能大于10000', + path: ['warningThreshold'], + }); + } + if (data.criticalThreshold > 10000) { + ctx.addIssue({ + code: 'custom', + message: '严重阈值不能大于10000', + path: ['criticalThreshold'], + }); + } + } + // 严重阈值必须大于警告阈值 if (data.criticalThreshold <= data.warningThreshold) { ctx.addIssue({ diff --git a/frontend/src/pages/System/Release/List/components/ReleaseEditDialog.tsx b/frontend/src/pages/System/Release/List/components/ReleaseEditDialog.tsx index 1163394a..c1e89b54 100644 --- a/frontend/src/pages/System/Release/List/components/ReleaseEditDialog.tsx +++ b/frontend/src/pages/System/Release/List/components/ReleaseEditDialog.tsx @@ -286,54 +286,98 @@ export const ReleaseEditDialog: React.FC = ({ ( - - - 延迟执行(分钟) * - - - field.onChange(e.target.value ? parseInt(e.target.value) : 0)} - /> - -

- 延迟执行分钟数(0表示立即执行) -

- -
- )} + render={({ field }) => { + const [localValue, setLocalValue] = React.useState( + field.value?.toString() ?? '' + ); + + React.useEffect(() => { + setLocalValue(field.value?.toString() ?? ''); + }, [field.value]); + + return ( + + + 延迟执行(分钟) * + + + { + const value = e.target.value; + setLocalValue(value); + if (value !== '') { + field.onChange(parseInt(value)); + } + }} + onBlur={() => { + if (localValue === '') { + field.onChange(undefined); + } + field.onBlur(); + }} + name={field.name} + /> + +

+ 延迟执行分钟数(0表示立即执行) +

+ +
+ ); + }} /> {/* 预计维护时长 */} ( - - - 预计时长(分钟) * - - - field.onChange(e.target.value ? parseInt(e.target.value) : 30)} - /> - -

- 预计维护所需时长(分钟) -

- -
- )} + render={({ field }) => { + const [localValue, setLocalValue] = React.useState( + field.value?.toString() ?? '' + ); + + React.useEffect(() => { + setLocalValue(field.value?.toString() ?? ''); + }, [field.value]); + + return ( + + + 预计时长(分钟) * + + + { + const value = e.target.value; + setLocalValue(value); + if (value !== '') { + field.onChange(parseInt(value)); + } + }} + onBlur={() => { + if (localValue === '') { + field.onChange(undefined); + } + field.onBlur(); + }} + name={field.name} + /> + +

+ 预计维护所需时长(分钟) +

+ +
+ ); + }} /> {/* 是否自动停止服务 */}