# 画面設計書 25-メニュー管理一覧

## 概要

本ドキュメントは、RuoYi後台管理システムにおける「メニュー管理一覧」画面の設計仕様を定義するものである。システムのナビゲーションメニュー構造を管理するための画面で、メニューの一覧表示、追加、編集、削除、並び順変更機能を提供する。

### 本画面の処理概要

この画面では、システムのメニュー構造をツリー形式で一覧表示し、メニューの新規追加、編集、削除、および表示順序の変更を行う。メニューには目録（ディレクトリ）、菜単（メニュー項目）、按鈕（ボタン/権限）の3種類があり、階層構造で管理される。

**業務上の目的・背景**：システムのナビゲーション構造を管理者が自由にカスタマイズできるようにすることで、業務要件に応じた画面構成の変更を可能にする。また、ボタン単位の権限制御により、きめ細かなアクセス制御を実現する。

**画面へのアクセス方法**：システム首頁のサイドメニューから「システム管理」→「菜单管理」をクリックすることで、ページタブとして表示される。

**主要な操作・処理内容**：
1. メニュー一覧のツリー形式表示
2. メニュー名称・状態による検索
3. 新規メニューの追加（子メニュー追加含む）
4. 既存メニューの編集
5. メニューの削除（子メニューなし、未割当の場合のみ）
6. 表示順序の一括保存
7. ツリーの展開/折叠

**画面遷移**：システム首頁から遷移。「新増」「編集」ボタンで各モーダルダイアログを表示。

**権限による表示制御**：`system:menu:view`権限を持つユーザーのみアクセス可能。`system:menu:add`権限がないと「新增」ボタンは非表示。`system:menu:edit`権限がないと「修改」「編集」リンクは非表示。`system:menu:remove`権限がないと「削除」リンクは非表示。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | メニュー管理 | 主機能 | メニュー一覧のツリー表示、検索処理 |

## 画面種別

一覧（ツリーテーブル、ページタブ）

## URL/ルーティング

- 画面表示: `GET /system/menu`
- メニュー一覧取得: `POST /system/menu/list`
- メニュー追加画面: `GET /system/menu/add/{parentId}`
- メニュー編集画面: `GET /system/menu/edit/{menuId}`
- メニュー削除: `GET /system/menu/remove/{menuId}`
- 並び順保存: `POST /system/menu/updateSort`

## 入出力項目

### 検索条件入力項目

| 項目名 | 物理名 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| 菜单名称 | menuName | String | - | 部分一致検索 |
| 菜单状態 | visible | String | - | 0:顕示、1:隠蔽 |

### 出力項目（ツリーテーブル表示）

| 項目名 | 物理名 | 型 | 幅 | 説明 |
|--------|--------|-----|-----|------|
| ラジオボタン | selectItem | - | - | 単一選択用 |
| 菜单名称 | menuName | String | 20% | アイコン付きで表示 |
| 排序 | orderNum | String | 10% | 編集可能な入力欄 |
| 請求地址 | url | String | 15% | ツールチップ表示 |
| 類型 | menuType | String | 10% | 目録/菜単/按鈕（ラベル表示） |
| 可見 | visible | String | 10% | 辞書変換、按鈕は「-」表示 |
| 権限標識 | perms | String | 15% | ツールチップ表示 |
| 操作 | - | - | 20% | 編集/新増/削除リンク |

## 表示項目

| 表示項目 | 説明 | 初期値/条件 |
|----------|------|-------------|
| 菜单名称検索欄 | テキスト入力 | 空 |
| 菜单状態セレクト | ドロップダウン（所有/顕示/隠蔽） | 所有 |
| 搜索ボタン | 検索実行 | - |
| 重置ボタン | 検索条件クリア | - |
| 新增ボタン | メニュー追加 | system:menu:add権限必要 |
| 修改ボタン | メニュー編集 | system:menu:edit権限必要 |
| 保存排序ボタン | 並び順一括保存 | - |
| 展開/折疊ボタン | ツリー展開/折叠切替 | - |
| ツリーテーブル | Bootstrap Tree Table | 初期は折叠状態 |

