+
회원사관리
바로빌 연동 회원사를 관리합니다
@@ -26,11 +27,12 @@ class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition
hx-get="/api/admin/barobill/members/stats"
hx-trigger="load, memberUpdated from:body"
hx-headers='{"X-CSRF-TOKEN": "{{ csrf_token() }}"}'
- class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
+ class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6 flex-shrink-0">
@include('barobill.members.partials.stats-skeleton')
+
+
+ class="bg-white rounded-lg shadow-sm overflow-hidden flex-1 flex flex-col min-h-0">
+
@include('barobill.members.partials.modal-form')
+
+
+
+
@endsection
@push('scripts')
@@ -101,7 +140,11 @@ class="bg-white rounded-lg shadow-sm overflow-hidden">
this.resetForm();
document.getElementById('modalTitle').textContent = '회원사 등록';
document.getElementById('submitBtn').textContent = '등록하기';
+ // 비밀번호 필드 표시 (필수 입력)
document.getElementById('passwordFields').classList.remove('hidden');
+ document.getElementById('barobillIdField').classList.remove('hidden'); // 아이디 표시
+ document.getElementById('pwdRequired').classList.remove('hidden'); // 필수 표시
+ document.getElementById('pwdHint').classList.add('hidden'); // 힌트 숨김
this.modal.classList.remove('hidden');
},
@@ -111,7 +154,11 @@ class="bg-white rounded-lg shadow-sm overflow-hidden">
this.resetForm();
document.getElementById('modalTitle').textContent = '회원사 수정';
document.getElementById('submitBtn').textContent = '수정하기';
- document.getElementById('passwordFields').classList.add('hidden');
+ // 비밀번호 필드 표시 (선택적 입력)
+ document.getElementById('passwordFields').classList.remove('hidden');
+ document.getElementById('barobillIdField').classList.add('hidden'); // 아이디는 숨김
+ document.getElementById('pwdRequired').classList.add('hidden'); // 필수 표시 숨김
+ document.getElementById('pwdHint').classList.remove('hidden'); // 힌트 표시
// 데이터 로드
fetch(`/api/admin/barobill/members/${id}`, {
@@ -164,7 +211,10 @@ class="bg-white rounded-lg shadow-sm overflow-hidden">
if (this.isEditing) {
delete data.biz_no;
delete data.barobill_id;
- delete data.barobill_pwd;
+ // 비밀번호가 비어있으면 제외 (서버에서도 빈 값은 무시)
+ if (!data.barobill_pwd) {
+ delete data.barobill_pwd;
+ }
}
const url = this.isEditing
@@ -240,6 +290,270 @@ class="bg-white rounded-lg shadow-sm overflow-hidden">
});
};
+ // 바로빌 서비스 관리
+ const BarobillService = {
+ currentMemberId: null,
+ currentMemberName: '',
+ currentAction: '',
+ currentTitle: '',
+
+ // 액션별 엔드포인트 매핑
+ endpoints: {
+ // 계좌 관련
+ 'bank_account': 'bank-account-url',
+ 'bank_account_manage': 'bank-account-manage-url',
+ 'bank_account_log': 'bank-account-log-url',
+ // 카드 관련
+ 'card': 'card-url',
+ 'card_manage': 'card-manage-url',
+ 'card_log': 'card-log-url',
+ // 전자세금계산서 관련
+ 'certificate': 'certificate-url',
+ 'tax_invoice': 'tax-invoice-url',
+ 'tax_invoice_list': 'tax-invoice-list-url',
+ // 공통
+ 'cash_charge': 'cash-charge-url',
+ },
+
+ // 통합 URL 열기 함수 (비밀번호 입력 없이 바로 호출)
+ async openUrl(memberId, memberName, action, title) {
+ const endpoint = this.endpoints[action];
+ if (!endpoint) {
+ showToast('잘못된 액션입니다.', 'error');
+ return;
+ }
+
+ try {
+ const res = await fetch(`/api/admin/barobill/members/${memberId}/${endpoint}`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-CSRF-TOKEN': '{{ csrf_token() }}',
+ 'Accept': 'application/json'
+ },
+ body: JSON.stringify({})
+ });
+
+ const result = await res.json();
+
+ if (result.success && result.data?.url) {
+ window.open(result.data.url, '_blank', 'width=1000,height=700');
+ } else {
+ showToast(result.message || result.error || 'URL을 가져오는데 실패했습니다.', 'error');
+ }
+ } catch (error) {
+ showToast('통신 오류가 발생했습니다.', 'error');
+ }
+ },
+
+ // 상태 조회 모달 열기
+ async showStatus(memberId, memberName) {
+ document.getElementById('statusModalMemberName').textContent = memberName;
+ document.getElementById('statusModalContent').innerHTML = `
+
+ `;
+ document.getElementById('statusModal').classList.remove('hidden');
+
+ try {
+ // 병렬로 상태 조회 (인증서, 잔액, 계좌, 카드)
+ const [certRes, balanceRes, accountsRes, cardsRes] = await Promise.all([
+ fetch(`/api/admin/barobill/members/${memberId}/certificate-status`, {
+ headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}', 'Accept': 'application/json' }
+ }),
+ fetch(`/api/admin/barobill/members/${memberId}/balance`, {
+ headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}', 'Accept': 'application/json' }
+ }),
+ fetch(`/api/admin/barobill/members/${memberId}/bank-accounts`, {
+ headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}', 'Accept': 'application/json' }
+ }),
+ fetch(`/api/admin/barobill/members/${memberId}/cards`, {
+ headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}', 'Accept': 'application/json' }
+ }),
+ ]);
+
+ const cert = await certRes.json();
+ const balance = await balanceRes.json();
+ const accounts = await accountsRes.json();
+ const cards = await cardsRes.json();
+
+ this.renderStatusContent(cert, balance, accounts, cards);
+ } catch (error) {
+ document.getElementById('statusModalContent').innerHTML = `
+
+ `;
+ }
+ },
+
+ renderStatusContent(cert, balance, accounts, cards) {
+ const certData = cert.success ? cert.data : {};
+ const balanceData = balance.success ? balance.data : {};
+
+ let html = `
+
+
+
+
+
+ 공동인증서 (전자세금계산서용)
+
+
+
+
상태
+
+ ${certData.is_valid ? '유효' : '미등록 또는 만료'}
+
+
+
+
만료일
+
${certData.expire_date || '-'}
+
+
+
+
+
+
+
+
+ 충전 잔액
+
+
+ ${balanceData.balance !== undefined ? Number(balanceData.balance).toLocaleString() + '원' : '-'}
+
+
+
+
+
+
+
+ 등록 계좌 (빠른조회 서비스)
+
+ `;
+
+ if (accounts.success && accounts.data) {
+ const accountList = Array.isArray(accounts.data) ? accounts.data :
+ (accounts.data.BankAccountInfo ? [accounts.data.BankAccountInfo] : []);
+
+ if (accountList.length > 0) {
+ html += `
`;
+ accountList.forEach(acc => {
+ html += `
+
+ ${acc.Bank || acc.BankCode || '은행'}
+ ${acc.BankAccountNum || acc.AccountNum || '-'}
+
+ `;
+ });
+ html += `
`;
+ } else {
+ html += `
등록된 계좌가 없습니다.
`;
+ }
+ } else {
+ html += `
계좌 정보를 불러올 수 없습니다.
`;
+ }
+
+ html += `
`;
+
+ // 등록 카드
+ html += `
+
+
+
+ 등록 카드
+
+ `;
+
+ if (cards && cards.success && cards.data) {
+ const cardList = Array.isArray(cards.data) ? cards.data :
+ (cards.data.CardInfo ? [cards.data.CardInfo] : []);
+
+ if (cardList.length > 0) {
+ html += `
`;
+ cardList.forEach(card => {
+ const cardNum = card.CardNum || card.cardNum || '-';
+ const maskedNum = cardNum.length > 8 ? cardNum.slice(0, 4) + '-****-****-' + cardNum.slice(-4) : cardNum;
+ html += `
+
+ ${card.CardCompanyName || card.cardCompanyName || '카드사'}
+ ${maskedNum}
+
+ `;
+ });
+ html += `
`;
+ } else {
+ html += `
등록된 카드가 없습니다.
`;
+ }
+ } else {
+ html += `
카드 정보를 불러올 수 없습니다.
`;
+ }
+
+ html += `
+
+
+ `;
+
+ document.getElementById('statusModalContent').innerHTML = html;
+ },
+
+ closeStatusModal() {
+ document.getElementById('statusModal').classList.add('hidden');
+ }
+ };
+
+ // 바로빌 드롭다운 토글 (vanilla JS)
+ let currentOpenDropdown = null;
+
+ function toggleBarobillDropdown(button) {
+ const dropdown = button.closest('.barobill-dropdown');
+ const menu = dropdown.querySelector('.barobill-menu');
+ const isOpen = !menu.classList.contains('hidden');
+
+ // 다른 열린 드롭다운 닫기
+ closeBarobillDropdown();
+
+ if (!isOpen) {
+ menu.classList.remove('hidden');
+ currentOpenDropdown = dropdown;
+ }
+ }
+
+ function closeBarobillDropdown() {
+ if (currentOpenDropdown) {
+ const menu = currentOpenDropdown.querySelector('.barobill-menu');
+ if (menu) menu.classList.add('hidden');
+ currentOpenDropdown = null;
+ }
+ // 모든 드롭다운 닫기
+ document.querySelectorAll('.barobill-menu').forEach(menu => {
+ menu.classList.add('hidden');
+ });
+ }
+
+ // 바깥 클릭 시 드롭다운 닫기
+ document.addEventListener('click', function(e) {
+ if (!e.target.closest('.barobill-dropdown')) {
+ closeBarobillDropdown();
+ }
+ });
+
+ // ESC 키로 드롭다운 닫기
+ document.addEventListener('keydown', function(e) {
+ if (e.key === 'Escape') {
+ closeBarobillDropdown();
+ }
+ });
+
// 초기화
document.addEventListener('DOMContentLoaded', function() {
MemberModal.init();
diff --git a/resources/views/barobill/members/partials/modal-form.blade.php b/resources/views/barobill/members/partials/modal-form.blade.php
index e3239e77..bd66fe9b 100644
--- a/resources/views/barobill/members/partials/modal-form.blade.php
+++ b/resources/views/barobill/members/partials/modal-form.blade.php
@@ -76,15 +76,16 @@ class="w-10 h-10 flex items-center justify-center rounded-full text-gray-600 hov