# 画面設計書 31-部門新規登録

## 概要

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

### 本画面の処理概要

本画面は、組織管理における新規部門を登録するための入力フォーム画面である。システム管理者は本画面を通じて、企業や組織の部門階層構造を構築・拡張することができる。

**業務上の目的・背景**：企業における組織構造の管理は、ユーザー管理やデータ権限管理の基盤となる。新規事業部門の設立、組織再編時の部門追加など、組織変更に伴う部門マスタの登録業務を効率的に行うために本画面が必要である。部門は階層構造を持ち、親部門配下に子部門を追加する形で組織ツリーを構築する。

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

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

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

**権限による表示制御**：`system:dept:add`権限を持つユーザーのみが本画面にアクセス可能。一般管理者の場合、親部門は自身の所属部門に制限される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | 部門管理 | 主機能 | 新規部門情報入力と登録保存処理 |

## 画面種別

登録（モーダルダイアログ形式）

## URL/ルーティング

- 画面表示：`GET /system/dept/add/{parentId}`
- 登録処理：`POST /system/dept/add`
- 部門名一意性チェック：`POST /system/dept/checkDeptNameUnique`

## 入出力項目

| 項目名 | 項目ID | 型 | 必須 | 最大長 | 入力形式 | 備考 |
|--------|--------|-----|------|--------|----------|------|
| 親部門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）がモーダルダイアログとして表示される。ツリー画面で部門を選択すると、選択された部門IDがparentIdに、部門名がtreeNameに設定される。

**処理フロー**：
1. 現在の親部門ID（treeId）が空かチェック
2. 空の場合は警告メッセージ「請先添加用户所属的部门！」を表示
3. 値がある場合、`/system/dept/selectDeptTree/{treeId}/0`を呼び出してツリー画面を開く
4. ツリー画面で選択後、callBack関数でparentIdとtreeNameを更新

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

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

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

**登録処理**：
1. バリデーション成功後、`/system/dept/add`へフォームデータをPOST
2. サーバー側で親部門の状態チェック（停用部門配下には追加不可）
3. ancestors（祖先ID列）を親部門情報から構築
4. sys_deptテーブルにINSERT
5. 成功時：親画面を更新してモーダルを閉じる

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 確定ボタン押下 | sys_dept | INSERT | 新規部門レコードの登録 |

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

#### sys_dept

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | dept_id | 自動採番 | 主キー |
| INSERT | parent_id | 画面入力値（parentId） | 親部門ID |
| INSERT | ancestors | 親部門のancestors + "," + parentId | 祖先ID列 |
| INSERT | dept_name | 画面入力値（deptName） | 部門名称 |
| INSERT | order_num | 画面入力値（orderNum） | 表示順序 |
| INSERT | leader | 画面入力値（leader） | 負責人 |
| INSERT | phone | 画面入力値（phone） | 連絡電話 |
| INSERT | email | 画面入力値（email） | メール |
| INSERT | status | 画面入力値（status） | 部門状態 |
| INSERT | del_flag | '0' | 削除フラグ（未削除） |
| INSERT | create_by | ログインユーザー名 | 作成者 |
| INSERT | create_time | sysdate() | 作成日時 |

## メッセージ仕様

| メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|-------------|---------------|---------------|----------|
| MSG001 | エラー | 部門已經存在 | 部門名重複時 |
| MSG002 | エラー | 新増部門'xxx'失敗，部門名称已存在 | サーバー側重複チェック時 |
| MSG003 | エラー | 部門停用，不允許新増 | 親部門が停用状態の場合 |
| MSG004 | 警告 | 請先添加用户所属的部門！ | 親部門未設定で選択試行時 |
| MSG005 | 成功 | 操作成功 | 登録成功時 |

## 例外処理

| 例外パターン | 発生条件 | 処理内容 |
|-------------|----------|----------|
| 権限不足 | system:dept:add権限なし | 画面アクセス拒否、エラー画面表示 |
| 親部門停用 | 選択した親部門が停用状態 | ServiceExceptionをスロー、エラーメッセージ表示 |
| 通信エラー | Ajaxリクエスト失敗 | エラーメッセージをモーダル表示 |
| セッション切れ | ログインセッション期限切れ | ログイン画面へリダイレクト |

