# 画面設計書 32-部門編集

## 概要

本ドキュメントは、RuoYi後台管理システムにおける「部門編集」画面の設計仕様を定義するものである。

### 本画面の処理概要

本画面は、既存の部門情報を変更するための編集フォーム画面である。部門名称、所属（上級部門）、表示順序、責任者情報など部門に関する各種属性を更新することができる。

**業務上の目的・背景**：組織運営において、部門の統廃合、名称変更、責任者異動などの組織変更は日常的に発生する。本画面は、これらの組織変更を迅速かつ正確にシステムへ反映するために必要である。特に部門の階層構造（親子関係）の変更は、配下のすべての部門のancestors（祖先情報）にも影響を与えるため、システム的に整合性を保った更新処理が求められる。

**画面へのアクセス方法**：システム首頁の左側メニューから「システム管理」>「部門管理」を選択し、部門管理一覧画面に遷移後、編集対象の部門行の「編集」ボタンをクリックすることで本画面がモーダルダイアログとして表示される。

**主要な操作・処理内容**：
1. 既存の部門情報の表示・確認
2. 上級部門の変更（部門ツリー選択画面を呼び出し、新しい親部門を指定）
3. 部門名称の変更（必須、30文字以内、同一親部門内で一意性チェック）
4. 表示順序の変更（必須、数値のみ）
5. 負責人（責任者）の変更（任意）
6. 連絡電話の変更（任意、電話番号形式チェック）
7. メールアドレスの変更（任意、メール形式チェック）
8. 部門状態の変更（正常/停用）
9. 確定ボタンで更新処理を実行

**画面遷移**：部門管理一覧画面から本画面に遷移する。上級部門選択時は部門ツリー選択画面（モーダル）が開く。更新完了後は部門管理一覧画面に戻り、一覧が更新される。

**権限による表示制御**：`system:dept:edit`権限を持つユーザーのみが本画面にアクセス可能。また、データスコープによるアクセス制限が適用され、権限のない部門データは編集できない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | 部門管理 | 主機能 | 部門情報の更新保存処理 |

## 画面種別

編集（モーダルダイアログ形式）

## URL/ルーティング

- 画面表示：`GET /system/dept/edit/{deptId}`
- 更新処理：`POST /system/dept/edit`
- 部門名一意性チェック：`POST /system/dept/checkDeptNameUnique`

## 入出力項目

| 項目名 | 項目ID | 型 | 必須 | 最大長 | 入力形式 | 備考 |
|--------|--------|-----|------|--------|----------|------|
| 部門ID | deptId | Long | ○ | - | hidden | 更新対象の識別子 |
| 親部門ID | parentId | Long | ○ | - | hidden | 部門ツリーから選択 |
| 親部門名 | treeName | String | - | - | 読取専用 | 表示用、ツリー選択で設定 |
| 部門名称 | deptName | String | ○ | 30 | テキスト | 同一親部門内で一意 |
| 表示順序 | orderNum | Integer | ○ | - | 数値 | 整数のみ |
| 負責人 | leader | String | - | - | テキスト | 責任者名 |
| 連絡電話 | phone | String | - | 11 | 電話番号 | 電話番号形式チェック |
| メール | email | String | - | 50 | メール | メール形式チェック |
| 部門状態 | status | String | - | 1 | ラジオ | 0:正常、1:停用 |

## 表示項目

| 項目名 | 表示形式 | 初期値 | 備考 |
|--------|----------|--------|------|
| 上級部門 | テキスト（読取専用）+検索ボタン | 現在の親部門名 | クリックでツリー選択 |
| 部門名称 | テキストボックス | 現在の部門名 | 必須入力 |
| 表示順序 | テキストボックス | 現在の表示順序 | 必須入力、数値のみ |
| 負責人 | テキストボックス | 現在の負責人 | 任意 |
| 連絡電話 | テキストボックス | 現在の電話番号 | 任意 |
| メール | テキストボックス | 現在のメール | 任意 |
| 部門状態 | ラジオボタン | 現在の状態 | sys_normal_disable辞書から取得 |

