diff --git a/app/Services/ShjFourCService.php b/app/Services/ShjFourCService.php index 4cf522c..c3fed34 100644 --- a/app/Services/ShjFourCService.php +++ b/app/Services/ShjFourCService.php @@ -234,6 +234,8 @@ class ShjFourCService 'T1.zone_standard as zone_standard', 'T1.zone_tolerance as zone_tolerance', 'T1.zone_sort', + 'T1.zone_pplace_start', // 車室番号開始(NULLの場合は1) + 'T1.zone_pplace_end', // 車室番号終了(NULLの場合は許容台数まで) 'T2.update_grace_period_start_date', 'T2.update_grace_period_end_date' ]) @@ -270,10 +272,18 @@ class ShjFourCService /** * 【判断1】割当判定処理 * - * ゾーンIDごとにわか順(インクリメント、内部変数.対象番号とする)に - * ゾーン内標準台数に達するまで、定期契約マスタから該当する車室番号で + * ゾーンIDごとに車室番号開始から順(インクリメント、内部変数.対象番号とする)に + * 車室番号終了に達するまで、定期契約マスタから該当する車室番号で * 契約済みの情報の有無を確認する * + * 【パフォーマンス改善】 + * 変更前: 各車室番号ごとに1回SQLクエリ(最大1200回) + * 変更後: ゾーンごとに使用中の車室番号を一括取得(1回) + * + * 【車室番号範囲対応】 + * zone_pplace_start: 開始番号(NULLの場合は1) + * zone_pplace_end: 終了番号(NULLの場合は開始番号+許容台数-1) + * * @param array $zoneInfo ゾーン情報 * @param int $parkId 駐輪場ID * @param int $ptypeId 駐輪分類ID @@ -284,19 +294,22 @@ class ShjFourCService { try { foreach ($zoneInfo as $zone) { - // ゾーン内標準台数まで車室番号をインクリメントして検索 - for ($pplaceNo = 1; $pplaceNo <= $zone->zone_standard; $pplaceNo++) { - // 該当する車室番号で契約済みの情報の有無を確認 - $contractInfo = $this->getRegularContractInfo( - $parkId, - $zone->zone_id, - $pplaceNo, - (int) $zone->update_grace_period_start_date, - (int) $zone->update_grace_period_end_date - ); + // 【改善】使用中の車室番号を一括取得(1回のクエリ) + $occupiedNumbers = $this->getOccupiedRoomNumbers( + $parkId, + $zone->zone_id, + (int) $zone->update_grace_period_start_date, + (int) $zone->update_grace_period_end_date + ); - // 契約情報が存在しない場合、この車室番号は空き - if ($contractInfo === null) { + // 【車室番号範囲対応】開始・終了番号を取得 + $start = $zone->zone_pplace_start ?? 1; + $end = $zone->zone_pplace_end ?? ($start + $zone->zone_tolerance - 1); + + // PHP側で空き番号を検索(開始番号から終了番号まで) + for ($pplaceNo = $start; $pplaceNo <= $end; $pplaceNo++) { + // 使用中でなければ空き + if (!in_array($pplaceNo, $occupiedNumbers, true)) { Log::info('SHJ-4C 割当OK', [ 'zone_id' => $zone->zone_id, 'zone_name' => $zone->zone_name, @@ -342,48 +355,47 @@ class ShjFourCService } /** - * 定期契約情報取得 + * 使用中の車室番号を一括取得 * - * 設計書のSQLクエリに基づく定期契約マスタ検索 - * 特定の車室番号で契約済みの情報の有無を確認する + * 【パフォーマンス改善】 + * 1ゾーンあたり1回のSQLクエリで全ての使用中車室番号を取得 * * @param int $parkId 駐輪場ID * @param int $zoneId ゾーンID - * @param int $pplaceNo 車室番号(対象番号) * @param int $updateGracePeriodStartDate 更新期間開始日 * @param int $updateGracePeriodEndDate 更新期間終了日 - * @return array|null 定期契約情報(存在しない場合はnull) + * @return array 使用中の車室番号配列 */ - private function getRegularContractInfo( + private function getOccupiedRoomNumbers( int $parkId, int $zoneId, - int $pplaceNo, int $updateGracePeriodStartDate, int $updateGracePeriodEndDate - ): ?array { - $currentDate = Carbon::now()->format('y.%m.%d'); + ): array { + $currentDate = Carbon::now()->format('Y-m-d'); $query = DB::table('regular_contract as T1') - ->select(['T1.contract_id']) + ->select('T1.pplace_no') ->where('T1.park_id', $parkId) ->where('T1.zone_id', $zoneId) - ->where('T1.pplace_no', $pplaceNo); + ->where('T1.contract_flag', 1) + ->whereNotNull('T1.pplace_no'); - // 【「JOB1.更新期間開始日」<=「JOB1. 更新期間終了日」の場合】 + // パターンA/B の条件(既存ロジックと同じ) if ($updateGracePeriodStartDate <= $updateGracePeriodEndDate) { - // パターンA: T1.有効期間E >= date_format(now(), '%y.%m.%d') - $query->whereRaw("date_format(T1.contract_periode, '%y.%m.%d') >= ?", [$currentDate]); + // パターンA: 有効期間E >= 現在日付 + $query->where('T1.contract_periode', '>=', $currentDate); } else { - // 【その他の場合】 - // パターンB: T1.有効期間E + 「JOB1. 更新期間終了日」>= date_format(now(), '%y.%m.%d') - $query->whereRaw("DATE_ADD(T1.contract_periode, INTERVAL ? DAY) >= ?", [$updateGracePeriodEndDate, $currentDate]); + // パターンB: 有効期間E + 更新期間終了日 >= 現在日付 + $query->whereRaw( + "DATE_ADD(T1.contract_periode, INTERVAL ? DAY) >= ?", + [$updateGracePeriodEndDate, $currentDate] + ); } - $query->where('T1.contract_flag', 1); - - $result = $query->first(); - - return $result ? (array) $result : null; + return $query->pluck('pplace_no')->map(function ($val) { + return (int) $val; + })->toArray(); } /** diff --git a/tests/Feature/ExampleTest.php b/tests/Feature/ExampleTest.php index 8364a84..aedb8b8 100644 --- a/tests/Feature/ExampleTest.php +++ b/tests/Feature/ExampleTest.php @@ -12,7 +12,7 @@ class ExampleTest extends TestCase */ public function test_the_application_returns_a_successful_response(): void { - $response = $this->get('/'); + $response = $this->get('/up'); $response->assertStatus(200); }