# FrimaPrize (フリプラ) Laravel 12 載せ替えメモ

`tmp/match_8` の Laravel 8/10 系 frima_prize を Laravel 12 用に載せ替えた構成です。

## 追加したファイル

### コントローラー
- `app/Http/Controllers/App/FrimaPrize/HomeController.php`
- `app/Http/Controllers/App/FrimaPrize/SitemapController.php`
- `app/Http/Controllers/App/FrimaPrize/Item/ItemsController.php`

### ミドルウェア
- `app/Http/Middleware/MasterInfoMiddleware.php` … APP_NAME=app_frima_prize のとき FrimaPrize 用 view 共有
- `app/Http/Middleware/App/FrimaPrize/FrimaPrizeMasterMiddleware.php`

### コマンド
- `app/Console/Commands/App/FrimaPrize/CheckMercariItemCommand.php`  
  - 実行: `php artisan frima_prize:check_mercari_item`

### ルート
- プレフィックス: `/frima_prize`
- 例: `/frima_prize/` (ホーム), `/frima_prize/item/list`, `/frima_prize/sitemap.xml`

### ビュー（元コントローラーの view パスに合わせて配置）
| コントローラーで指定している view パス | Blade ファイル |
|----------------------------------------|----------------|
| `app.app_frima_prize.home` | `resources/views/app/app_frima_prize/home.blade.php` |
| `app.app_frima_prize.item.index` | `resources/views/app/app_frima_prize/item/index.blade.php` |
| `app.app_frima_prize.item.list` | `resources/views/app/app_frima_prize/item/list.blade.php` |
| `app.app_frima_prize.item.ranking` | `resources/views/app/app_frima_prize/item/ranking.blade.php` |
| `app.app_frima_prize.item.view` | `resources/views/app/app_frima_prize/item/view.blade.php` |
| `app.app_frima_prize.item.search_histories` | `resources/views/app/app_frima_prize/item/search_histories.blade.php` |
| `element.item.disp_items` | `resources/views/element/item/disp_items.blade.php` |

- レイアウト: `resources/views/layouts/app_frima_prize.blade.php`  
  - `APP_NAME=app_frima_prize` のとき `MasterInfoMiddleware` が `layout_path` を `layouts.app_frima_prize` で共有するため、Blade 側で `@extends($layout_path, [...])` が使えます。  
  - match_8 の **c_layout_1** と同じ構造（`#all_content` → `header` / `#main_content` → `#col_main` / `#footer`）で、`app_frima_prize.css` でヘッダー色・見出しを揃えています。Bootstrap 5 は CDN で読み込み済みです。

### 設定・アセット
- `config/custom/app_frima_prize/config.php`
- `resources/css/app_frima_prize.css`（Vite に登録済み）
- `resources/css/c_layout_1.css`（Vite に登録済み）

### JS / Vue（match_8 からコピー済み）
- **Pinia store**: `resources/js/stores/item/products.js`  
  - API パスは `/frima_prize/item`（`disp_items_json`, `update_items`）に変更済み。
- **Vue コンポーネント**  
  - `resources/js/components/common/item/OutputItems.vue`  
  - `resources/js/components/common/item/ItemCellComponent.vue`  
  - `resources/js/components/app/app_frima_prize/ItemSearchComponent.vue`  
  - `resources/js/components/app/app_frima_prize/VueItemSearchComponent.vue`
- **利用する場合**  
  Vue 3 + Pinia + Vue Router + axios + vue-loading-overlay + jQuery を導入し、エントリ（例: `app_frima_prize.js`）で `#app` に Vue をマウント、ルートで `ItemSearchComponent` を表示する構成にすると、商品検索の Vue 版が動作します。  
  `index.blade.php` の `View::exists('element.app.app_frima_prize.item.router-view')` が true になるように `resources/views/element/app/app_frima_prize/item/router-view.blade.php` を用意し、その中で `#app` と上記エントリを読み込む形にすると、従来の router-view 構成と揃えられます。

## 必要な作業（match_8 から持ってくるもの）

次のモデル・ヘルパー・定数が **match_12 にまだ無い**場合は、`tmp/match_8` からコピーしてください。

- **Models**: `App\Models\Common\News`, `App\Models\User\UserView`, `App\Models\User\UserSearchHistory`, `App\Models\Shop\ImShopItem`
- **Foundation**: `App\Foundation\Helpers\Shop\ShopItemCommon` およびその依存
- **Consts**: `App\Consts\Shop\CONST_SHOP`
- **Jobs**: `App\Jobs\Shop\UpdatePostItemJob`
- **ログ**: `config/logging.php` に `item_error_report` チャンネル（必要なら）
- **環境変数**: `.env` に `APP_NAME=app_frima_prize`（フリプラ専用で動かす場合）、`KINDLE_GET_URL`（Kindle 取得用）、`FRIMA_PRIZE_LOG_SLACK_WEB_URL` など

