# 画面設計書 10-ユーザー新規登録

## 概要

本ドキュメントは、RuoYi後台管理システムにおける「ユーザー新規登録」の設計仕様を定義する。

### 本画面の処理概要

新規ユーザーアカウントを登録するためのフォーム画面。タブ形式で開かれ、ユーザーの基本情報、所属部門、ロール、岗位（ポスト）などを入力して登録する。

**業務上の目的・背景**：システム管理者がユーザーアカウントを作成するための機能。ユーザー名、ログインアカウント、パスワード、所属部門、権限（ロール）、岗位などを一括で設定できる。入力値の重複チェック（ログイン名、メール、電話番号）をリアルタイムで行い、データの整合性を確保する。

**画面へのアクセス方法**：ユーザー管理一覧画面の「新規」ボタンをクリックすると、新しいタブとして開かれる。

**主要な操作・処理内容**：
1. 基本情報（ユーザー名称、ログイン名、パスワード）の入力
2. 所属部門の選択（ツリーダイアログ）
3. 連絡先（手機番号、メール）の入力
4. 性別、状態の選択
5. 岗位の選択（Select2マルチセレクト）
6. ロールの選択（チェックボックス）
7. 備考の入力
8. 保存または閉じる

**画面遷移**：
- 遷移元：ユーザー管理一覧画面
- 遷移先：保存後はユーザー管理一覧画面に戻る

**権限による表示制御**：`system:user:add` 権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | ユーザー管理 | 主機能 | ユーザー新規登録処理 |
| 4 | 部門管理 | 補助機能 | 部門選択ダイアログ |

## 画面種別

登録

## URL/ルーティング

- GET `/system/user/add` - ユーザー新規登録画面の表示
- POST `/system/user/add` - ユーザー新規登録の保存
- POST `/system/user/checkLoginNameUnique` - ログイン名重複チェック
- POST `/system/user/checkPhoneUnique` - 電話番号重複チェック
- POST `/system/user/checkEmailUnique` - メール重複チェック
- GET `/system/user/selectDeptTree/{deptId}` - 部門選択ツリーダイアログ

## 入出力項目

### 入力項目

| 項目名 | 物理名 | 型 | 必須 | 入出力 | 説明 |
|--------|--------|-----|------|--------|------|
| 部門ID | deptId | Long | - | 入力 | 隠しフィールド |
| ユーザー名称 | userName | String | ○ | 入力 | 表示名、最大30文字 |
| 部門名称 | deptName | String | - | 入力 | ツリー選択で設定 |
| 手機番号 | phonenumber | String | - | 入力 | 最大11桁、重複チェックあり |
| メール | email | String | - | 入力 | 最大50文字、形式・重複チェックあり |
| ログインアカウント | loginName | String | ○ | 入力 | 2-20文字、重複チェックあり |
| パスワード | password | String | ○ | 入力 | 5-20文字、初期値は設定から取得 |
| 性別 | sex | String | - | 入力 | 辞書「sys_user_sex」から選択 |
| 状態 | status | String | - | 入力 | トグルスイッチ、0:正常/1:停止 |
| 岗位 | postIds | String | - | 入力 | マルチセレクト |
| ロール | roleIds | String | - | 入力 | チェックボックス |
| 備考 | remark | String | - | 入力 | 最大500文字 |

## 表示項目

### フォームセクション

| セクション | 項目 |
|-----------|------|
| 基本信息 | ユーザー名称、部門、手機番号、メール、ログインアカウント、パスワード、性別、状態 |
| 岗位・ロール | 岗位（マルチセレクト）、ロール（チェックボックス） |
| 其他信息 | 備考 |

### ボタン

| ボタン名 | 機能 |
|---------|------|
| 保存 | フォーム内容を保存 |
| 閉じる | タブを閉じる |

## イベント仕様

### 1-保存ボタン押下

1. フォームバリデーション実行
2. パスワードポリシーチェック（chrtype設定に基づく）
3. フォームデータをシリアライズ
4. 状態値（チェックボックス→0/1変換）を追加
5. 選択されたロールID、岗位IDを追加
6. AjaxでPOST `/system/user/add` にリクエスト送信
7. 成功時、タブを閉じてユーザー管理一覧を更新

### 2-閉じるボタン押下

1. 現在のタブを閉じる

### 3-部門選択クリック

1. `selectDeptTree()` 関数を呼び出し
2. `/system/user/selectDeptTree/{deptId}` をモーダルで開く
3. ツリーから部門を選択
4. 「確認」で部門ID・部門名をフォームにセット
5. 「清除」で部門情報をクリア

### 4-ログイン名入力（リアルタイムチェック）

1. Ajax remote バリデーションで重複チェック
2. 重複時は「用户已经存在」メッセージを表示

### 5-メール入力（リアルタイムチェック）

1. 形式チェック（emailルール）
2. Ajax remote バリデーションで重複チェック
3. 重複時は「Email已经存在」メッセージを表示

### 6-電話番号入力（リアルタイムチェック）

1. isPhoneルールでフォーマットチェック
2. Ajax remote バリデーションで重複チェック
3. 重複時は「手机号码已经存在」メッセージを表示

### 7-パスワード表示切替

1. 鍵アイコンをマウスダウンでtype="text"に変更
2. マウスアップでtype="password"に戻す

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存 | sys_user | INSERT | ユーザー情報登録 |
| 保存 | sys_user_post | INSERT | ユーザー・岗位関連登録 |
| 保存 | sys_user_role | INSERT | ユーザー・ロール関連登録 |
| 重複チェック | sys_user | SELECT | ログイン名/メール/電話番号の一意性確認 |

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