### メニュー類型の表示

| 値 | 表示ラベル | 色 |
|----|----------|-----|
| M | 目录 | 緑（success） |
| C | 菜单 | 青（primary） |
| F | 按钮 | 黄（warning） |

## イベント仕様

### 1-画面表示

メニュー管理一覧画面をページタブとして表示する。

**処理フロー**：
1. `SysMenuController.menu()`が呼び出される
2. Thymeleafテンプレートを描画
3. JavaScript初期化処理でBootstrap Tree Tableを初期化
4. POST /system/menu/listでメニュー一覧を取得
5. ツリー形式で表示（初期は折叠状態）

### 2-検索実行

検索条件に基づいてメニュー一覧を再取得する。

**処理フロー**：
1. 「搜索」ボタンクリックで`$.treeTable.search()`が呼び出される
2. menuNameとvisibleを検索パラメータとして送信
3. サーバー側でフィルタリング
4. 結果をツリーテーブルに表示

### 3-検索条件リセット

検索条件をクリアして全件表示する。

**処理フロー**：
1. 「重置」ボタンクリックで`$.form.reset()`が呼び出される
2. 検索フォームの入力値をクリア
3. テーブルを再検索

### 4-新規メニュー追加

新規メニュー追加画面をモーダルで表示する。

**処理フロー**：
1. 「新增」ボタンまたは行の「新増」リンクをクリック
2. `$.operate.add(parentId)`が呼び出される
3. GET /system/menu/add/{parentId}でモーダルを表示
4. モーダルで保存後、一覧が更新される

### 5-メニュー編集

メニュー編集画面をモーダルで表示する。

**処理フロー**：
1. 「修改」ボタンまたは行の「編集」リンクをクリック
2. `$.operate.edit(menuId)`が呼び出される
3. GET /system/menu/edit/{menuId}でモーダルを表示
4. モーダルで保存後、一覧が更新される

### 6-メニュー削除

メニューを削除する。

**処理フロー**：
1. 行の「削除」リンクをクリックで`$.operate.remove(menuId)`が呼び出される
2. 確認ダイアログを表示
3. OK押下でGET /system/menu/remove/{menuId}を実行
4. サーバー側でチェック（子メニュー存在確認、ロール割当確認）
5. エラーがあれば警告メッセージを表示
6. 成功時は一覧を更新

### 7-並び順保存

変更した並び順を一括保存する。

**処理フロー**：
1. 各行の排序入力欄で値を変更
2. 「保存排序」ボタンをクリックで`saveSort()`が呼び出される
3. originalOrdersと現在値を比較し、変更分のみ抽出
4. 変更がない場合は「未检测到排序修改」警告を表示
5. 変更がある場合はPOST /system/menu/updateSortで送信
6. 成功時は一覧を更新

### 8-ツリー展開/折叠

ツリーの展開/折叠を切り替える。

**処理フロー**：
1. 「展開/折疊」ボタンクリック
2. expandAllBtnのトグル処理
3. 現在の状態に応じて展開または折叠

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| メニュー削除 | sys_menu | DELETE | メニューレコードを削除 |
| 並び順保存 | sys_menu | UPDATE | 複数メニューのorder_numを更新 |

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

#### sys_menu（削除）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | menu_id = 対象メニューID | 物理削除 |

#### sys_menu（並び順更新）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | order_num | 入力値 | 表示順序 |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|----------|----------|
| 警告 | 存在子菜单,不允许删除 | 子メニューが存在する場合 |
| 警告 | 菜单已分配,不允许删除 | ロールに割り当てられている場合 |
| 警告 | 未检测到排序修改 | 並び順変更なしで保存した場合 |
| 成功 | 操作成功 | 削除・更新成功時 |

## 例外処理

