# 機能設計書 83-コンタクト一覧

## 概要

本ドキュメントは、QuickerSite CMSにおける「コンタクト一覧」機能について、その設計仕様を詳細に記述したものである。

### 本機能の処理概要

コンタクト一覧機能は、会員（コンタクト）情報を検索・一覧表示する管理機能である。カスタムフィールドによる柔軟な検索条件設定と、検索結果のExcelエクスポート機能を提供する。

**業務上の目的・背景**：会員制サイトの運営において、登録会員の情報を効率的に検索・確認することは必須の機能である。本機能により、管理者は会員のステータス確認、特定条件に合致する会員の抽出、会員情報のエクスポートなどを行うことができる。また、抽出した会員に対する一括メール送信機能への導線も提供する。

**機能の利用シーン**：特定の会員情報を検索する際、会員リストをExcelで出力してオフライン分析を行う際、特定条件の会員に一括メールを送信する際、アクティベーション待ちの会員を確認する際に使用する。

**主要な処理内容**：
1. カスタムフィールドに基づく検索条件フォームの動的生成
2. メールアドレス、ニックネーム、会員ステータスによる検索
3. 日付範囲指定による期間検索
4. 検索結果の一覧表示（ページネーション対応）
5. 検索結果のExcelエクスポート
6. 選択した会員への一括メール送信機能への遷移

**関連システム・外部連携**：一括メール送信機能（No.86）との連携。検索結果をbs_contactSelectionActions.aspに渡して一括操作を実行する。

**権限による制御**：イントラネットコンタクト管理権限（secondAdmin.bIntranetContacts）を持つ管理者のみがアクセス可能である。一括メール送信はsecondAdmin.bIntranetMail権限も必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 52 | 連絡先ホーム | 主画面 | 会員（コンタクト）の検索・一覧表示 |
| 53 | 連絡先編集 | 遷移先画面 | 会員情報編集画面への遷移 |
| 56 | 連絡先ページ | 主画面 | 連絡先一覧ページの表示 |

## 機能種別

検索・一覧表示（Read: 会員情報の検索・取得）/ データエクスポート（Excel出力）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| (カスタムフィールド) | 動的 | No | 定義されたカスタムフィールドの検索値 | フィールドタイプに依存 |
| from{fieldID} | String | No | 日付フィールドの開始日 | 日付形式 |
| untill{fieldID} | String | No | 日付フィールドの終了日 | 日付形式 |
| sEmail | String | No | メールアドレス検索 | 部分一致 |
| sNickname | String | No | ニックネーム検索 | 部分一致 |
| iStatus | Integer | No | 会員ステータス | ステータスリストの値 |
| pageSize | Integer | No | 1ページあたりの表示件数 | 100/200/300/400/500または99999（全件） |
| btnaction | String | Yes | 実行アクション | "search"または"excel" |
| postback | Boolean | Yes | POSTフラグ | true/false |

### 入力データソース

- 画面フォーム入力（検索条件）
- URLパラメータ（ポップアップ表示用のiCPP）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| iId | Integer | 会員ID |
| sEmail | String | メールアドレス |
| sNickname | String | ニックネーム |
| iStatus | Integer | 会員ステータス |
| fields | Dictionary | カスタムフィールド値 |
| dCreatedTS | DateTime | 登録日時 |
| dUpdatedTS | DateTime | 更新日時 |
| dLastLoginTS | DateTime | 最終ログイン日時 |

### 出力先

- 画面表示（検索結果一覧テーブル）
- Excelファイル（エクスポート時）

## 処理フロー

### 処理シーケンス

