# 画面設計書 16-プロフィール画面

## 概要

本ドキュメントは、RuoYi後台管理システムにおけるプロフィール画面の設計仕様を定義するものである。

### 本画面の処理概要

プロフィール画面は、ログインユーザーが自身の個人情報を確認・編集するための画面である。基本情報の表示に加え、「基本資料」タブでの情報編集と「修改密码」タブでのパスワード変更機能を提供する統合的な個人設定画面である。

**業務上の目的・背景**：ユーザーは業務上の変更（電話番号変更、メールアドレス変更など）に応じて自身の情報を更新する必要がある。また、セキュリティの観点から定期的なパスワード変更も推奨される。本画面は、管理者を介さずにユーザー自身がこれらの操作を行える自己サービス機能を提供し、システム運用の効率化とユーザー体験の向上を実現する。

**画面へのアクセス方法**：ヘッダー部分のユーザー名リンクをクリック、または右上のユーザーメニューから「個人中心」を選択すると、メインコンテンツエリアにこの画面が表示される。URLパターンは `/system/user/profile` である。

**主要な操作・処理内容**：
1. 画面左側に個人資料（アバター、ログイン名、電話番号、部門、メール、作成日）を表示
2. 画面右側に「基本資料」「修改密码」のタブ切替UI
3. 「基本資料」タブ：ユーザー名、電話番号、メール、性別の編集と保存
4. 「修改密码」タブ：旧パスワード確認と新パスワード設定
5. アバター画像クリックでアバター変更画面（No.17）を起動

**画面遷移**：
- 遷移元：メインメニュー（ヘッダー部分のユーザーリンク）
- 遷移先：アバター変更画面（No.17）（モーダル形式）

**権限による表示制御**：ログインしているユーザー自身の情報のみ表示・編集可能。他ユーザーの情報にはアクセスできない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 22 | プロファイル管理 | 主機能 | 個人情報の表示処理 |
| 1 | ユーザー管理 | 補助機能 | ロール・役職グループ情報の取得 |

## 画面種別

編集（タブ形式・複合機能画面）

## URL/ルーティング

| メソッド | URL | 説明 |
|---------|-----|------|
| GET | /system/user/profile | プロフィール画面表示 |
| POST | /system/user/profile/update | 個人情報更新 |
| POST | /system/user/profile/resetPwd | パスワード変更 |
| GET | /system/user/profile/checkPassword | 旧パスワード確認（Ajax） |

## 入出力項目

### 基本資料タブ入力項目

| No | 項目名 | 物理名 | 型 | 桁数 | 必須 | 初期値 | バリデーション |
|----|--------|--------|----|----|------|--------|--------------|
| 1 | ユーザー名称 | userName | text | 30 | ○ | 現在のユーザー名 | 必須入力 |
| 2 | 手機号碼 | phonenumber | text | 11 | ○ | 現在の電話番号 | 必須、電話番号形式、重複不可 |
| 3 | 邮箱 | email | text | 50 | ○ | 現在のメール | 必須、メール形式、重複不可 |
| 4 | 性別 | sex | radio | - | - | 現在の性別 | 0:男, 1:女 |

### 修改密码タブ入力項目

| No | 項目名 | 物理名 | 型 | 桁数 | 必須 | 初期値 | バリデーション |
|----|--------|--------|----|----|------|--------|--------------|
| 1 | 旧密碼 | oldPassword | password | - | ○ | 空 | 必須、既存パスワードとの一致確認 |
| 2 | 新密碼 | newPassword | password | 20 | ○ | 空 | 必須、6〜20文字、パスワードポリシー準拠 |
| 3 | 確認密碼 | confirmPassword | password | - | ○ | 空 | 必須、新パスワードと一致 |

### 左側パネル表示項目

| No | 項目名 | 物理名 | 説明 |
|----|--------|--------|------|
| 1 | アバター | avatar | プロフィール画像（クリックで変更画面起動） |
| 2 | 登録名稱 | loginName | ログインID |
| 3 | 手機号碼 | phonenumber | 電話番号 |
| 4 | 所属部門 | dept.deptName / postGroup | 部門名/岗位グループ |
| 5 | 邮箱地址 | email | メールアドレス（16文字で省略表示） |
| 6 | 創建時間 | createTime | アカウント作成日 |

## イベント仕様

### 1-画面初期表示