#### sys_user（登録時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | user_id | 自動採番 | 主キー |
| INSERT | dept_id | 入力値 | 部門ID |
| INSERT | login_name | 入力値 | ログインアカウント |
| INSERT | user_name | 入力値 | ユーザー名称 |
| INSERT | email | 入力値 | メール |
| INSERT | phonenumber | 入力値 | 手機番号 |
| INSERT | sex | 入力値 | 性別 |
| INSERT | password | 暗号化された値 | MD5(loginName+password+salt) |
| INSERT | salt | ランダム生成 | パスワードソルト |
| INSERT | status | 入力値(0/1) | 状態 |
| INSERT | remark | 入力値 | 備考 |
| INSERT | create_by | ログインユーザー名 | - |
| INSERT | create_time | 現在日時 | - |
| INSERT | pwd_update_date | 現在日時 | パスワード更新日時 |

#### sys_user_post（登録時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | user_id | 新規ユーザーID | - |
| INSERT | post_id | 選択された岗位ID | 複数行挿入 |

#### sys_user_role（登録時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | user_id | 新規ユーザーID | - |
| INSERT | role_id | 選択されたロールID | 複数行挿入 |

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|----------|----------|
| バリデーション | 用户已经存在 | ログイン名が重複している場合 |
| バリデーション | Email已经存在 | メールアドレスが重複している場合 |
| バリデーション | 手机号码已经存在 | 電話番号が重複している場合 |
| エラー | 新增用户'xxx'失败，登录账号已存在 | サーバー側での重複チェックエラー |
| エラー | 新增用户'xxx'失败，手机号码已存在 | サーバー側での重複チェックエラー |
| エラー | 新增用户'xxx'失败，邮箱账号已存在 | サーバー側での重複チェックエラー |

## 例外処理

| 例外状況 | 処理内容 |
|----------|----------|
| 権限不足 | 画面アクセス不可またはエラー |
| 入力値バリデーションエラー | 該当フィールドにエラーメッセージを表示 |
| 部門データスコープ外 | エラーを返す |
| ロールデータスコープ外 | エラーを返す |

## 備考

- パスワードの初期値は `sys.user.initPassword` 設定から取得
- パスワードポリシーは `sys.account.chrtype` 設定で制御
- パスワードは MD5(loginName + password + salt) で暗号化
- 管理者ロール（admin）は選択肢から除外される
- 停止状態の岗位・ロールはdisabled表示
- Select2.jsで岗位のマルチセレクトを実装

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SysUser.java | `ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java` | ユーザーエンティティ、roleIds, postIds |
| 1-2 | SysPost.java | `ruoyi-system/src/main/java/com/ruoyi/system/domain/SysPost.java` | 岗位エンティティ |
| 1-3 | SysRole.java | `ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java` | ロールエンティティ |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | SysUserController.java | `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java` | add, addSaveエンドポイント |

**主要処理フロー**:
1. **117-123行目**: GET /add - 登録画面表示、ロール・岗位リストをModelに設定
2. **128-153行目**: POST /add - 登録保存処理、重複チェック・暗号化・挿入

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | add.html | `ruoyi-admin/src/main/resources/templates/system/user/add.html` | フォームレイアウト、バリデーション |

**主要処理フロー**:
- **9-138行目**: フォーム定義（基本情報、岗位・ロール、その他）
- **152-213行目**: jQuery Validateルール（remote重複チェック）
- **215-228行目**: submitHandler() - 保存処理
- **230-256行目**: selectDeptTree() - 部門選択ダイアログ

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

```
add.html
    │
    ├─ submitHandler() - 保存処理
    │      │
    │      ├─ $.validate.form() - バリデーション
    │      │
    │      ├─ checkpwd() - パスワードポリシーチェック
    │      │
    │      └─ $.operate.saveTab() - Ajax POST /system/user/add
    │             │
    │             └─ SysUserController.addSave()
    │                    │
    │                    ├─ deptService.checkDeptDataScope()
    │                    │
    │                    ├─ roleService.checkRoleDataScope()
    │                    │
    │                    ├─ userService.checkLoginNameUnique()
    │                    │
    │                    ├─ passwordService.encryptPassword()
    │                    │
    │                    └─ userService.insertUser()
    │
    └─ selectDeptTree() - 部門選択
           │
           └─ $.modal.openOptions() - モーダル表示
                  │
                  └─ GET /system/user/selectDeptTree/{deptId}
```

### データフロー図

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

フォーム入力 ──────▶ add.html JS ──────────▶ Ajax POST /system/user/add
                        │                          │
バリデーション ◀────────┤                          │
  ├─ loginName重複 ◀─── remote チェック            │
  ├─ email重複 ◀─────── remote チェック            │
  └─ phone重複 ◀─────── remote チェック            │
                        │                          │
                        └─▶ SysUserController      └──▶ AjaxResult
                               │
                               ├─▶ checkXxxUnique()
                               │
                               ├─▶ encryptPassword()
                               │
                               └─▶ userService.insertUser()
                                      │
                                      ├─▶ sys_user (INSERT)
                                      ├─▶ sys_user_post (INSERT)
                                      └─▶ sys_user_role (INSERT)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| add.html | `ruoyi-admin/src/main/resources/templates/system/user/add.html` | テンプレート | 新規登録画面 |
| SysUserController.java | `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java` | コントローラー | エンドポイント |
| ISysUserService.java | `ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java` | サービス | ビジネスロジック |
| SysUserServiceImpl.java | `ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java` | サービス実装 | insertUser実装 |
| SysUserMapper.xml | `ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml` | MyBatis | SQL定義 |
| ry-ui.js | `ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js` | JavaScript | $.operate.saveTab等 |
| select2.js | `ruoyi-admin/src/main/resources/static/ajax/libs/select2/select2.js` | JavaScript | マルチセレクト |
