|
|
@@ -104,6 +104,17 @@ const POLL_INTERVAL_PRESETS = [
|
|
|
{ label: '4 小时', value: 14400 },
|
|
|
];
|
|
|
|
|
|
+// S8-SCHED-SAVE-SPLIT-1:打开抽屉时记录的 schedule / params / enabled 快照,
|
|
|
+// 用于在 save() 中判断真实变更,避免无意义触发 PUT /params 重序列化。
|
|
|
+interface ScheduleSnapshot {
|
|
|
+ pollIntervalSeconds: number;
|
|
|
+ triggerCountRequired: number;
|
|
|
+ recoverCountRequired: number;
|
|
|
+}
|
|
|
+const originalScheduleSnapshot = ref<ScheduleSnapshot | null>(null);
|
|
|
+const originalParamsSnapshot = ref<string | null>(null);
|
|
|
+const originalEnabled = ref<boolean>(true);
|
|
|
+
|
|
|
// S8-SCHED-FRONTEND-1:30s 自动刷新;onMounted/onActivated 启动;onUnmounted/onDeactivated 清理。
|
|
|
const REFRESH_INTERVAL_MS = 30000;
|
|
|
let refreshTimer: ReturnType<typeof setInterval> | null = null;
|
|
|
@@ -250,9 +261,35 @@ function loadFormFromRow(row: S8WatchRuleConfigRow) {
|
|
|
function openEdit(row: S8WatchRuleConfigRow) {
|
|
|
editingRow.value = row;
|
|
|
loadFormFromRow(row);
|
|
|
+ // S8-SCHED-SAVE-SPLIT-1:写入快照。schedule 走数值归一化;params 走 buildPayloadParamsJson
|
|
|
+ // 自身的稳定 key 顺序,因此打开时与保存时两次调用即可字节级比较。
|
|
|
+ originalScheduleSnapshot.value = {
|
|
|
+ pollIntervalSeconds: clampInt(scheduleForm.pollIntervalSeconds, 60, 86400, 300),
|
|
|
+ triggerCountRequired: clampInt(scheduleForm.triggerCountRequired, 1, 10, 1),
|
|
|
+ recoverCountRequired: clampInt(scheduleForm.recoverCountRequired, 1, 10, 1),
|
|
|
+ };
|
|
|
+ originalParamsSnapshot.value = buildPayloadParamsJson();
|
|
|
+ originalEnabled.value = enabledForm.value;
|
|
|
drawerOpen.value = true;
|
|
|
}
|
|
|
|
|
|
+function hasScheduleChanged(): boolean {
|
|
|
+ const o = originalScheduleSnapshot.value;
|
|
|
+ if (!o) return false;
|
|
|
+ return (
|
|
|
+ clampInt(scheduleForm.pollIntervalSeconds, 60, 86400, 300) !== o.pollIntervalSeconds
|
|
|
+ || clampInt(scheduleForm.triggerCountRequired, 1, 10, 1) !== o.triggerCountRequired
|
|
|
+ || clampInt(scheduleForm.recoverCountRequired, 1, 10, 1) !== o.recoverCountRequired
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+function hasParamsChanged(): boolean {
|
|
|
+ // enabled 在后端走 /params 端点,因此 enabled 切换视为 params 变更。
|
|
|
+ if (enabledForm.value !== originalEnabled.value) return true;
|
|
|
+ const next = buildPayloadParamsJson();
|
|
|
+ return next !== originalParamsSnapshot.value;
|
|
|
+}
|
|
|
+
|
|
|
function closeDrawer() {
|
|
|
drawerOpen.value = false;
|
|
|
editingRow.value = null;
|
|
|
@@ -305,19 +342,35 @@ function buildPayloadParamsJson(): string | null {
|
|
|
|
|
|
async function save() {
|
|
|
if (!editingRow.value) return;
|
|
|
+ const scheduleChanged = hasScheduleChanged();
|
|
|
+ const paramsChanged = hasParamsChanged();
|
|
|
+ if (!scheduleChanged && !paramsChanged) {
|
|
|
+ ElMessage.info('未检测到变更');
|
|
|
+ return;
|
|
|
+ }
|
|
|
saving.value = true;
|
|
|
try {
|
|
|
- // 调度参数走专用 schedule 端点;params_json / rule_type / expression 不会被触碰。
|
|
|
- await s8ConfigApi.watchRules.updateSchedule(editingRow.value.id, {
|
|
|
+ if (scheduleChanged) {
|
|
|
+ await s8ConfigApi.watchRules.updateSchedule(editingRow.value.id, {
|
|
|
+ pollIntervalSeconds: clampInt(scheduleForm.pollIntervalSeconds, 60, 86400, 300),
|
|
|
+ triggerCountRequired: clampInt(scheduleForm.triggerCountRequired, 1, 10, 1),
|
|
|
+ recoverCountRequired: clampInt(scheduleForm.recoverCountRequired, 1, 10, 1),
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (paramsChanged) {
|
|
|
+ await s8ConfigApi.watchRules.updateParams(editingRow.value.id, {
|
|
|
+ paramsJson: buildPayloadParamsJson(),
|
|
|
+ enabled: enabledForm.value,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // S8-SCHED-SAVE-SPLIT-1:保存成功后刷新快照,避免下一次保存被误判为仍有变更。
|
|
|
+ originalScheduleSnapshot.value = {
|
|
|
pollIntervalSeconds: clampInt(scheduleForm.pollIntervalSeconds, 60, 86400, 300),
|
|
|
triggerCountRequired: clampInt(scheduleForm.triggerCountRequired, 1, 10, 1),
|
|
|
recoverCountRequired: clampInt(scheduleForm.recoverCountRequired, 1, 10, 1),
|
|
|
- });
|
|
|
- // params_json + enabled 仍走原 params 端点,保持模板化保存语义。
|
|
|
- await s8ConfigApi.watchRules.updateParams(editingRow.value.id, {
|
|
|
- paramsJson: buildPayloadParamsJson(),
|
|
|
- enabled: enabledForm.value,
|
|
|
- });
|
|
|
+ };
|
|
|
+ originalParamsSnapshot.value = buildPayloadParamsJson();
|
|
|
+ originalEnabled.value = enabledForm.value;
|
|
|
ElMessage.success('保存成功');
|
|
|
closeDrawer();
|
|
|
await loadRows();
|