| 項目 | 内容 |
|------|------|
| トリガー | ヘッダーのユーザーリンクまたは「個人中心」メニュー選択時 |
| 処理内容 | 1. ログインユーザーの情報を取得<br>2. ロールグループ・岗位グループ文字列を取得<br>3. 左側パネルに個人資料を表示<br>4. 右側に「基本資料」タブをアクティブで表示 |
| 呼び出しAPI | GET /system/user/profile |
| 遷移先 | - |

### 2-アバタークリック（avatar()）

| 項目 | 内容 |
|------|------|
| トリガー | アバター画像または「修改头像」リンククリック時 |
| 処理内容 | 1. アバター変更画面をレイヤーポップアップで表示<br>2. 確定ボタンで変更を保存<br>3. 保存後、現在のページをリロード |
| 呼び出しAPI | GET /system/user/profile/avatar |
| 遷移先 | アバター変更画面（No.17）（モーダル形式） |

### 3-基本資料保存ボタン押下（submitUserInfo）

| 項目 | 内容 |
|------|------|
| トリガー | 「基本資料」タブの「保存」ボタン押下時 |
| 処理内容 | 1. フォームバリデーション実行<br>2. 電話番号・メール重複チェック（Ajax）<br>3. バリデーション成功時、フォームデータをPOST送信<br>4. ユーザー情報更新後、セッション情報も更新 |
| 呼び出しAPI | POST /system/user/profile/update |
| 遷移先 | - (モーダル表示で結果通知) |

### 4-パスワード変更保存ボタン押下（submitChangPassword）

| 項目 | 内容 |
|------|------|
| トリガー | 「修改密码」タブの「保存」ボタン押下時 |
| 処理内容 | 1. フォームバリデーション実行<br>2. 旧パスワード確認（Ajax checkPassword）<br>3. 新パスワードの確認入力一致チェック<br>4. パスワードポリシーチェック（checkpwd関数）<br>5. バリデーション成功時、パスワード更新処理実行 |
| 呼び出しAPI | POST /system/user/profile/resetPwd |
| 遷移先 | - (モーダル表示で結果通知) |

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

| 項目 | 内容 |
|------|------|
| トリガー | 各タブの「閉じる」ボタン押下時 |
| 処理内容 | 現在のタブ（iframe）を閉じる |
| 呼び出しAPI | - |
| 遷移先 | - |

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 基本資料保存 | sys_user | UPDATE | ユーザー基本情報の更新 |
| パスワード変更 | sys_user | UPDATE | パスワード関連項目の更新 |

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

#### sys_user（基本資料保存時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | user_name | 入力されたユーザー名称 | - |
| UPDATE | phonenumber | 入力された電話番号 | - |
| UPDATE | email | 入力されたメールアドレス | - |
| UPDATE | sex | 選択された性別コード | 0:男, 1:女 |
| UPDATE | update_time | sysdate() | 更新日時（暗黙） |

#### sys_user（パスワード変更時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | password | 暗号化された新パスワード | encryptPasswordで暗号化 |
| UPDATE | salt | 新規生成されたソルト値 | randomSalt() |
| UPDATE | pwd_update_date | sysdate() | パスワード更新日時 |
| UPDATE | update_time | sysdate() | 更新日時 |

## メッセージ仕様

| No | 種別 | メッセージ | 表示条件 |
|----|------|----------|----------|
| 1 | 成功 | 操作成功 | 基本資料/パスワード更新成功時 |
| 2 | エラー | Email已经存在 | メール重複時 |
| 3 | エラー | 手机号码已经存在 | 電話番号重複時 |
| 4 | エラー | 修改密码失败，旧密码错误 | 旧パスワード不一致時 |
| 5 | エラー | 新密码不能与旧密码相同 | 新旧パスワード同一時 |
| 6 | エラー | 修改密码异常，请联系管理员 | パスワード更新処理エラー時 |
| 7 | バリデーション | 请输入用户名称 | ユーザー名未入力時 |
| 8 | バリデーション | 请输入邮箱 | メール未入力時 |
| 9 | バリデーション | 请输入手机号码 | 電話番号未入力時 |
| 10 | バリデーション | 请输入原密码 | 旧パスワード未入力時 |
| 11 | バリデーション | 原密码错误 | 旧パスワードリモート検証失敗時 |
| 12 | バリデーション | 密码不能小于6个字符 | 新パスワード6文字未満時 |
| 13 | バリデーション | 密码不能大于20个字符 | 新パスワード20文字超過時 |
| 14 | バリデーション | 两次密码输入不一致 | 確認パスワード不一致時 |

