# 03 処理の流れ（入力 → 画像処理 → 保存 → 表示）

クライアント（加盟店）がマークシート CSV と肌画像 ZIP をアップロードしてから、診断結果 PDF を出力するまでの流れを記す。

---

## 1. 全体シーケンス（概要）

```
[利用者]
   │ ログイン (/client/login/)
   ▼
[Web:PHP]
   │ ZIP 受信 (/client/main/zip_upload.php)
   ▼
[ZIP 展開] --> uploaded_zip/{client}_{yyyymmddHHMMSS}_{us}/
   │
   │ JPG をトリミング (ImageMagick convert)
   ▼
[画像処理エンジン] SkinDiagnosisSystem2.exe (Wine + xvfb)
   │ 解析値（7 値）を標準出力に返す
   ▼
[CSV 解析＋診断ロジック] lib/promolib/*.php
   │ 年齢・水分量・皮脂量などを決定
   ▼
[MySQL] c_{client} DB に登録
   │
   │ 利用者が「PDF 作成」を押下
   ▼
[PDF 生成] /client/main/exec_make_pdf.php → files/pdf_result/client_{id}_file_{n}/
   ▼
[表示／ダウンロード] /client/main/pdf_download.php / result_detail.php
```

---

## 2. 各ステップ詳細

### 2.1 入力（アップロード）

- エントリポイント:
    - 標準・クレシエール系（ID=10, 11）: `/client/main/zip_upload.php`
    - Panasonic 系（ID=4, 21）: `/client/main/zip_upload_panasonic.php`
    - Panasonic PB 系（ID=25）: 確認要（zip_upload_panasonic.php が担う可能性あり）

**クレシエール系（ID=10, 11）について:**
クレシエール系は通常の `zip_upload.php` を使用する。ただし、`zip_upload.php` 内では `$client_id == CRECHER_ID`（定数値 `11`）の条件分岐が存在し、ID=11（crecher）に固有の処理が含まれる。ID=10（crecher2）は CRECHER_ID には該当しないため、標準処理となる。

- 受付ファイル: `.zip`
- ZIP 内の構成:
    - マークシート CSV（1 本）
    - 被写体ごとの角質チェッカー JPG（複数可）
- 同名ファイルや CSV / JPG 以外の拡張子が混ざっている場合はエラー終了する。

### 2.2 展開と前処理

`zip_upload.php` 内で以下のディレクトリを作成する。

```
files/uploaded_zip/{clientId}_{datetime}_{us}/
  ├─ ZipExtract/      … ZIP 一時展開
  ├─ ZipFiles/        … CSV/JPG を集約
  └─ KCheckerIng/
       ├─ Original/   … 元画像（600x600 切り出し）
       ├─ Crop1/      … 解析用 300x300 JPG
       ├─ Crop2/      … 解析エンジン出力の BMP
       └─ Crop3/      … BMP を JPG 化したもの
```

前処理で以下のコマンドを実行。

```bash
# 1) 大枠を 600x600 で切り出し
convert -crop 600x600+3960+1035 <src.jpg> -quality 100 -type truecolor <Original/...>

# 2) 中央 300x300 で解析用に切り出し
convert -gravity center -crop 300x300+0+0 <Original/...> -quality 100 -type truecolor <Crop1/...>
```

### 2.3 画像処理（解析エンジン起動）

1 枚ずつ以下のコマンドで解析エンジンを呼び出す。

```bash
WINEPREFIX=/home/skin/.wine-skindiagnosis \
  xvfb-run -a wine \
  /home/skin/asp.hada-check.com/bin/SkinDiagnosisSystem/SkinDiagnosisSystem2.exe \
  <Crop1/xxx.jpg> <Crop2/xxx.bmp>
```

- 標準出力に 7 つの数値（カンマ区切り）が返る。
- 二値化 BMP は `Crop2/` に保存される。
- 結果は PHP 側で `preg_split` により 7 値に分解し、連想配列に格納される。

引数・戻り値の詳細は [04_画像処理連携仕様.md](./04_画像処理連携仕様.md) 参照。

### 2.4 CSV 読込と診断判定

