feat(scheduling): rename 通知→干预, allow drill-in on intervened items

- Globally rename user-facing 通知 → 干预 (list badge, detail button, batch
  modal, CSV header, server response messages, db table comment)
- 已干预 row in detail is now clickable — opens SwapPreview which shows
  a read-only summary plus a 取消干预 action (PATCH notify /:id with
  status=cancelled). Sending is blocked while already intervened.
- Selected suggestion now follows the latest data snapshot so status
  changes from within the detail flow propagate immediately.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
kkfluous
2026-04-17 09:14:53 +08:00
parent 1d9f4cb43d
commit 210db7f8ff
8 changed files with 69 additions and 32 deletions

View File

@@ -20,7 +20,7 @@ CREATE TABLE IF NOT EXISTS tab_scheduling_notifications (
INDEX idx_candidate_plate (candidate_plate),
INDEX idx_status (status),
INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='智能调度通知/执行记录'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='智能调度干预/执行记录'
`;
export async function ensureSchedulingTables(): Promise<void> {

View File

@@ -119,12 +119,12 @@ app.post('/', async (c) => {
return c.json({
success: true,
message: `替换通知已发送${currentPlate}${candidatePlate}`,
message: `干预已登记${currentPlate}${candidatePlate}`,
record: result,
});
} catch (e: unknown) {
console.error('scheduling notify error:', e);
return c.json({ success: false, message: '发送通知失败' }, 500);
return c.json({ success: false, message: '登记干预失败' }, 500);
}
});
@@ -166,12 +166,12 @@ app.post('/batch', async (c) => {
return c.json({
success: true,
message: `批量通知:成功 ${result.success},跳过 ${result.skipped},失败 ${result.failed}`,
message: `批量干预:成功 ${result.success},跳过 ${result.skipped},失败 ${result.failed}`,
result,
});
} catch (e: unknown) {
console.error('scheduling batch notify error:', e);
return c.json({ success: false, message: '批量通知失败' }, 500);
return c.json({ success: false, message: '批量干预失败' }, 500);
}
});