## 例外処理

| 例外パターン | 対応処理 |
|------------|---------|
| セッション切れ | ログイン画面にリダイレクト |
| 通信エラー | Ajax通信失敗時、エラーメッセージを表示 |

## 備考

- パスワードポリシーは sys_config の `sys.account.chrtype` で設定
  - 0: 制限なし
  - 1: 数字のみ
  - 2: 英字のみ
  - 3: 英数字必須
  - 4: 英数字+特殊文字必須
- 基本資料タブとパスワード変更タブはBootstrap Tabで切り替え
- アバター変更はlayer.jsでポップアップ表示

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SysUser.java | `ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java` | ユーザーエンティティ全体 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | SysProfileController.java | `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java` | profile(), update(), resetPwd()メソッド |

**主要処理フロー**:
1. **47-58行目**: `profile()` メソッド - 画面表示、ユーザー情報とグループ情報取得
2. **125-149行目**: `update()` メソッド - 基本情報更新処理
3. **76-98行目**: `resetPwd()` メソッド - パスワード変更処理
4. **60-66行目**: `checkPassword()` メソッド - 旧パスワード確認

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SysPasswordService.java | `ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/service/SysPasswordService.java` | matches(), encryptPassword()メソッド |
| 3-2 | ISysUserService.java | `ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java` | updateUserInfo(), resetUserPwd()の定義 |

#### Step 4: 画面テンプレートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | profile.html | `ruoyi-admin/src/main/resources/templates/system/user/profile/profile.html` | 2カラムレイアウト、タブ切替、バリデーション設定 |

**主要処理フロー**:
- **12-45行目**: 左側パネル（個人資料表示）
- **55-58行目**: タブナビゲーション（基本資料/修改密码）
- **61-102行目**: 基本資料フォーム
- **106-142行目**: パスワード変更フォーム
- **155-177行目**: avatar()関数（アバター変更画面起動）
- **179-241行目**: フォームバリデーション設定

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

```
ヘッダー [個人中心]メニュー選択
    │
    └─ SysProfileController.profile()       ← GET /system/user/profile
           ├─ getSysUser()                      ← セッションからユーザー取得
           ├─ userService.selectUserRoleGroup() ← ロールグループ取得
           └─ userService.selectUserPostGroup() ← 岗位グループ取得
                  │
                  └─ profile.html 表示
                         │
                         ├─ [アバタークリック] → avatar()
                         │      └─ layer.open() → avatar.html (モーダル)
                         │
                         ├─ [基本資料保存] → submitUserInfo()
                         │      └─ POST /system/user/profile/update
                         │             └─ SysProfileController.update()
                         │
                         └─ [パスワード変更保存] → submitChangPassword()
                                ├─ GET /profile/checkPassword (旧PW確認)
                                └─ POST /system/user/profile/resetPwd
                                       └─ SysProfileController.resetPwd()
```

### データフロー図

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

--- 基本資料更新 ---
userName, phonenumber,   SysProfileController.update()      sys_user更新
email, sex          ───▶    ├─ checkPhoneUnique()            │
                           ├─ checkEmailUnique()            │
                           └─ updateUserInfo()         ───▶  UPDATE

--- パスワード変更 ---
oldPassword,          SysProfileController.resetPwd()      sys_user更新
newPassword      ───▶    ├─ matches() (旧PW確認)             │
                         ├─ randomSalt()                    │
                         ├─ encryptPassword()               │
                         └─ resetUserPwd()            ───▶  UPDATE
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SysProfileController.java | `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java` | コントローラー | プロフィール関連処理 |
| profile.html | `ruoyi-admin/src/main/resources/templates/system/user/profile/profile.html` | テンプレート | プロフィール画面UI |
| avatar.html | `ruoyi-admin/src/main/resources/templates/system/user/profile/avatar.html` | テンプレート | アバター変更画面（モーダル） |
| SysUser.java | `ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java` | エンティティ | ユーザードメイン |
| SysPasswordService.java | `ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/service/SysPasswordService.java` | サービス | パスワード暗号化・検証 |
| ISysUserService.java | `ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java` | インターフェース | ユーザーサービス定義 |