- ZIP 同梱の CSV（Shift-JIS）を 1 行ずつ UTF-8 に変換。
- 標準 CSV は 38 カラム（`MS_CSV_COLUMNS`）、Panasonic 系は 46 カラム（`MS_CSV_PANASONIC_COLUMNS`）。
- 1 行目がカラム名、2〜3 行目は捨て行、4 行目以降がデータ行。
- データ行と解析結果（7 値）を突合し、以下の判定を行う。

| ファイル | 判定内容 |
| --- | --- |
| `lib/promolib/skin_diagnosis.php` | 角質チェッカー結果・水分レベル・肌タイプ判定 |
| `lib/promolib/moisture_capacity.php` | 水分量 |
| `lib/promolib/sebum_capacity.php` | 皮脂量 |
| `lib/promolib/skin_age.php` | 肌年齢 |
| `lib/promolib/skin_totality.php` | 総合判定 |
| `lib/promolib/skin_danger.php` | 肌リスク |
| `lib/promolib/comment.php` | コメント（定型文）選択 |
| `lib/promolib/agemember.php` | 年齢別判定 |

**CSV カラムと各データの対応（標準・38 カラム）:**

CSV の主要カラムは `lib/column_list.php` に定義されている。データ行の各列は以下のように `zip_upload.php` で読み取られる。

| 読み取り内容 | CSV 列（0-indexed の例） | 用途 |
| --- | --- | --- |
| 生年月日（年月日） | 第9〜12列（4文字） | 年齢算出 |
| 問診回答（ans1〜20） | 第13列以降（クライアントにより異なる） | 診断ロジックの入力 |
| 角質チェッカースコア1〜7 | 画像解析エンジンの出力 | `k_checker_score1` 〜 `k_checker_score7` として保存 |

**クライアント別の差異:**

| 項目 | 標準（crecher 等） | Panasonic 系 |
| --- | --- | --- |
| 入口ファイル | `zip_upload.php` | `zip_upload_panasonic.php` |
| CSV カラム数 | 38 | 46（PANASONICPB は 46、PANASONICSBSC は 38） |
| 診断ロジック | 標準 `lib/promolib/*.php` | 同左（一部条件分岐あり） |
| PDF 生成 | `exec_make_pdf.php` | `exec_make_pdf_panasonic.php` |
| CSV ダウンロード | `csv_download.php` | `csv_download_panasonic.php` |

### 2.5 保存（DB）

- 診断結果は `c_{クライアント名}` DB に保存される。

**テーブルと保存内容:**

| テーブル | 保存内容 |
| --- | --- |
| `t_inported_file` | ZIP ファイル単位の管理（`file_id`、ファイル名、PDF生成済みフラグ） |
| `t_user` | 被験者ユーザー情報（`user_id`） |
| `t_result` | 診断結果本体（`file_id`・`user_id` で紐づく）。問診回答（`ans1`〜`ans20`）・画像解析結果7値（`k_checker_score1`〜`k_checker_score7`）・肌タイプ・各種判定値・画像パス（`k_checker_img_path`）をすべて保存 |

PDF 出力に必要な情報（解析結果・問診回答・コメント ID）はすべて `t_result` に集約される。`t_inported_file.file_id` ← → `t_result.file_id` で紐づく。

**書込み処理のファイル:**

- 標準・クレシエール系（ID=10, 11）: `lib/class/client/csv.php`（`InsertZipData` メソッド）
- Panasonic 系（ID=4）: `lib/class/client/csv_panasonic.php`
- Panasonic SBSC 系（ID=21）: `lib/class/client/csv_panasonicsbsc.php`
- Panasonic PB 系（ID=25）: `lib/class/client/csv_panasonicpb.php`

クレシエール系（ID=10, 11）については専用の csv クラスは存在せず、通常の `csv.php` を使用する。ただし `zip_upload.php` 内で `$client_id == CRECHER_ID`（=11）の場合に個別の条件分岐処理がある。

### 2.6 PDF 生成

