# 画面設計書 54-定時任務編集

## 概要

本ドキュメントは、RuoYi後台管理システムの定時任務編集画面の設計仕様を記述したものである。

### 本画面の処理概要

定時任務編集画面は、既存の定期実行タスクの設定を変更するための入力フォーム画面である。タスク名、呼び出し先、Cron式、実行ポリシー、ステータスなどを編集し、Quartzスケジューラの設定を更新する。

**業務上の目的・背景**：運用中にタスクのスケジュール変更や呼び出し先の変更が必要になった場合、本画面から設定を修正できる。また、タスクの有効化/無効化もこの画面から行える。これにより、運用担当者が柔軟にタスク設定を管理できる。

**画面へのアクセス方法**：定時任務管理一覧画面から対象タスクの「編集」ボタンをクリックすることでモーダルダイアログとして表示される。アクセスには`monitor:job:edit`権限が必要である。

**主要な操作・処理内容**：
1. 既存タスク情報の表示と編集
2. 任務分組、執行策略、並発執行、状態の変更
3. Cron式の変更とリアルタイムバリデーション
4. 更新処理の実行

**画面遷移**：定時任務管理一覧画面から遷移し、保存成功後は一覧画面に戻る。

**権限による表示制御**：`monitor:job:edit`権限がない場合、本画面にはアクセスできない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 16 | 定期タスク管理 | 主機能 | タスク情報の更新保存処理 |

## 画面種別

編集

## URL/ルーティング

| 操作 | メソッド | URL |
|------|----------|-----|
| 画面表示 | GET | /monitor/job/edit/{jobId} |
| 保存 | POST | /monitor/job/edit |
| Cron式検証 | POST | /monitor/job/checkCronExpressionIsValid |

## 入出力項目

### 入力項目

| 項目名 | 項目ID | データ型 | 必須 | 最大長 | 説明 |
|--------|--------|----------|------|--------|------|
| 任務ID | jobId | Long | - | - | hidden項目（編集対象の主キー） |
| 更新者 | updateBy | String | - | - | hidden項目（ログインユーザー名を自動設定） |
| 任務名称 | jobName | String | 必須 | 64 | タスク名 |
| 任務分組 | jobGroup | String | 任意 | - | タスクグループ（辞書：sys_job_group） |
| 調用目標字符串 | invokeTarget | String | 必須 | 1000 | 呼び出し対象 |
| cron表達式 | cronExpression | String | 必須 | 255 | Cron式 |
| 執行策略 | misfirePolicy | String | 任意 | - | 1:立即執行、2:執行一次、3:放棄執行 |
| 並発執行 | concurrent | String | 任意 | - | 0:允許、1:禁止 |
| 状態 | status | String | 任意 | - | 0:正常、1:暂停（辞書：sys_job_status） |
| 備注 | remark | String | 任意 | - | 備考欄 |

## 表示項目

入力項目と同じ（既存データを初期表示）

## イベント仕様

### 1-確定（保存）ボタン押下

1. クライアント側でフォームバリデーションを実行
2. Cron式のサーバーサイドバリデーションを実行
3. 検証成功の場合、フォームデータをサーバーに送信
4. サーバー側でセキュリティチェック（RMI、LDAP、HTTP呼び出し禁止、ホワイトリストチェック）
5. Quartzスケジューラのジョブ設定を更新
6. DBのタスク情報を更新
7. 処理成功の場合、モーダルを閉じて一覧を再読み込み
8. 処理失敗の場合、エラーメッセージを表示

### 2-Cron式入力時

入力内容が変更されるたびに、サーバーにCron式の検証リクエストを送信し、無効な場合はエラーメッセージ「表達式不正確」を表示する。

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 画面表示 | sys_job | SELECT | タスク情報の取得 |
| 保存 | sys_job | UPDATE | タスクレコードの更新 |

### テーブル別更新項目詳細

#### sys_job

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | job_id | = パスパラメータ | 主キー |
| UPDATE | job_name | 入力値 | 必須 |
| UPDATE | job_group | 入力値 | - |
| UPDATE | invoke_target | 入力値 | 必須 |
| UPDATE | cron_expression | 入力値 | 必須 |
| UPDATE | misfire_policy | 入力値 | - |
| UPDATE | concurrent | 入力値 | - |
| UPDATE | status | 入力値 | - |
| UPDATE | update_by | ログインユーザー名 | - |
| UPDATE | update_time | 現在日時 | - |
| UPDATE | remark | 入力値 | - |