## イベント仕様

### 1-上級部門選択クリック

上級部門入力欄または検索アイコンをクリックすると、部門ツリー選択画面（tree.html）がモーダルダイアログとして表示される。ただし、ルート部門（deptId=100）の場合は親部門選択不可。

**処理フロー**：
1. 現在の親部門ID（treeId）が0以上かチェック
2. 0以下の場合は警告メッセージ「父部門不能選択」を表示
3. 値がある場合、`/system/dept/selectDeptTree/{treeId}/{excludeId}`を呼び出してツリー画面を開く
4. excludeIdには編集対象のdeptIdを渡し、自部門と配下部門をツリーから除外
5. ツリー画面で選択後、callBack関数でparentIdとtreeNameを更新

### 2-確定ボタン押下

入力内容のバリデーションを行い、問題がなければサーバーへPOSTリクエストを送信して部門情報を更新する。

**バリデーション処理**：
1. 必須項目チェック（部門名称、表示順序）
2. 部門名称の一意性チェック（Ajax、`/system/dept/checkDeptNameUnique`）
3. 表示順序の数値チェック
4. メールアドレス形式チェック
5. 電話番号形式チェック

**更新処理**：
1. バリデーション成功後、`/system/dept/edit`へフォームデータをPOST
2. サーバー側でデータスコープチェック
3. 部門名一意性チェック
4. 上級部門として自部門を選択していないかチェック
5. 停用への変更時、配下に正常状態の子部門がないかチェック
6. 親部門変更時はancestorsを再構築し、配下部門のancestorsも一括更新
7. 成功時：親画面を更新してモーダルを閉じる

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 確定ボタン押下 | sys_dept | UPDATE | 部門レコードの更新 |
| 親部門変更時 | sys_dept | UPDATE | 配下部門のancestors一括更新 |
| 状態を正常に変更時 | sys_dept | UPDATE | 祖先部門のstatus一括更新 |

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

#### sys_dept（メインレコード更新）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | parent_id | 画面入力値（parentId） | 親部門ID |
| UPDATE | dept_name | 画面入力値（deptName） | 部門名称 |
| UPDATE | ancestors | 新親部門のancestors + "," + 新parentId | 祖先ID列（親変更時） |
| UPDATE | order_num | 画面入力値（orderNum） | 表示順序 |
| UPDATE | leader | 画面入力値（leader） | 負責人 |
| UPDATE | phone | 画面入力値（phone） | 連絡電話 |
| UPDATE | email | 画面入力値（email） | メール |
| UPDATE | status | 画面入力値（status） | 部門状態 |
| UPDATE | update_by | ログインユーザー名 | 更新者 |
| UPDATE | update_time | sysdate() | 更新日時 |

#### sys_dept（配下部門のancestors更新）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | ancestors | 旧ancestorsを新ancestorsに置換 | 親部門変更時のみ |

#### sys_dept（祖先部門の状態更新）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | status | '0'（正常） | 正常状態への変更時、祖先部門も正常化 |

## メッセージ仕様

| メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|-------------|---------------|---------------|----------|
| MSG001 | エラー | 部門已經存在 | 部門名重複時 |
| MSG002 | エラー | 修改部門'xxx'失敗，部門名称已存在 | サーバー側重複チェック時 |
| MSG003 | エラー | 修改部門'xxx'失敗，上級部門不能是自己 | 自部門を親に設定時 |
| MSG004 | エラー | 該部門包含未停用的子部門！ | 停用変更時に正常な子部門存在 |
| MSG005 | エラー | 父部門不能選択 | ルート部門の親変更試行時 |
| MSG006 | エラー | 没有権限訪問部門数据！ | データスコープ外アクセス時 |
| MSG007 | 成功 | 操作成功 | 更新成功時 |

## 例外処理