## マイグレーション

- **`database/migrations/2025_02_21_100000_create_frima_prize_tables.php`** … FrimaPrize 用テーブル一式をまとめたマイグレーション
  - `setting_sites` … サイト設定（app_name, layout_name, catchphrase など）
  - `news` … お知らせ
  - `user_views` … 閲覧履歴（PV 集計用）
  - `user_search_histories` … 検索履歴
  - `im_shop_items` … 商品マスタ

実行済み: `php artisan migrate` で上記テーブルが作成されます。未実行の場合は `php artisan migrate` を実行してください。

### 初期データ（Seeder）

- **`database/seeders/FrimaPrizeSeeder.php`** … フリプラ用の初期データを投入
  - **setting_sites**: `app_name = app_frima_prize`, `site_name = フリプラ`, `layout_name = c_layout_1`, キャッチコピー・meta など
  - **news**: お知らせサンプル 1 件（setting_site_id は上記で作成した ID に紐付け）

実行: `php artisan db:seed --class=FrimaPrizeSeeder`  
`DatabaseSeeder` からも呼ばれるため、`php artisan db:seed` 実行時にも投入されます。既に `app_frima_prize` が存在する場合はスキップします。

## パッケージ

- `spatie/laravel-sitemap` を `composer.json` に追加済み。未インストールなら:
  - `composer update`

## 従来の URL との違い

- 旧: `/`, `/item`, `/item/list` など（APP_NAME でアプリ切り替え）
- 新: `/frima_prize/`, `/frima_prize/item`, `/frima_prize/item/list` など（プレフィックスで共存）

同じドメインでフリプラだけを公開する場合は、ルートを `frima_prize` なし（`/`, `/item` など）に変更し、`APP_NAME=app_frima_prize` で運用できます。

---

## Blade ファイルのコピー

**注意**: `tmp/match_8` には `resources/views` が含まれていません。元の Laravel 8 の frima_prize プロジェクト（本番や別クローン）から Blade をコピーしてください。

### コピーするパス（元プロジェクト → match_12）

| 元（Laravel 8 等） | コピー先（match_12） |
|-------------------|----------------------|
| `resources/views/app/app_frima_prize/`（フォルダごと） | `resources/views/app/app_frima_prize/` |
| `resources/views/layouts/app_frima_prize.blade.php` | `resources/views/layouts/app_frima_prize.blade.php` |
| `resources/views/element/item/disp_items.blade.php` | `resources/views/element/item/disp_items.blade.php` |

### コピー用スクリプト（PowerShell）

元プロジェクトのルートを `SOURCE` に指定して実行します。

```powershell
.\scripts\copy_frima_prize_blades.ps1 -Source "C:\path\to\laravel8_frima_prize"
```

例: 元プロジェクトが `D:\frima_prize2023` の場合

```powershell
.\scripts\copy_frima_prize_blades.ps1 -Source "D:\frima_prize2023"
```

### コピー後の修正

Laravel 12 側ではルート名に `frima_prize.` プレフィックスを付けています。コピーした Blade 内の `route()` や `url()` を必要に応じて書き換えてください。

### resources コピー後の確認（実施済み）

- **ルート・レイアウト**: 全 app_frima_prize ビューで `route('frima_prize.*')` および `@extends($layout_path ?? 'layouts.app_frima_prize', ...)` を使用していることを確認済み。
- **element スタブ**: `@include` で参照される以下のビューを match_12 に追加済み。  
  - `element/common/paging/disp_page_count_container.blade.php`（ページネーション）  
  - `element/common/form/input/input_keyword_search.blade.php`（キーワード入力）  
  - `element/common/container/item/item_row_3.blade.php`（商品1行表示）
- **商品詳細の soldout 画像**: `item/view.blade.php` では `asset('images/common/shop/soldout.png')` を参照。必要なら match_8 の `public/images/common/shop/soldout.png`（または `public/img/common/icon/soldout.png`）を match_12 の `public/images/common/shop/` にコピーしてください。
- **parts/common**: match_8 の `app_frima_prize/parts/common/sidebar.blade.php` 等はレイアウトに未組み込み。利用する場合は `url('/item')` を `route('frima_prize.item.index')` に置き換えてからコピーすること。

| 旧（例） | 新（match_12） |
|----------|----------------|
| `url('/')` / `route('home')` | `route('frima_prize.home')` |
| `url('item')` | `route('frima_prize.item.index')` |
| `url('item/list')` | `route('frima_prize.item.list')` |
| `url('item/ranking')` | `route('frima_prize.item.ranking')` |
| `url('item/view/'.$id)` | `route('frima_prize.item.view', ['id' => $id])` |
| `url('item/search_histories')` | `route('frima_prize.item.search_histories')` |
| `url('sitemap.xml')` | `route('frima_prize.sitemap')` |