## 備考

- 非管理者ユーザーの場合、親部門は自身の所属部門に制限される（コントローラー行61-64）
- 部門名の一意性は同一親部門内でのみチェックされる
- 状態の選択肢はsys_normal_disable辞書から動的に取得される

---

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

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

### 推奨読解順序

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

まず、プログラム間で受け渡されるデータ構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SysDept.java | `ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java` | 部門エンティティの構造、バリデーションアノテーション（@NotBlank, @Size, @Email等）を確認 |

**読解のコツ**: エンティティクラスのフィールドとバリデーションアノテーションを確認することで、入力項目の制約が理解できる。特にancestors（祖先ID列）フィールドは階層構造管理の要である。

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

処理の起点となるファイル・関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | add.html | `ruoyi-admin/src/main/resources/templates/system/dept/add.html` | 画面構成、入力項目、JavaScript処理を確認 |

**主要処理フロー**:
1. **行8-58**: フォーム定義（form-dept-add）、各入力項目のHTML構造
2. **行64-98**: jQuery Validateによるクライアント側バリデーション設定
3. **行100-104**: submitHandler関数で$.operate.saveを呼び出し
4. **行106-127**: selectDeptTree関数で親部門選択ダイアログを開く

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SysDeptController.java | `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java` | 画面表示・登録処理のエンドポイント |

**主要処理フロー**:
- **行57-67**: add()メソッド - 画面表示、非管理者は自部門のみ選択可能
- **行72-84**: addSave()メソッド - 登録処理、名称一意性チェック、Service呼び出し
- **行153-159**: checkDeptNameUnique()メソッド - Ajax一意性チェック

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ISysDeptService.java | `ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java` | サービスインターフェース定義 |
| 4-2 | SysDeptServiceImpl.java | `ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java` | サービス実装 |

**主要処理フロー**:
- **行192-203**: insertDept()メソッド - 親部門状態チェック、ancestors構築、INSERT実行
- **行297-306**: checkDeptNameUnique()メソッド - 部門名一意性チェックロジック

#### Step 5: データアクセス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | SysDeptMapper.xml | `ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml` | SQLマッピング定義 |

**主要処理フロー**:
- **行69-72**: checkDeptNameUnique - 同一親部門内での名称重複チェックSQL
- **行74-79**: selectDeptById - 部門IDによる検索（親部門情報取得用）
- **行89-115**: insertDept - 部門登録INSERT文

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

```
add.html（フォーム送信）
    │
    ├─ submitHandler() [JavaScript]
    │      └─ $.operate.save()
    │             └─ POST /system/dept/add
    │
    └─ SysDeptController.addSave() [行72-84]
           │
           ├─ deptService.checkDeptNameUnique() [行78]
           │      └─ SysDeptServiceImpl.checkDeptNameUnique() [行297-306]
           │             └─ deptMapper.checkDeptNameUnique() [Mapper]
           │
           └─ deptService.insertDept() [行83]
                  └─ SysDeptServiceImpl.insertDept() [行192-203]
                         ├─ deptMapper.selectDeptById() [行195] - 親部門取得
                         └─ deptMapper.insertDept() [行202] - INSERT実行
```

### データフロー図

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

フォーム入力データ ───────▶ SysDeptController.addSave()
  - parentId                        │
  - deptName                        ├─▶ checkDeptNameUnique()
  - orderNum                        │         │
  - leader                          │         └─▶ sys_dept SELECT
  - phone                           │
  - email                           ├─▶ insertDept()
  - status                          │         │
                                    │         ├─▶ 親部門状態チェック
                                    │         ├─▶ ancestors構築
                                    │         └─▶ sys_dept INSERT ───▶ AjaxResult
                                    │                                    │
                                    └──────────────────────────────────▶ 成功/失敗レスポンス
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| add.html | `ruoyi-admin/src/main/resources/templates/system/dept/add.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` | コントローラー | リクエスト処理 |
| ISysDeptService.java | `ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java` | インターフェース | サービス定義 |
| SysDeptServiceImpl.java | `ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java` | サービス | ビジネスロジック |
| SysDeptMapper.java | `ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java` | マッパー | DAOインターフェース |
| 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` | エンティティ | データモデル |
