From 56aa538b3bef972eac8d9a086e9b61a35fe401b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Tue, 3 Feb 2026 07:40:35 +0900 Subject: [PATCH] =?UTF-8?q?feat:=EB=B0=94=EB=A1=9C=EB=B9=8C=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8/=EC=9A=B4=EC=98=81=20=EC=84=9C=EB=B2=84=20?= =?UTF-8?q?=EC=84=A0=ED=83=9D=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 회원사 관리 페이지에 서버 선택 토글 UI 추가 - 서버 모드 전환 API 추가 (GET/POST /api/admin/barobill/members/server-mode) - BarobillService에서 세션 기반 서버 모드 읽기 지원 - 선택한 서버 설정이 바로빌 API 호출에 적용됨 Co-Authored-By: Claude Opus 4.5 --- .../Barobill/BarobillMemberController.php | 55 +++++++++ app/Services/Barobill/BarobillService.php | 10 +- .../views/barobill/members/index.blade.php | 106 ++++++++++++++++-- routes/api.php | 3 + 4 files changed, 162 insertions(+), 12 deletions(-) diff --git a/app/Http/Controllers/Api/Admin/Barobill/BarobillMemberController.php b/app/Http/Controllers/Api/Admin/Barobill/BarobillMemberController.php index 7afc0caa..58e982c2 100644 --- a/app/Http/Controllers/Api/Admin/Barobill/BarobillMemberController.php +++ b/app/Http/Controllers/Api/Admin/Barobill/BarobillMemberController.php @@ -856,4 +856,59 @@ public function getServiceCodes(): JsonResponse ], ]); } + + /** + * 서버 모드 설정 (테스트/운영 서버 전환) + * + * 세션에 바로빌 서버 모드를 저장합니다. + * BarobillService 생성 시 이 세션 값을 읽어 사용합니다. + */ + public function setServerMode(Request $request): JsonResponse + { + $validated = $request->validate([ + 'mode' => 'required|in:test,production', + ], [ + 'mode.required' => '서버 모드를 선택해주세요.', + 'mode.in' => '서버 모드는 test 또는 production 이어야 합니다.', + ]); + + $mode = $validated['mode']; + session(['barobill_server_mode' => $mode]); + + Log::info('바로빌 서버 모드 변경', [ + 'mode' => $mode, + 'user_id' => auth()->id(), + ]); + + return response()->json([ + 'success' => true, + 'mode' => $mode, + 'message' => ($mode === 'test' ? '테스트' : '운영') . ' 서버로 전환되었습니다.', + ]); + } + + /** + * 서버 모드 조회 + * + * 현재 세션에 저장된 바로빌 서버 모드를 반환합니다. + * 세션 값이 없으면 .env 설정값을 반환합니다. + */ + public function getServerMode(): JsonResponse + { + $sessionMode = session('barobill_server_mode'); + + if ($sessionMode) { + $mode = $sessionMode; + } else { + // .env 설정 기준 (BAROBILL_TEST_MODE) + $isTestMode = config('services.barobill.test_mode', true); + $mode = $isTestMode ? 'test' : 'production'; + } + + return response()->json([ + 'success' => true, + 'mode' => $mode, + 'source' => $sessionMode ? 'session' : 'env', + ]); + } } diff --git a/app/Services/Barobill/BarobillService.php b/app/Services/Barobill/BarobillService.php index f61bc5bf..9b065bf8 100644 --- a/app/Services/Barobill/BarobillService.php +++ b/app/Services/Barobill/BarobillService.php @@ -96,8 +96,14 @@ class BarobillService public function __construct() { - // .env에서 테스트 모드 설정 가져오기 (기본값: true = 테스트 모드) - $this->isTestMode = config('services.barobill.test_mode', true); + // 1. 세션에서 서버 모드 가져오기 (최우선) + $sessionMode = session('barobill_server_mode'); + if ($sessionMode) { + $this->isTestMode = ($sessionMode === 'test'); + } else { + // 2. .env에서 테스트 모드 설정 가져오기 (기본값: true = 테스트 모드) + $this->isTestMode = config('services.barobill.test_mode', true); + } // DB에서 활성화된 설정 가져오기 (우선순위) $dbConfig = $this->loadConfigFromDatabase(); diff --git a/resources/views/barobill/members/index.blade.php b/resources/views/barobill/members/index.blade.php index 23062cf0..dc132333 100644 --- a/resources/views/barobill/members/index.blade.php +++ b/resources/views/barobill/members/index.blade.php @@ -10,16 +10,30 @@

회원사관리

바로빌 연동 회원사를 관리합니다

- +
+ +
+ 서버: + + +
+ +
@@ -621,9 +635,81 @@ function closeBarobillDropdown() { } }); + // 바로빌 서버 모드 관리 + const BarobillServer = { + currentMode: 'test', + + async init() { + try { + const res = await fetch('/api/admin/barobill/members/server-mode', { + headers: { + 'X-CSRF-TOKEN': '{{ csrf_token() }}', + 'Accept': 'application/json' + } + }); + const data = await res.json(); + if (data.success) { + this.currentMode = data.mode; + this.updateUI(); + } + } catch (error) { + console.error('서버 모드 조회 실패:', error); + } + }, + + async setMode(mode) { + if (mode === this.currentMode) return; + + try { + const res = await fetch('/api/admin/barobill/members/server-mode', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRF-TOKEN': '{{ csrf_token() }}', + 'Accept': 'application/json' + }, + body: JSON.stringify({ mode }) + }); + + const data = await res.json(); + + if (data.success) { + this.currentMode = mode; + this.updateUI(); + showToast(data.message, 'success'); + // 목록 새로고침 + htmx.trigger(document.body, 'memberUpdated'); + } else { + showToast(data.message || '서버 모드 변경 실패', 'error'); + } + } catch (error) { + console.error('서버 모드 변경 실패:', error); + showToast('서버 모드 변경 중 오류가 발생했습니다.', 'error'); + } + }, + + updateUI() { + const testBtn = document.getElementById('testServerBtn'); + const prodBtn = document.getElementById('prodServerBtn'); + + // 버튼 스타일 초기화 + testBtn.classList.remove('bg-amber-500', 'text-white', 'bg-gray-200', 'text-gray-600'); + prodBtn.classList.remove('bg-green-500', 'text-white', 'bg-gray-200', 'text-gray-600'); + + if (this.currentMode === 'test') { + testBtn.classList.add('bg-amber-500', 'text-white'); + prodBtn.classList.add('bg-gray-200', 'text-gray-600'); + } else { + testBtn.classList.add('bg-gray-200', 'text-gray-600'); + prodBtn.classList.add('bg-green-500', 'text-white'); + } + } + }; + // 초기화 document.addEventListener('DOMContentLoaded', function() { MemberModal.init(); + BarobillServer.init(); }); @endpush diff --git a/routes/api.php b/routes/api.php index b56a0dcb..d785a902 100644 --- a/routes/api.php +++ b/routes/api.php @@ -118,6 +118,9 @@ Route::get('/stats', [\App\Http\Controllers\Api\Admin\Barobill\BarobillMemberController::class, 'stats'])->name('stats'); // 서비스 코드 목록 (카드사/은행) Route::get('/service-codes', [\App\Http\Controllers\Api\Admin\Barobill\BarobillMemberController::class, 'getServiceCodes'])->name('service-codes'); + // 서버 모드 전환 (테스트/운영) + Route::get('/server-mode', [\App\Http\Controllers\Api\Admin\Barobill\BarobillMemberController::class, 'getServerMode'])->name('server-mode.get'); + Route::post('/server-mode', [\App\Http\Controllers\Api\Admin\Barobill\BarobillMemberController::class, 'setServerMode'])->name('server-mode.set'); // 기본 CRUD Route::get('/', [\App\Http\Controllers\Api\Admin\Barobill\BarobillMemberController::class, 'index'])->name('index');