# PRD — 定时任务弹窗交互优化

> 版本：1.0 ｜ 日期：2026-07-21 ｜ 作者：czj

---

## 1. 背景与问题

当前定时任务创建/编辑弹窗使用 **Cron 表达式**（如 `0 8 * * *`）配置调度周期，存在以下问题：

1. **非技术人员看不懂**：Cron 表达式是运维/开发专用语法，普通管理员难以理解
2. **容易写错**：5 段格式、特殊字符规则复杂，输入错误率高
3. **缺少起止时间**：无法设置任务的有效期，任务会无限期执行
4. **预设不够直观**：虽然有快捷预设，但仍是填入 Cron 文本，用户不知道选了什么

## 2. 需求目标

将 Cron 表达式替换为**用户友好的可视化调度配置**：

- **重复周期**：每天 / 工作日 / 每周 — 三种模式覆盖绝大多数场景
- **时间点**：时:分 选择器，直观选择执行时间
- **星期选择**：每周模式下选择具体星期几
- **起止日期**：可选设置任务生效的起止日期
- **列表展示**：用自然语言描述替代 Cron 表达式显示

## 3. 功能设计

### 3.1 弹窗表单字段

| 字段 | 控件 | 说明 |
|------|------|------|
| 任务名称 | 文本输入 | 必填，如"每日全量巡检" |
| 监测目标 | 下拉选择 | 必选，从已有目标列表选 |
| 巡检套件 | 下拉选择 | 快速巡检 / 全量巡检 |
| **重复周期** | **单选按钮组** | **每天 / 工作日 / 每周** |
| **执行时间** | **时间选择器** | **时(0-23) + 分(0-59)** |
| **星期几** | **多选按钮** | **仅"每周"模式显示，可选周一~周日** |
| **生效日期** | **日期选择器** | **可选，任务开始生效日期** |
| **失效日期** | **日期选择器** | **可选，任务到期后不再执行** |

### 3.2 重复周期与 Cron 映射

| 重复周期 | 用户选择 | 生成的 Cron | 显示描述 |
|----------|----------|-------------|----------|
| 每天 | 时间 08:00 | `0 8 * * *` | 每天 08:00 |
| 工作日 | 时间 09:00 | `0 9 * * 1-5` | 工作日 09:00 |
| 每周 | 周一 + 时间 08:00 | `0 8 * * 1` | 每周一 08:00 |
| 每周 | 周一、三、五 + 时间 10:30 | `30 10 * * 1,3,5` | 每周一、三、五 10:30 |

### 3.3 起止日期逻辑

- **生效日期**（start_date）：可选，不填则立即生效。APScheduler 的 `start_date` 参数
- **失效日期**（end_date）：可选，不填则永不过期。APScheduler 的 `end_date` 参数
- 列表显示：如有起止日期，在描述后追加"（2026-07-21 至 2026-12-31）"

### 3.4 列表展示优化

| 原展示 | 新展示 |
|--------|--------|
| Cron 列：`0 8 * * *` | 周期列：每天 08:00 |
| Cron 列：`0 9 * * 1-5` | 周期列：工作日 09:00 |
| Cron 列：`30 10 * * 1,3,5` | 周期列：每周一、三、五 10:30 |

去掉"Cron"列头，改为"调度周期"。

### 3.5 编辑回填

编辑定时任务时，弹窗需从存储的 `repeat_mode` / `hour` / `minute` / `weekdays` / `start_date` / `end_date` 字段回填，而非反向解析 Cron。

## 4. 数据模型变更

### schedules.json 新增字段

```json
{
  "id": "sched_xxx",
  "name": "每日全量巡检",
  "target_id": "tgt_xxx",
  "target_name": "生产服务器",
  "suite": "quick",
  "cron": "0 8 * * *",
  "repeat_mode": "daily",
  "hour": 8,
  "minute": 0,
  "weekdays": [],
  "start_date": "2026-07-21",
  "end_date": "2026-12-31",
  "enabled": true,
  "next_run_at": "2026-07-22T08:00:00:00",
  "created_at": "2026-07-21T10:00:00",
  "created_by": "admin"
}
```

| 字段 | 类型 | 说明 |
|------|------|------|
| `repeat_mode` | string | `daily` / `weekday` / `weekly` |
| `hour` | int | 执行时间-时（0-23） |
| `minute` | int | 执行时间-分（0-59） |
| `weekdays` | int[] | 星期几（1=周一…7=周日），仅 weekly 模式 |
| `start_date` | string\|null | 生效日期（YYYY-MM-DD），可选 |
| `end_date` | string\|null | 失效日期（YYYY-MM-DD），可选 |

> `cron` 字段保留，由后端根据 repeat_mode/hour/minute/weekdays 自动生成，前端不再直接传 cron。

## 5. 交互细节

### 5.1 重复周期切换

- 选择"每天"：只显示时间选择器
- 选择"工作日"：只显示时间选择器
- 选择"每周"：显示时间选择器 + 星期多选按钮组

### 5.2 星期多选按钮

7 个按钮横排：周一 周二 周三 周四 周五 周六 周日
- 选中态：实心蓝色背景 + 白色文字
- 未选态：浅灰背景 + 深灰文字
- 至少选 1 个，否则提示"请选择至少一个星期"

### 5.3 时间选择器

- 小时：下拉 00-23
- 分钟：下拉 00/15/30/45（整刻度，简化选择）
- 也可手动输入任意分钟

### 5.4 起止日期

- 日期选择器（`<input type="date">`）
- 生效日期默认为今天
- 失效日期不填则表示永不过期
- 校验：失效日期必须晚于生效日期

## 6. 不做的事

- 不支持"每月"/"自定义 Cron"等高级模式（后续可扩展）
- 不修改 APScheduler 调度逻辑，仅改前端输入和后端字段转换
- 不修改已有定时任务数据（兼容旧数据：无 repeat_mode 字段时仍用 cron 显示）
