|
|
@@ -5,11 +5,14 @@ namespace App\Http\Controllers\Movie;
|
|
|
use Illuminate\Http\Request;
|
|
|
use Illuminate\Http\Client\ConnectionException;
|
|
|
use Illuminate\Support\Facades\Http;
|
|
|
+use Illuminate\Support\Facades\Cache;
|
|
|
use Illuminate\Support\Facades\Validator;
|
|
|
use App\Http\Controllers\Controller;
|
|
|
use App\Http\Traits\CommonTrait;
|
|
|
use App\Http\Traits\PagingTrait;
|
|
|
+use App\Models\DTO\SearchData;
|
|
|
use App\Models\DTO\Movie\CompanyParams;
|
|
|
+use App\Models\Movie\Company;
|
|
|
use Exception;
|
|
|
|
|
|
class CompanyController extends Controller
|
|
|
@@ -18,19 +21,21 @@ class CompanyController extends Controller
|
|
|
use PagingTrait;
|
|
|
|
|
|
private string $host;
|
|
|
+ private Company $companyModel;
|
|
|
|
|
|
- public function __construct() {
|
|
|
+ public function __construct(Company $companyModel) {
|
|
|
$this->middleware('front');
|
|
|
|
|
|
$this->host = env('MOVIE_API');
|
|
|
+ $this->companyModel = $companyModel;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 영화사 목록
|
|
|
+ * 영화사 목록 (DB 조회)
|
|
|
* @method GET
|
|
|
* @see /movie/company
|
|
|
*/
|
|
|
- public function index(Request $request, CompanyParams $params)
|
|
|
+ public function index(Request $request)
|
|
|
{
|
|
|
$rules = [
|
|
|
'page' => 'nullable|numeric',
|
|
|
@@ -53,51 +58,32 @@ class CompanyController extends Controller
|
|
|
// 검색 유효성 검사
|
|
|
Validator::make($request->all(), $rules, $message, $attributes)->validated();
|
|
|
|
|
|
- $page = max(1, (int)$request->get('page', 1));
|
|
|
- $params->curPage = $page;
|
|
|
- $params->companyNm = $request->get('keyword');
|
|
|
- $params->ceoNm = $request->get('ceo');
|
|
|
+ $params = SearchData::fromRequest($request);
|
|
|
+ $data = $this->companyModel->list($params);
|
|
|
|
|
|
- // 검색 조건 (crawler 장애 시 빈 목록으로 격리)
|
|
|
- $total = 0;
|
|
|
- $list = [];
|
|
|
- try {
|
|
|
- $response = Http::timeout(5)->get($this->host . COMPANY_LIST, $params->toArray());
|
|
|
- } catch (ConnectionException) {
|
|
|
- $response = null;
|
|
|
- }
|
|
|
-
|
|
|
- if ($response && $response->ok()) {
|
|
|
- $data = json_decode($response->body());
|
|
|
- $total = (int)($data->total ?? 0);
|
|
|
- if ($total > 0) {
|
|
|
- $queryString = $request->getQueryString();
|
|
|
- foreach ($data->list as $row) {
|
|
|
- $row->viewURL = route('movie.company.show', base64_encode($row->companyCd));
|
|
|
- if ($queryString) {
|
|
|
- $row->viewURL .= ('?' . $queryString);
|
|
|
- }
|
|
|
- $list[] = $row;
|
|
|
- }
|
|
|
+ // 상세 보기 URL 세팅
|
|
|
+ $queryString = $request->getQueryString();
|
|
|
+ foreach ($data->list as $row) {
|
|
|
+ $row->viewURL = route('movie.company.show', base64_encode($row->companyCd));
|
|
|
+ if ($queryString) {
|
|
|
+ $row->viewURL .= ('?' . $queryString);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- $companies = $this->getPaginator($list, $total, $params->itemPerPage, $page);
|
|
|
-
|
|
|
return view(layout('movie.company.index'), [
|
|
|
'keyword' => $request->get('keyword'),
|
|
|
'ceo' => $request->get('ceo'),
|
|
|
- 'total' => $total,
|
|
|
- 'companies' => $companies
|
|
|
+ 'total' => $data->total,
|
|
|
+ 'companies' => $data->list
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 영화사 상세 보기
|
|
|
+ * 영화사 상세 보기 (DB 우선 + 캐시, 미수집 시 API 폴백)
|
|
|
* @method GET
|
|
|
* @see /movie/company/{company_cd}
|
|
|
*/
|
|
|
- public function show(string $base64, Request $request, CompanyParams $params)
|
|
|
+ public function show(string $base64, Request $request)
|
|
|
{
|
|
|
try {
|
|
|
|
|
|
@@ -116,16 +102,22 @@ class CompanyController extends Controller
|
|
|
$listURL .= ('?' . $queryString);
|
|
|
}
|
|
|
|
|
|
- // 검색 조건
|
|
|
- $params->companyCd = $companyCd;
|
|
|
- $response = Http::timeout(5)->get($this->host . COMPANY_INFO, $params->toArray());
|
|
|
+ // 캐시 → DB → crawler API 폴백 순으로 조회
|
|
|
+ $cacheKey = ('movie:company:' . $companyCd);
|
|
|
+ $info = Cache::get($cacheKey);
|
|
|
|
|
|
- if(!$response->ok()) {
|
|
|
- throw new Exception('요청한 정보가 없습니다.');
|
|
|
- }
|
|
|
+ if (!$info) {
|
|
|
+ $info = $this->companyModel->info($companyCd);
|
|
|
|
|
|
- $data = json_decode($response->body());
|
|
|
- $info = ($data->info ?? null);
|
|
|
+ // DB 미수집이면 crawler API 폴백 (수집은 cron 이 채움)
|
|
|
+ if (!$info) {
|
|
|
+ $info = $this->fetchFromApi($companyCd);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($info && !empty($info->companyCd)) {
|
|
|
+ Cache::put($cacheKey, $info, CACHE_EXPIRE_TIME);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
if(!$info || empty($info->companyCd)) {
|
|
|
throw new Exception('요청한 정보가 없습니다.');
|
|
|
@@ -142,8 +134,29 @@ class CompanyController extends Controller
|
|
|
'listURL' => $listURL
|
|
|
]);
|
|
|
|
|
|
- }catch(Exception $e) {
|
|
|
+ } catch(Exception $e) {
|
|
|
abort($e->getCode() ?: 500, $e->getMessage());
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * DB 미수집 영화사를 crawler API 로 즉석 조회 (폴백)
|
|
|
+ */
|
|
|
+ private function fetchFromApi(string $companyCd): ?object
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ $params = new CompanyParams();
|
|
|
+ $params->companyCd = $companyCd;
|
|
|
+ $response = Http::timeout(5)->get($this->host . COMPANY_INFO, $params->toArray());
|
|
|
+ } catch (ConnectionException) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!$response->ok()) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ $data = json_decode($response->body());
|
|
|
+ return ($data->info ?? null);
|
|
|
+ }
|
|
|
}
|