## メッセージ仕様

| 種別 | メッセージ | 発生条件 |
|------|-----------|----------|
| エラー | 表達式不正確 | Cron式が無効な場合 |
| エラー | 修改任務'XXX'失敗，Cron表達式不正確 | 保存時にCron式が無効 |
| エラー | 修改任務'XXX'失敗，目標字符串不允許'rmi'調用 | RMI呼び出しを含む場合 |
| エラー | 修改任務'XXX'失敗，目標字符串不允許'ldap'調用 | LDAP呼び出しを含む場合 |
| エラー | 修改任務'XXX'失敗，目標字符串不允許'http(s)'調用 | HTTP呼び出しを含む場合 |
| エラー | 修改任務'XXX'失敗，目標字符串存在違規 | 禁止文字列を含む場合 |
| エラー | 修改任務'XXX'失敗，目標字符串不在白名單内 | ホワイトリスト外の場合 |
| 成功 | 操作成功 | 処理正常完了時 |

## 例外処理

| 例外ケース | 処理内容 |
|-----------|----------|
| タスク未存在 | エラーメッセージを表示 |
| Cron式無効 | エラーメッセージを表示、保存を中断 |
| セキュリティ違反 | エラーメッセージを表示、保存を中断 |
| 権限不足 | 403エラー画面に遷移 |
| サーバーエラー | 500エラー画面に遷移 |

## 備考

- 新規登録画面との違いは、状態（status）の編集が可能な点
- ステータス変更時はQuartzスケジューラのジョブも一時停止/再開される
- Cron式の変更時は次回実行時刻が再計算される

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SysJob.java | `ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java` | フィールド定義とバリデーション |

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | SysJobController.java | `ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java` | edit（GET/POST）メソッドを確認 |

**主要処理フロー**:
1. **168-174行目**: edit()メソッドで画面表示（GET /monitor/job/edit/{jobId}）
2. **179-210行目**: editSave()メソッドで保存処理（POST /monitor/job/edit）
3. **185-207行目**: セキュリティチェック

#### Step 3: ビュー層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | edit.html | `ruoyi-quartz/src/main/resources/templates/monitor/job/edit.html` | th:field、th:objectによるデータバインディング |

**主要処理フロー**:
- **8-69行目**: フォーム定義（th:objectでjobをバインド）
- **56-62行目**: 状態選択（新規登録にはない項目）

### プログラム呼び出し階層図

```
SysJobController.editSave()
    │
    ├─ CronUtils.isValid() ─── Cron式検証
    │
    ├─ セキュリティチェック
    │
    └─ ISysJobService.updateJob()
           ├─ SysJobMapper.updateJob() ─── DB UPDATE
           └─ ScheduleUtils.updateScheduleJob() ─── Quartz更新
                 ├─ deleteScheduleJob()
                 └─ createScheduleJob()
```

### データフロー図

```
[入力]               [処理]                    [出力]

フォーム入力 ───▶ SysJobController.editSave() ───▶ AjaxResult
(jobId,            │
 jobName,          ├─▶ バリデーション
 invokeTarget,     │
 cronExpression,   ├─▶ セキュリティチェック
 misfirePolicy,    │
 concurrent,       ├─▶ ISysJobService.updateJob()
 status,           │    ├─▶ SysJobMapper
 remark)           │    │    └─▶ sys_job(UPDATE)
                   │    └─▶ Quartz Scheduler
                   │         └─▶ ジョブ更新
                   │
                   └─▶ 成功/エラーレスポンス
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SysJobController.java | `ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java` | ソース | コントローラー |
| ISysJobService.java | `ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/ISysJobService.java` | ソース | サービスインターフェース |
| SysJobServiceImpl.java | `ruoyi-quartz/src/main/java/com/ruoyi/quartz/service/impl/SysJobServiceImpl.java` | ソース | サービス実装 |
| SysJob.java | `ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java` | ソース | ドメインクラス |
| edit.html | `ruoyi-quartz/src/main/resources/templates/monitor/job/edit.html` | テンプレート | 画面テンプレート |