```
1. 認証・権限チェック
   └─ イントラネットコンタクト管理権限の確認
2. カスタムフィールド定義の取得
   └─ customer.contactFields()で検索フィールドを取得
3. 検索オブジェクトの初期化
   └─ cls_contactSearchインスタンス作成
4. POSTデータの処理
   └─ getRequestValues()で検索条件を取得
5. 検索実行
   └─ resultTableで検索結果を生成
6. 結果表示
   └─ 検索：HTML一覧テーブル / Excel：Excel形式出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{認証チェック}
    B -->|失敗| C[アクセス拒否]
    B -->|成功| D[カスタムフィールド取得]
    D --> E[検索オブジェクト初期化]
    E --> F[リクエスト値取得]
    F --> G{POSTリクエスト?}
    G -->|No| H[検索フォーム表示]
    G -->|Yes| I{アクション判定}
    I -->|search| J[HTML一覧生成]
    J --> K[結果テーブル表示]
    I -->|excel| L[Excel形式生成]
    L --> M[Excelダウンロード]
    K --> N{一括メール権限?}
    N -->|Yes| O[一括メールリンク表示]
    N -->|No| P[終了]
    O --> P
    H --> P
    M --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-83-01 | 検索フィールド表示 | bSearchField=trueのフィールドのみ検索条件に表示 | 検索フォーム生成時 |
| BR-83-02 | 大量データ警告 | 多数の会員がいる場合はページサイズ選択を表示 | customer.hasManyContacts=true |
| BR-83-03 | 一括メール権限 | 一括メールリンクはbIntranetMail権限が必要 | 検索結果表示時 |
| BR-83-04 | 顧客ID絞り込み | 検索は現在のサイト（顧客ID）に限定 | 検索実行時 |

### 計算ロジック

特になし

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| フィールド定義取得 | tblContactField | SELECT | カスタムフィールド定義の取得 |
| 会員検索 | tblContact | SELECT | 検索条件に合致する会員の取得 |
| フィールド値取得 | tblContactValues | SELECT | カスタムフィールドの値取得 |

### テーブル別操作詳細

#### tblContact

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | iCustomerID = cId AND 検索条件 | 動的SQL生成 |
| SELECT | sEmail | LIKE '%検索値%' | 部分一致検索 |
| SELECT | sNickname | LIKE '%検索値%' | 部分一致検索 |
| SELECT | iStatus | = 指定値 | 完全一致 |

#### tblContactValues

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | sValue | iContactID = 会員ID AND iFieldID = フィールドID | JOIN検索 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 検索結果なし | 条件に合致するデータがない | 結果なしメッセージ表示 |

### リトライ仕様

リトライ処理は実装されていない。

## トランザクション仕様

参照のみのため、トランザクション制御は不要。

## パフォーマンス要件

- 大量会員対応：pageSizeによるページネーション実装
- customer.hasManyContactsフラグによる動的ページサイズ選択表示

## セキュリティ考慮事項

- 認証必須：`logon.hasaccess secondAdmin.bIntranetContacts`による権限チェック
- 入力サニタイズ：`quotRep()`関数による出力エスケープ
- CSRF対策：一括メール送信時に確認ダイアログと警告表示
- ID暗号化：`encrypt()`関数による会員IDの暗号化

## 備考

- カスタムフィールドの種類（text, textarea, checkbox, select, date, richtext）によって検索UIが動的に変化する
- 検索結果からポップアップで会員編集画面を開くことができる（colorboxライブラリ使用）

---

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

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

### 推奨読解順序

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

会員（コンタクト）クラスと検索クラスの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | contact.asp | `asp/includes/contact.asp` | cls_contactクラスの定義、プロパティ |
| 1-2 | contactSearch.asp | `asp/includes/contactSearch.asp` | cls_contactSearchクラスの定義 |
| 1-3 | contactField.asp | `asp/includes/contactField.asp` | cls_contactFieldクラスの定義 |

**読解のコツ**: contactオブジェクトのfieldsプロパティはDictionaryオブジェクトで、カスタムフィールドIDをキー、値をバリューとして保持する。

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

管理画面のメインファイルから処理の流れを追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | bs_contactHome.asp | `asp/bs_contactHome.asp` | 画面表示と検索処理のフロー |

**主要処理フロー**:
1. **4行目**: 権限チェック（`secondAdmin.bIntranetContacts`）
2. **5-8行目**: カスタムフィールド定義の取得
3. **9-14行目**: cls_contactSearchインスタンス作成と検索条件設定
4. **20行目**: 検索結果テーブル（resultTable）の取得
5. **23-24行目**: フィールドタイプごとの検索フォーム要素生成
6. **26-27行目**: 検索結果表示とExcelエクスポート分岐

#### Step 3: 会員クラスの詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | contact.asp | `asp/includes/contact.asp` | Pick、Save、delete、fieldsの各処理 |

**主要処理フロー**:
- **2-19行目**: クラス初期化、デフォルト値設定
- **45-79行目**: `Pick`関数 - IDから会員データとフィールド値を取得
- **153-225行目**: `Save`関数 - 会員情報とフィールド値の保存
- **247-271行目**: `delete`関数 - 関連データを含む会員削除

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

```
bs_contactHome.asp（エントリーポイント）
    │
    ├─ begin.asp（共通初期化）
    │
    ├─ bs_security.asp（認証チェック）
    │      └─ logon.hasaccess（権限検証）
    │
    ├─ customer.contactFields()（フィールド定義取得）
    │
    ├─ cls_contactSearch（検索オブジェクト）
    │      ├─ getRequestValues()（検索条件取得）
    │      ├─ resultTable（検索結果生成）
    │      └─ showSelected()（選択リスト生成）
    │
    └─ bs_contactSelectionActions.asp（一括操作画面）
           └─ 一括メール送信機能
```

### データフロー図

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

検索条件フォーム ───▶ cls_contactSearch ───▶ 検索クエリ生成
     │                    │
     │                    ▼
     │             tblContact ───▶ 会員データ
     │                    │
     │                    ▼
     │             tblContactValues ───▶ フィールド値
     │                    │
     ▼                    ▼
btnaction ───────▶ 結果表示分岐
                         │
            ┌────────────┴────────────┐
            ▼                         ▼
       HTML一覧表示              Excel出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| bs_contactHome.asp | `asp/bs_contactHome.asp` | ソース | コンタクト一覧画面のエントリーポイント |
| contact.asp | `asp/includes/contact.asp` | ソース | cls_contactクラス定義 |
| contactSearch.asp | `asp/includes/contactSearch.asp` | ソース | cls_contactSearchクラス定義 |
| contactField.asp | `asp/includes/contactField.asp` | ソース | cls_contactFieldクラス定義 |
| contactStatusList.asp | `asp/includes/contactStatusList.asp` | ソース | 会員ステータスリスト |
| bs_contactEdit.asp | `asp/bs_contactEdit.asp` | ソース | 会員編集画面 |
| bs_contactSelectionActions.asp | `asp/bs_contactSelectionActions.asp` | ソース | 一括操作画面 |
| begin.asp | `asp/begin.asp` | ソース | 共通初期化処理 |
| bs_security.asp | `asp/bs_security.asp` | ソース | 認証・権限チェック |