| 例外パターン | 発生条件 | 処理内容 |
|-------------|----------|----------|
| 権限不足 | system:dept:edit権限なし | 画面アクセス拒否、エラー画面表示 |
| データスコープ外 | 権限のない部門データへのアクセス | ServiceExceptionをスロー |
| 循環参照 | 自部門を親部門に設定 | エラーメッセージ表示、処理中止 |
| 子部門制約 | 正常な子部門がある状態で停用変更 | エラーメッセージ表示、処理中止 |
| 通信エラー | Ajaxリクエスト失敗 | エラーメッセージをモーダル表示 |

## 備考

- ルート部門（deptId=100）の場合、parentNameは「無」と表示される（コントローラー行95-98）
- 親部門選択時、自部門と配下部門はツリーから除外される
- 部門を正常状態に変更した場合、すべての祖先部門も自動的に正常状態に更新される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SysDept.java | `ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java` | 部門エンティティ、特にancestorsフィールドの役割 |

**読解のコツ**: ancestorsは親部門のID列をカンマ区切りで保持し、階層構造の効率的な検索を可能にする。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | edit.html | `ruoyi-admin/src/main/resources/templates/system/dept/edit.html` | 画面構成、th:field による既存値バインディング |

**主要処理フロー**:
1. **行8-9**: deptId, parentIdをhiddenフィールドで保持
2. **行65-102**: jQuery Validateによるバリデーション（deptIdも含めた一意性チェック）
3. **行111-125**: selectDeptTree関数でexcludeIdを渡して配下除外

#### Step 3: コントローラー層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SysDeptController.java | `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java` | edit, editSaveメソッド |

**主要処理フロー**:
- **行89-101**: edit()メソッド - データスコープチェック、ルート部門処理
- **行106-128**: editSave()メソッド - 各種チェックと更新処理

#### Step 4: サービス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SysDeptServiceImpl.java | `ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java` | updateDept, updateDeptChildrenメソッド |

**主要処理フロー**:
- **行211-232**: updateDept()メソッド - ancestors再構築、配下更新、祖先状態更新
- **行253-264**: updateDeptChildren()メソッド - 配下部門のancestors一括更新

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

```
edit.html（フォーム送信）
    │
    └─ SysDeptController.editSave() [行106-128]
           │
           ├─ deptService.checkDeptDataScope() [行113]
           ├─ deptService.checkDeptNameUnique() [行114]
           ├─ 自己参照チェック [行118]
           ├─ 子部門状態チェック [行122]
           │
           └─ deptService.updateDept() [行127]
                  └─ SysDeptServiceImpl.updateDept() [行211-232]
                         ├─ ancestors再構築 [行219-222]
                         ├─ updateDeptChildren() [行222]
                         ├─ deptMapper.updateDept() [行224]
                         └─ updateParentDeptStatusNormal() [行229]
```

### データフロー図

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

編集フォームデータ ──▶ SysDeptController.editSave()
                              │
                              ├─▶ データスコープチェック
                              ├─▶ 名称一意性チェック
                              ├─▶ 循環参照チェック
                              ├─▶ 子部門状態チェック
                              │
                              └─▶ updateDept()
                                      │
                                      ├─▶ ancestors再構築
                                      ├─▶ sys_dept UPDATE（本レコード）
                                      ├─▶ sys_dept UPDATE（配下ancestors）
                                      └─▶ sys_dept UPDATE（祖先status） ──▶ AjaxResult
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| edit.html | `ruoyi-admin/src/main/resources/templates/system/dept/edit.html` | テンプレート | 画面表示 |
| tree.html | `ruoyi-admin/src/main/resources/templates/system/dept/tree.html` | テンプレート | 部門ツリー選択 |
| SysDeptController.java | `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java` | コントローラー | リクエスト処理 |
| SysDeptServiceImpl.java | `ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java` | サービス | ビジネスロジック |
| SysDeptMapper.xml | `ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml` | 設定 | SQLマッピング |
| SysDept.java | `ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java` | エンティティ | データモデル |