- 入口: `/client/main/exec_make_pdf.php`（Panasonic 系は `exec_make_pdf_panasonic.php`）
- 実装: `lib/class/client/show_pdf.php`（または Panasonic 系は `show_pdf_panasonic.php`）＋ `lib/fpdf/mbfpdf.php`（MB 対応版 FPDF）
- 参照する DB テーブル: `t_result`（診断結果）、`t_inported_file`（ファイル管理）
- 参照する画像フォルダ: `user/{クライアント名}/images/pdf/`（クライアント別 PDF 用画像）
- 参照するテンプレート・設定: `lib/class/client/show_pdf.php` に PDF レイアウトを定義

**出力先と紐づけ:**
- 出力先: `files/pdf_result/client_{id}_file_{file_id}/result_{result_id}.pdf`
- `t_result.result_id` と `t_inported_file.file_id` の組み合わせでファイルパスを特定
- `t_inported_file.pdf_download_flg` が PDF 生成完了を示すフラグ

**`files/pdf_result_temp/` について:**
`lib/config.php` に `FILE_EXPORT_TEMP_DIR` として定数定義されているが、現行コードでは参照するファイルが存在せず、ディレクトリ自体も未作成。現行運用では PDF は直接 `files/pdf_result/` へ生成される。バックアップ対象外・削除不要（存在しない）。

### 2.7 表示・ダウンロード

**クライアント向け画面（標準）:**

| 画面 | PHP | 参照する DB・ファイル |
| --- | --- | --- |
| 診断結果一覧 | `/client/main/result_list.php` | `t_inported_file`、`t_result` |
| 診断結果詳細 | `/client/main/result_detail.php` | `t_result`、`m_skin_type` 等マスタ |
| 描画プレビュー | `/client/main/result_drawing.php` | `t_result`、`KCheckerIng/Crop3/` の JPG 画像 |
| PDF ダウンロード | `/client/main/pdf_download.php` | `files/pdf_result/` 配下の PDF ファイル |
| CSV ダウンロード | `/client/main/csv_download.php` | `t_result`、`t_user` |

**Panasonic 系の別画面:**

| 画面 | PHP |
| --- | --- |
| 診断結果一覧 | `result_list_panasonic.php` |
| 診断結果詳細 | `result_detail_panasonic.php` |
| PDF ダウンロード | `pdf_download_panasonic.php` |
| CSV ダウンロード | `csv_download_panasonic.php` |

**管理者側 `/admin/`:**

管理者は `/admin/` 以下の各画面からすべてのクライアントを横断的に参照可能。参照するテーブルは `admin.t_client`（クライアント一覧）と各クライアント DB（`c_xxx`）の `t_result`、`t_user`。

---

## 3. データの「入口」と「出口」まとめ

### 3.1 標準処理・クレシエール系（ID=10, 11）

| 区分 | 場所 |
| --- | --- |
| 入口（画面） | `/client/main/zip_upload.php` |
| 入口（ファイル） | `files/uploaded_zip/` 配下の作業ディレクトリ |
| 解析エンジン入出力 | `KCheckerIng/Crop1`（入力JPG）→ `KCheckerIng/Crop2`（出力BMP） |
| DB 書込み | `lib/class/client/csv.php`（InsertZipData） |
| PDF 生成 | `exec_make_pdf.php` → `files/pdf_result/client_{id}_file_{n}/` |
| PDF テンプレート画像 | `user/crecher/images/pdf/` または `user/crecher2/images/pdf/` |
| 出口（ファイル） | `files/pdf_result/client_{id}_file_{n}/*.pdf` |
| 出口（画面） | `result_list.php` / `result_detail.php` / `pdf_download.php` |

### 3.2 Panasonic 系（ID=4, 21, 25）

| 区分 | 場所 |
| --- | --- |
| 入口（画面） | `/client/main/zip_upload_panasonic.php` |
| CSV カラム数 | 46（PanasonicSBSC は 38） |
| DB 書込み | `lib/class/client/csv_panasonic.php`（または sbsc/pb 対応版） |
| PDF 生成 | `exec_make_pdf_panasonic.php` |
| PDF テンプレート画像 | `user/panasonic/images/`（または sbsc/pb 対応フォルダー） |
| 出口（画面） | `result_list_panasonic.php` / `result_detail_panasonic.php` / `pdf_download_panasonic.php` |
