feat: 백제약품 프론트엔드 완전 통합

- 도매상 재고 조회에 백제 추가
- searchBaekjeAPI 함수 추가
- renderWholesaleResults에 백제 섹션 추가
- addToCartFromWholesale에 백제 처리 추가
- executeOrder에 백제 도매상 필터 추가
- CSS 스타일 추가 (주황색 테마)
This commit is contained in:
thug0bin 2026-03-06 13:18:29 +09:00
parent 857a058691
commit 055fad574d

View File

@ -1180,15 +1180,11 @@
const wholesaler = currentOrderWholesaler || 'geoyoung';
// 해당 도매상 품목 필터
let items;
if (wholesaler === 'sooin') {
items = cart.filter(c => c.supplier === '수인약품' || c.wholesaler === 'sooin');
} else {
items = cart.filter(c => c.supplier === '지오영' || c.wholesaler === 'geoyoung');
}
const ws = WHOLESALERS[wholesaler];
const items = cart.filter(ws.filterFn);
if (items.length === 0) {
showToast(`${wholesaler === 'sooin' ? '수인약품' : '지오영'} 품목이 없습니다`, 'error');
showToast(`${ws.name} 품목이 없습니다`, 'error');
return;
}
@ -1317,9 +1313,14 @@
html += `<div class="result-note">💡 테스트 모드입니다. 실제 주문은 "실제 주문" 버튼을 누르세요.</div>`;
}
// 수인약품 실제 주문 시 안내
if (!isDryRun && wholesalerId === 'sooin' && result.note) {
html += `<div class="result-note" style="background:rgba(168,85,247,0.1);color:#a855f7;">📌 ${result.note}</div>`;
// 수인/백제 실제 주문 시 안내
if (!isDryRun && result.note) {
const noteColors = {
sooin: 'rgba(168,85,247,0.1);color:#a855f7',
baekje: 'rgba(245,158,11,0.1);color:#f59e0b'
};
const noteStyle = noteColors[wholesalerId] || 'rgba(100,100,100,0.1);color:#888';
html += `<div class="result-note" style="background:${noteStyle};">📌 ${result.note}</div>`;
}
content.innerHTML = html;
@ -1393,9 +1394,9 @@
if (e.key === 'Enter') loadUsageData();
});
// ──────────────── 도매상 재고 조회 (지오영 + 수인) ────────────────
// ──────────────── 도매상 재고 조회 (지오영 + 수인 + 백제) ────────────────
let currentWholesaleItem = null;
window.wholesaleItems = { geoyoung: [], sooin: [] };
window.wholesaleItems = { geoyoung: [], sooin: [], baekje: [] };
function openWholesaleModal(idx) {
const item = usageData[idx];
@ -1415,11 +1416,11 @@
document.getElementById('geoResultBody').innerHTML = `
<div class="geo-loading">
<div class="loading-spinner"></div>
<div>도매상 재고 조회 중... (지오영 + 수인)</div>
<div>도매상 재고 조회 중... (지오영 + 수인 + 백제)</div>
</div>`;
document.getElementById('geoSearchKeyword').style.display = 'none';
// 도매상 동시 호출
// 도매상 동시 호출
searchAllWholesalers(item.drug_code, item.product_name);
}
@ -1431,20 +1432,22 @@
async function searchAllWholesalers(kdCode, productName) {
const resultBody = document.getElementById('geoResultBody');
// 도매상 동시 호출
const [geoResult, sooinResult] = await Promise.all([
// 도매상 동시 호출
const [geoResult, sooinResult, baekjeResult] = await Promise.all([
searchGeoyoungAPI(kdCode, productName),
searchSooinAPI(kdCode)
searchSooinAPI(kdCode),
searchBaekjeAPI(kdCode)
]);
// 결과 저장
window.wholesaleItems = {
geoyoung: geoResult.items || [],
sooin: sooinResult.items || []
sooin: sooinResult.items || [],
baekje: baekjeResult.items || []
};
// 통합 렌더링
renderWholesaleResults(geoResult, sooinResult);
renderWholesaleResults(geoResult, sooinResult, baekjeResult);
}
async function searchGeoyoungAPI(kdCode, productName) {
@ -1475,15 +1478,27 @@
}
}
function renderWholesaleResults(geoResult, sooinResult) {
async function searchBaekjeAPI(kdCode) {
try {
const response = await fetch(`/api/baekje/stock?keyword=${encodeURIComponent(kdCode)}`);
const data = await response.json();
return data;
} catch (err) {
return { success: false, error: err.message, items: [] };
}
}
function renderWholesaleResults(geoResult, sooinResult, baekjeResult) {
const resultBody = document.getElementById('geoResultBody');
const geoItems = geoResult.items || [];
const sooinItems = sooinResult.items || [];
const baekjeItems = (baekjeResult && baekjeResult.items) || [];
// 재고 있는 것 먼저 정렬
geoItems.sort((a, b) => (b.stock > 0 ? 1 : 0) - (a.stock > 0 ? 1 : 0) || b.stock - a.stock);
sooinItems.sort((a, b) => (b.stock > 0 ? 1 : 0) - (a.stock > 0 ? 1 : 0) || b.stock - a.stock);
baekjeItems.sort((a, b) => (b.stock > 0 ? 1 : 0) - (a.stock > 0 ? 1 : 0) || b.stock - a.stock);
let html = '';
@ -1560,6 +1575,42 @@
}
html += '</div>';
// ═══════ 백제약품 섹션 ═══════
html += `<div class="ws-section">
<div class="ws-header baekje">
<span class="ws-logo">💉</span>
<span class="ws-name">백제약품</span>
<span class="ws-count">${baekjeItems.length}건</span>
</div>`;
if (baekjeItems.length > 0) {
html += `<table class="geo-table">
<thead><tr><th>제품명</th><th>규격</th><th>단가</th><th>재고</th><th></th></tr></thead>
<tbody>`;
baekjeItems.forEach((item, idx) => {
const hasStock = item.stock > 0;
html += `
<tr class="${hasStock ? '' : 'no-stock'}">
<td>
<div class="geo-product">
<span class="geo-name">${escapeHtml(item.name)}</span>
<span class="geo-code">${item.insurance_code || ''} · ${item.manufacturer || ''}</span>
</div>
</td>
<td class="geo-spec">${item.spec || '-'}</td>
<td class="geo-price">${item.price ? item.price.toLocaleString() + '원' : '-'}</td>
<td class="geo-stock ${hasStock ? 'in-stock' : 'out-stock'}">${item.stock}</td>
<td>${hasStock ? `<button class="geo-add-btn baekje" onclick="addToCartFromWholesale('baekje', ${idx})">담기</button>` : ''}</td>
</tr>`;
});
html += '</tbody></table>';
} else {
html += `<div class="ws-empty">📭 검색 결과 없음</div>`;
}
html += '</div>';
resultBody.innerHTML = html;
}
@ -1577,7 +1628,8 @@
const needed = currentWholesaleItem.total_dose;
const suggestedQty = Math.ceil(needed / specQty);
const supplierName = wholesaler === 'geoyoung' ? '지오영' : '수인약품';
const supplierNames = { geoyoung: '지오영', sooin: '수인약품', baekje: '백제약품' };
const supplierName = supplierNames[wholesaler] || wholesaler;
const productName = wholesaler === 'geoyoung' ? item.product_name : item.name;
const qty = prompt(`[${supplierName}] 주문 수량 (${spec} 기준)\n\n필요량: ${needed}개\n규격: ${specQty}개/단위\n추천: ${suggestedQty}단위 (${suggestedQty * specQty}개)`, suggestedQty);
@ -1592,9 +1644,10 @@
qty: parseInt(qty),
specification: spec,
wholesaler: wholesaler,
internal_code: wholesaler === 'geoyoung' ? item.internal_code : item.internal_code,
internal_code: item.internal_code,
geoyoung_code: wholesaler === 'geoyoung' ? item.insurance_code : null,
sooin_code: wholesaler === 'sooin' ? item.code : null
sooin_code: wholesaler === 'sooin' ? item.code : null,
baekje_code: wholesaler === 'baekje' ? item.internal_code : null
};
// 기존 항목 체크 (같은 도매상 + 같은 규격)
@ -1827,6 +1880,12 @@
.geo-add-btn.sooin:hover {
background: #7c3aed;
}
.geo-add-btn.baekje {
background: var(--accent-amber);
}
.geo-add-btn.baekje:hover {
background: #d97706;
}
.geo-price {
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
@ -1857,6 +1916,10 @@
background: linear-gradient(135deg, rgba(168, 85, 247, 0.2), rgba(124, 58, 237, 0.1));
border-left: 3px solid var(--accent-purple);
}
.ws-header.baekje {
background: linear-gradient(135deg, rgba(245, 158, 11, 0.2), rgba(217, 119, 6, 0.1));
border-left: 3px solid var(--accent-amber);
}
.ws-logo {
width: 24px;
height: 24px;