| 例外状況 | 処理内容 |
|----------|----------|
| 子メニュー存在 | 「存在子菜单,不允许删除」警告を表示 |
| ロール割当済み | 「菜单已分配,不允许删除」警告を表示 |
| 通信エラー | エラーメッセージを表示 |
| セッションタイムアウト | ログイン画面へリダイレクト |

## 備考

- メニューの可見状態は辞書（sys_show_hide）から変換される
- 按鈕（F）タイプのメニューは可見列に「-」を表示
- ツリーテーブルはparentIdをキーに親子関係を構築
- 排序入力欄はインライン編集可能
- 権限キャッシュは削除・更新時にクリアされる

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SysMenu.java | `ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java` | メニューエンティティの構造、menuType/visible/targetフィールドを理解する |

**読解のコツ**: menuTypeの値（M:目録、C:菜単、F:按鈕）とvisibleの値（0:顕示、1:隠蔽）を把握することが重要。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | SysMenuController.java | `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java` | menu()、list()、remove()、updateSort()メソッドを理解する |

**主要処理フロー**:
1. **40-45行目**: menu()メソッド - 画面表示処理
2. **47-55行目**: list()メソッド - メニュー一覧取得
3. **60-76行目**: remove()メソッド - メニュー削除処理
4. **150-156行目**: updateSort()メソッド - 並び順一括更新

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ISysMenuService.java | `ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java` | selectMenuList()、deleteMenuById()、updateMenuSort()メソッドの定義 |
| 3-2 | SysMenuServiceImpl.java | `ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java` | 各メソッドの実装詳細 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SysMenuMapper.xml | `ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml` | selectMenuList（88-99行目）、deleteMenuById（117-119行目）、updateMenuSort（191-195行目）のSQL |

#### Step 5: フロントエンド処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | menu.html | `ruoyi-admin/src/main/resources/templates/system/menu/menu.html` | 画面構造とJavaScript処理を理解する |

**主要処理フロー**:
- **60-168行目**: Bootstrap Tree Tableの初期化とカラム定義
- **95-99行目**: 排序のインライン編集設定
- **118-128行目**: menuTypeのラベル表示変換
- **170-187行目**: saveSort関数 - 並び順保存処理

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

```
[画面表示] menu.html
    │
    ├─ SysMenuController.menu()
    │
    ├─ [Ajax] list
    │      └─ SysMenuController.list()
    │             └─ menuService.selectMenuList()
    │                    └─ SysMenuMapper.selectMenuList()
    │
    ├─ [削除] $.operate.remove()
    │      └─ SysMenuController.remove()
    │             ├─ menuService.selectCountMenuByParentId()
    │             ├─ menuService.selectCountRoleMenuByMenuId()
    │             └─ menuService.deleteMenuById()
    │
    └─ [並び順保存] saveSort()
           └─ SysMenuController.updateSort()
                  └─ menuService.updateMenuSort()
                         └─ SysMenuMapper.updateMenuSort()
```

### データフロー図

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

menuName ─────────┐
visible ──────────┼───▶ menuService.selectMenuList() ─────▶ メニュー一覧(JSON)
userId ───────────┘

menuId ───────────────▶ menuService.deleteMenuById() ─────▶ sys_menu (DELETE)

menuIds[] ────────┐
orderNums[] ──────┴───▶ menuService.updateMenuSort() ─────▶ sys_menu (UPDATE order_num)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| menu.html | `ruoyi-admin/src/main/resources/templates/system/menu/menu.html` | テンプレート | メニュー管理一覧画面のHTML/JavaScript |
| SysMenuController.java | `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java` | コントローラー | HTTPリクエストの処理 |
| ISysMenuService.java | `ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java` | インターフェース | メニューサービスの定義 |
| SysMenuServiceImpl.java | `ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java` | サービス実装 | ビジネスロジック |
| SysMenuMapper.java | `ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysMenuMapper.java` | マッパー | データアクセス |
| SysMenuMapper.xml | `ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml` | SQL定義 | SQL文の定義 |
| SysMenu.java | `ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java` | エンティティ | メニューデータモデル |
