diff --git a/backend/app.py b/backend/app.py
index f9fe199..4c73bc4 100644
--- a/backend/app.py
+++ b/backend/app.py
@@ -3345,9 +3345,11 @@ def api_products():
ISNULL(G.SplName, '') as supplier,
0 as is_set,
G.POS_BOON as pos_boon,
- IT.IM_QT_sale_debit as stock
+ IT.IM_QT_sale_debit as stock,
+ ISNULL(POS.CD_NM_sale, '') as location
FROM CD_GOODS G
INNER JOIN IM_total IT ON G.DrugCode = IT.DrugCode AND IT.IM_QT_sale_debit > 0
+ LEFT JOIN CD_item_position POS ON G.DrugCode = POS.DrugCode
WHERE 1=1
{animal_condition}
{search_condition}
@@ -3367,9 +3369,11 @@ def api_products():
ISNULL(G.SplName, '') as supplier,
0 as is_set,
G.POS_BOON as pos_boon,
- ISNULL(IT.IM_QT_sale_debit, 0) as stock
+ ISNULL(IT.IM_QT_sale_debit, 0) as stock,
+ ISNULL(POS.CD_NM_sale, '') as location
FROM CD_GOODS G
LEFT JOIN IM_total IT ON G.DrugCode = IT.DrugCode
+ LEFT JOIN CD_item_position POS ON G.DrugCode = POS.DrugCode
WHERE G.POS_BOON = '010103'
{search_condition}
ORDER BY G.GoodsName
@@ -3389,9 +3393,11 @@ def api_products():
END as supplier,
CASE WHEN SET_CHK.is_set = 1 THEN 1 ELSE 0 END as is_set,
G.POS_BOON as pos_boon,
- ISNULL(IT.IM_QT_sale_debit, 0) as stock
+ ISNULL(IT.IM_QT_sale_debit, 0) as stock,
+ ISNULL(POS.CD_NM_sale, '') as location
FROM CD_GOODS G
LEFT JOIN IM_total IT ON G.DrugCode = IT.DrugCode
+ LEFT JOIN CD_item_position POS ON G.DrugCode = POS.DrugCode
OUTER APPLY (
SELECT TOP 1 CD_CD_BARCODE
FROM CD_ITEM_UNIT_MEMBER
@@ -3445,6 +3451,7 @@ def api_products():
'is_set': bool(row.is_set),
'is_animal_drug': is_animal,
'stock': int(row.stock) if row.stock else 0,
+ 'location': row.location or '', # 위치
'apc': apc,
'category': None, # PostgreSQL에서 lazy fetch
'wholesaler_stock': None,
diff --git a/backend/templates/admin_products.html b/backend/templates/admin_products.html
index 1acf396..af16793 100644
--- a/backend/templates/admin_products.html
+++ b/backend/templates/admin_products.html
@@ -1,9 +1,9 @@
-
+
- 제품 검색 - 청춘약국
+ ?�품 검??- �?��?�국
@@ -16,7 +16,7 @@
color: #1e293b;
}
- /* ── 헤더 ── */
+ /* ?�?� ?�더 ?�?� */
.header {
background: linear-gradient(135deg, #7c3aed 0%, #8b5cf6 50%, #a78bfa 100%);
padding: 28px 32px 24px;
@@ -46,14 +46,14 @@
opacity: 0.85;
}
- /* ── 컨텐츠 ── */
+ /* ?�?� 컨텐�??�?� */
.content {
max-width: 1100px;
margin: 0 auto;
padding: 24px 20px 60px;
}
- /* ── 플로팅 챗봇 ── */
+ /* ?�?� ?�로??챗봇 ?�?� */
.chatbot-panel {
position: fixed;
right: 24px;
@@ -224,7 +224,7 @@
30% { transform: translateY(-6px); opacity: 1; }
}
- /* ── 챗봇 토글 버튼 (항상 표시) ── */
+ /* ?�?� 챗봇 ?��? 버튼 (??�� ?�시) ?�?� */
.chatbot-toggle {
position: fixed;
bottom: 24px;
@@ -253,7 +253,7 @@
box-shadow: 0 4px 20px rgba(239, 68, 68, 0.4);
}
- /* 모바일 */
+ /* 모바??*/
@media (max-width: 640px) {
.chatbot-panel {
right: 0;
@@ -266,7 +266,7 @@
.chatbot-toggle { bottom: 16px; right: 16px; }
}
- /* ── 검색 영역 ── */
+ /* ?�?� 검???�역 ?�?� */
.search-section {
background: #fff;
border-radius: 14px;
@@ -320,7 +320,7 @@
margin-right: 8px;
}
- /* ── 결과 카운트 ── */
+ /* ?�?� 결과 카운???�?� */
.result-count {
margin-bottom: 16px;
font-size: 14px;
@@ -331,7 +331,7 @@
font-weight: 700;
}
- /* ── 테이블 ── */
+ /* ?�?� ?�이�??�?� */
.table-wrap {
background: #fff;
border-radius: 14px;
@@ -362,7 +362,7 @@
tbody tr:hover { background: #faf5ff; }
tbody tr:last-child td { border-bottom: none; }
- /* ── 상품 정보 ── */
+ /* ?�?� ?�품 ?�보 ?�?� */
.product-name {
font-weight: 600;
color: #1e293b;
@@ -377,7 +377,7 @@
font-weight: 500;
}
- /* ── 코드/바코드 ── */
+ /* ?�?� 코드/바코???�?� */
.code {
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
@@ -397,14 +397,23 @@
background: #f1f5f9;
color: #94a3b8;
}
+ .location-badge {
+ display: inline-block;
+ background: #fef3c7;
+ color: #92400e;
+ font-size: 11px;
+ padding: 3px 8px;
+ border-radius: 4px;
+ font-weight: 500;
+ }
- /* ── 가격 ── */
+ /* ?�?� 가�??�?� */
.price {
font-weight: 600;
color: #1e293b;
white-space: nowrap;
}
- /* ── 재고 ── */
+ /* ?�?� ?�고 ?�?� */
.stock {
font-weight: 600;
white-space: nowrap;
@@ -413,7 +422,7 @@
.stock.in-stock { color: #10b981; }
.stock.out-stock { color: #ef4444; }
- /* ── QR 버튼 ── */
+ /* ?�?� QR 버튼 ?�?� */
.btn-qr {
background: #8b5cf6;
color: #fff;
@@ -429,7 +438,7 @@
.btn-qr:hover { background: #7c3aed; }
.btn-qr:active { transform: scale(0.95); }
- /* ── 빈 상태 ── */
+ /* ?�?� �??�태 ?�?� */
.empty-state {
text-align: center;
padding: 60px 20px;
@@ -443,7 +452,7 @@
font-size: 15px;
}
- /* ── 모달 ── */
+ /* ?�?� 모달 ?�?� */
.modal-overlay {
display: none;
position: fixed;
@@ -479,7 +488,7 @@
border-radius: 8px;
}
- /* ── 수량 선택기 ── */
+ /* ?�?� ?�량 ?�택�??�?� */
.qty-selector {
display: flex;
align-items: center;
@@ -547,7 +556,7 @@
.modal-btn.confirm { background: #8b5cf6; color: #fff; }
.modal-btn.confirm:hover { background: #7c3aed; }
- /* ── 제품 이미지 ── */
+ /* ?�?� ?�품 ?��?지 ?�?� */
.product-thumb {
width: 40px;
height: 40px;
@@ -583,7 +592,7 @@
fill: #94a3b8;
}
- /* ── 이미지 모달 ── */
+ /* ?�?� ?��?지 모달 ?�?� */
.image-modal {
display: none;
position: fixed;
@@ -670,7 +679,7 @@
.img-modal-btn.secondary { background: #f1f5f9; color: #64748b; }
.img-modal-btn.primary { background: #8b5cf6; color: #fff; }
- /* ── 반응형 ── */
+ /* ?�?� 반응???�?� */
@media (max-width: 768px) {
.search-box { flex-direction: column; }
.table-wrap { overflow-x: auto; }
@@ -681,40 +690,40 @@
-
+
- 🔍 검색
+ ?�� 검??/button>
- 예시 타이레놀, 벤포파워, 8806418067510, LB000001423
+ ?�시 ?�?�레?�, 벤포?�워, 8806418067510, LB000001423
- 📦 사용약품만
+ ?�� ?�용?�품�?/strong>
- 🐾 동물약만
+ ?�� ?�물?�만
@@ -723,27 +732,28 @@
- 검색 결과: 0 건
+ 검??결과: 0 �?
- 이미지
- 상품명
- 상품코드
- 바코드
- 재고
- 판매가
+ ?��?지
+ ?�품�?/th>
+ ?�품코드
+ 바코??/th>
+ ?�치
+ ?�고
+ ?�매가
QR
-
- 🔍
- 상품명, 바코드, 상품코드로 검색하세요
+
+ ?��
+ ?�품�? 바코?? ?�품코드�?검?�하?�요
@@ -751,51 +761,51 @@
-
+
- 🐕 심장사상충약
- 넥스가드 vs 브라벡토
- 🐱 고양이 벼룩약
- 🪱 구충제
+ ?�� ?�장?�상충약
+ ?�스가??vs 브라벡토
+ ?�� 고양??벼룩??/button>
+ ?�� 구충??/button>
- 안녕하세요! 🐾 동물약 상담 AI입니다.
- 반려동물의 심장사상충 예방 , 벼룩/진드기 예방 , 구충제 등에 대해 무엇이든 물어보세요!
+ ?�녕?�세?? ?�� ?�물???�담 AI?�니??
+ 반려?�물???�장?�상�??�방 , 벼룩/진드�??�방 , 구충??/strong> ?�에 ?�??무엇?�든 물어보세??
-
- ➤
+ ??/button>
-
- 🐾
+
+ ?��
-
+
-
🏷️ QR 라벨 인쇄
+
?���?QR ?�벨 ?�쇄
-
미리보기 로딩 중...
+
미리보기 로딩 �?..
-
인쇄 매수
+
?�쇄 매수
취소
- 인쇄
+ ?�쇄
@@ -809,7 +819,7 @@
function formatPrice(num) {
if (!num) return '-';
- return new Intl.NumberFormat('ko-KR').format(num) + '원';
+ return new Intl.NumberFormat('ko-KR').format(num) + '??;
}
function escapeHtml(str) {
@@ -821,20 +831,20 @@
const search = document.getElementById('searchInput').value.trim();
const animalOnly = document.getElementById('animalOnly').checked;
- // 동물약만 체크시 검색어 없어도 전체 조회 가능
+ // ?�물?�만 체크??검?�어 ?�어???�체 조회 가??
if (!animalOnly) {
if (!search) {
- alert('검색어를 입력하세요');
+ alert('검?�어�??�력?�세??);
return;
}
if (search.length < 2) {
- alert('2글자 이상 입력하세요');
+ alert('2글???�상 ?�력?�세??);
return;
}
}
const tbody = document.getElementById('productsTableBody');
- tbody.innerHTML = '검색 중...
';
+ tbody.innerHTML = '검??�?..
';
const inStockOnly = document.getElementById('inStockOnly').checked;
let url = `/api/products?search=${encodeURIComponent(search)}`;
@@ -849,11 +859,11 @@
document.getElementById('resultNum').textContent = productsData.length;
renderTable();
} else {
- tbody.innerHTML = `오류: ${data.error}
`;
+ tbody.innerHTML = `?�류: ${data.error}
`;
}
})
.catch(err => {
- tbody.innerHTML = '검색 실패
';
+ tbody.innerHTML = '검???�패
';
});
}
@@ -861,18 +871,18 @@
const tbody = document.getElementById('productsTableBody');
if (productsData.length === 0) {
- tbody.innerHTML = '📭
검색 결과가 없습니다
';
+ tbody.innerHTML = '?��
검??결과가 ?�습?�다
';
return;
}
tbody.innerHTML = productsData.map((item, idx) => {
- // 분류 뱃지 (동물약만)
+ // 분류 뱃�? (?�물?�만)
const categoryBadge = item.category
? `${escapeHtml(item.category)} `
: '';
- // 도매상 재고 표시 (동물약만)
+ // ?�매???�고 ?�시 (?�물?�만)
const wsStock = (item.wholesaler_stock && item.wholesaler_stock > 0)
- ? `(도매 ${item.wholesaler_stock}) `
+ ? `(?�매 ${item.wholesaler_stock}) `
: '';
return `
@@ -886,7 +896,7 @@
${escapeHtml(item.product_name)}
- ${item.is_animal_drug ? '🐾 동물약 ' : ''}
+ ${item.is_animal_drug ? '?�� ?�물??/span>' : ''}
${categoryBadge}
${escapeHtml(item.supplier) || ''}
@@ -894,17 +904,18 @@
${item.drug_code}
${item.barcode
? `${item.barcode} `
- : `없음 `}
+ : `?�음 `}
+ ${item.location ? `${escapeHtml(item.location)} ` : ''}
${item.stock || 0}${wsStock}
${formatPrice(item.sale_price)}
- 🏷️ QR
+ ?���?QR
`}).join('');
}
- // ── QR 인쇄 관련 ──
+ // ?�?� QR ?�쇄 관???�?�
function adjustQty(delta) {
printQty = Math.max(MIN_QTY, Math.min(MAX_QTY, printQty + delta));
updateQtyUI();
@@ -914,7 +925,7 @@
document.getElementById('qtyValue').textContent = printQty;
document.getElementById('qtyMinus').disabled = printQty <= MIN_QTY;
document.getElementById('qtyPlus').disabled = printQty >= MAX_QTY;
- document.getElementById('printBtn').textContent = printQty > 1 ? `${printQty}장 인쇄` : '인쇄';
+ document.getElementById('printBtn').textContent = printQty > 1 ? `${printQty}???�쇄` : '?�쇄';
}
function printQR(idx) {
@@ -925,12 +936,12 @@
const preview = document.getElementById('qrPreview');
const info = document.getElementById('qrInfo');
- preview.innerHTML = '미리보기 로딩 중...
';
+ preview.innerHTML = '미리보기 로딩 �?..
';
info.innerHTML = `
${escapeHtml(selectedItem.product_name)}
- 바코드: ${selectedItem.barcode || selectedItem.drug_code || 'N/A'}
- 가격: ${formatPrice(selectedItem.sale_price)}
+ 바코?? ${selectedItem.barcode || selectedItem.drug_code || 'N/A'}
+ 가�? ${formatPrice(selectedItem.sale_price)}
`;
updateQtyUI();
@@ -951,11 +962,11 @@
if (data.success && data.image) {
preview.innerHTML = ` `;
} else {
- preview.innerHTML = '미리보기 실패
';
+ preview.innerHTML = '미리보기 ?�패
';
}
})
.catch(() => {
- preview.innerHTML = '미리보기 오류
';
+ preview.innerHTML = '미리보기 ?�류
';
});
}
@@ -976,7 +987,7 @@
let errorMsg = '';
for (let i = 0; i < totalQty; i++) {
- btn.textContent = `인쇄 중... (${i + 1}/${totalQty})`;
+ btn.textContent = `?�쇄 �?.. (${i + 1}/${totalQty})`;
try {
const res = await fetch('/api/qr-print', {
@@ -994,7 +1005,7 @@
if (data.success) {
successCount++;
} else {
- errorMsg = data.error || '알 수 없는 오류';
+ errorMsg = data.error || '?????�는 ?�류';
break;
}
@@ -1011,21 +1022,21 @@
updateQtyUI();
if (successCount === totalQty) {
- alert(`✅ QR 라벨 ${totalQty}장 인쇄 완료!`);
+ alert(`??QR ?�벨 ${totalQty}???�쇄 ?�료!`);
closeQRModal();
} else if (successCount > 0) {
- alert(`⚠️ ${successCount}/${totalQty}장 인쇄 완료\n오류: ${errorMsg}`);
+ alert(`?�️ ${successCount}/${totalQty}???�쇄 ?�료\n?�류: ${errorMsg}`);
} else {
- alert(`❌ 인쇄 실패: ${errorMsg}`);
+ alert(`???�쇄 ?�패: ${errorMsg}`);
}
}
- // 페이지 로드 시 검색창 포커스
+ // ?�이지 로드 ??검?�창 ?�커??
document.getElementById('searchInput').focus();
- // ══════════════════════════════════════════════════════════════════
- // 동물약 챗봇
- // ══════════════════════════════════════════════════════════════════
+ // ?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═
+ // ?�물??챗봇
+ // ?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═?�═
let chatHistory = [];
let isChatLoading = false;
@@ -1034,7 +1045,7 @@
const btn = document.getElementById('chatbotToggle');
const isOpen = panel.classList.toggle('open');
btn.classList.toggle('active', isOpen);
- btn.innerHTML = isOpen ? '✕' : '🐾';
+ btn.innerHTML = isOpen ? '?? : '?��';
if (isOpen) {
document.getElementById('chatInput').focus();
}
@@ -1051,14 +1062,14 @@
if (!message || isChatLoading) return;
- // 사용자 메시지 표시
+ // ?�용??메시지 ?�시
addChatMessage('user', message);
input.value = '';
- // 히스토리에 추가
+ // ?�스?�리??추�?
chatHistory.push({ role: 'user', content: message });
- // 로딩 표시
+ // 로딩 ?�시
isChatLoading = true;
document.getElementById('chatSendBtn').disabled = true;
showTypingIndicator();
@@ -1075,22 +1086,22 @@
hideTypingIndicator();
if (data.success) {
- // AI 응답 표시
+ // AI ?�답 ?�시
addChatMessage('assistant', data.message, data.products);
- // 히스토리에 추가
+ // ?�스?�리??추�?
chatHistory.push({ role: 'assistant', content: data.message });
- // 히스토리 길이 제한 (최근 20개)
+ // ?�스?�리 길이 ?�한 (최근 20�?
if (chatHistory.length > 20) {
chatHistory = chatHistory.slice(-20);
}
} else {
- addChatMessage('system', '⚠️ ' + (data.message || '오류가 발생했습니다'));
+ addChatMessage('system', '?�️ ' + (data.message || '?�류가 발생?�습?�다'));
}
} catch (error) {
hideTypingIndicator();
- addChatMessage('system', '⚠️ 네트워크 오류가 발생했습니다');
+ addChatMessage('system', '?�️ ?�트?�크 ?�류가 발생?�습?�다');
}
isChatLoading = false;
@@ -1102,19 +1113,19 @@
const msgDiv = document.createElement('div');
msgDiv.className = `chat-message ${role}`;
- // 줄바꿈 처리
+ // 줄바�?처리
let htmlContent = escapeHtml(content).replace(/\n/g, ' ');
- // 마크다운 굵게 처리
+ // 마크?�운 굵게 처리
htmlContent = htmlContent.replace(/\*\*(.+?)\*\*/g, '$1 ');
msgDiv.innerHTML = htmlContent;
- // 언급된 제품 표시 (이미지 포함)
+ // ?�급???�품 ?�시 (?��?지 ?�함)
if (products && products.length > 0) {
const productsDiv = document.createElement('div');
productsDiv.className = 'products-mentioned';
- productsDiv.innerHTML = '📦 관련 제품: ';
+ productsDiv.innerHTML = '?�� 관???�품: ';
const productsGrid = document.createElement('div');
productsGrid.style.cssText = 'display:flex;flex-wrap:wrap;gap:8px;margin-top:8px;';
@@ -1125,7 +1136,7 @@
card.style.cssText = 'display:flex;align-items:center;gap:8px;padding:8px;background:#f8fafc;border-radius:8px;cursor:pointer;border:1px solid #e2e8f0;';
card.onclick = () => searchProductFromChat(p.name);
- // 이미지 컨테이너
+ // ?��?지 컨테?�너
const imgContainer = document.createElement('div');
imgContainer.style.cssText = 'width:40px;height:40px;flex-shrink:0;';
@@ -1135,25 +1146,25 @@
img.src = p.image_url;
img.alt = p.name;
img.onerror = function() {
- // 이미지 로드 실패 시 아이콘으로 대체
- imgContainer.innerHTML = '💊
';
+ // ?��?지 로드 ?�패 ???�이콘으�??��?
+ imgContainer.innerHTML = '?��
';
};
imgContainer.appendChild(img);
} else {
- // 이미지 없으면 아이콘
- imgContainer.innerHTML = '💊
';
+ // ?��?지 ?�으�??�이�?
+ imgContainer.innerHTML = '?��
';
}
- // 텍스트 (카테고리 뱃지 + 약국/도매 재고)
+ // ?�스??(카테고리 뱃�? + ?�국/?�매 ?�고)
const textDiv = document.createElement('div');
const pharmacyStock = p.stock || 0;
const wholesalerStock = p.wholesaler_stock || 0;
const stockColor = (pharmacyStock > 0) ? '#10b981' : '#ef4444';
- const pharmacyText = (pharmacyStock > 0) ? `약국 ${pharmacyStock}` : '품절';
- const wholesalerText = (wholesalerStock > 0) ? `도매 ${wholesalerStock}` : '';
+ const pharmacyText = (pharmacyStock > 0) ? `?�국 ${pharmacyStock}` : '?�절';
+ const wholesalerText = (wholesalerStock > 0) ? `?�매 ${wholesalerStock}` : '';
const stockDisplay = wholesalerText ? `${pharmacyText} / ${wholesalerText}` : pharmacyText;
- // 카테고리 뱃지
+ // 카테고리 뱃�?
const categoryBadge = p.category
? `${p.category} `
: '';
@@ -1189,18 +1200,18 @@
}
function searchProductFromChat(productName) {
- // 챗봇에서 제품 클릭 시 검색창에 입력하고 검색
+ // 챗봇?�서 ?�품 ?�릭 ??검?�창???�력?�고 검??
document.getElementById('searchInput').value = productName;
document.getElementById('animalOnly').checked = true;
searchProducts();
- // 모바일에서 챗봇 닫기
+ // 모바?�에??챗봇 ?�기
if (window.innerWidth <= 1100) {
document.getElementById('chatbotPanel').classList.remove('open');
}
}
- // ── 이미지 등록 모달 ──
+ // ?�?� ?��?지 ?�록 모달 ?�?�
let imgModalBarcode = null;
let imgModalDrugCode = null;
let imgModalName = null;
@@ -1209,7 +1220,7 @@
function openImageModal(barcode, drugCode, productName) {
if (!barcode && !drugCode) {
- alert('제품 코드 정보가 없습니다');
+ alert('?�품 코드 ?�보가 ?�습?�다');
return;
}
@@ -1257,7 +1268,7 @@
document.getElementById('previewBtns').style.display = 'none';
capturedImageData = null;
} catch (err) {
- alert('카메라에 접근할 수 없습니다');
+ alert('카메?�에 ?�근?????�습?�다');
}
}
@@ -1298,11 +1309,11 @@
}
async function submitCapturedImage() {
- if (!capturedImageData) { alert('촬영된 이미지가 없습니다'); return; }
+ if (!capturedImageData) { alert('촬영???��?지가 ?�습?�다'); return; }
const code = imgModalBarcode || imgModalDrugCode;
const name = imgModalName;
closeImageModal();
- showToast(`"${name}" 이미지 저장 중...`);
+ showToast(`"${name}" ?��?지 ?�??�?..`);
try {
const res = await fetch(`/api/admin/product-images/${code}/upload`, {
method: 'POST',
@@ -1310,19 +1321,19 @@
body: JSON.stringify({ image_data: capturedImageData, product_name: name, drug_code: imgModalDrugCode })
});
const data = await res.json();
- if (data.success) { showToast('✅ 이미지 저장 완료!', 'success'); searchProducts(); }
- else showToast(data.error || '저장 실패', 'error');
- } catch (err) { showToast('오류: ' + err.message, 'error'); }
+ if (data.success) { showToast('???��?지 ?�???�료!', 'success'); searchProducts(); }
+ else showToast(data.error || '?�???�패', 'error');
+ } catch (err) { showToast('?�류: ' + err.message, 'error'); }
}
async function submitImageUrl() {
const url = document.getElementById('imgUrlInput').value.trim();
- if (!url) { alert('이미지 URL을 입력하세요'); return; }
- if (!url.startsWith('http')) { alert('올바른 URL을 입력하세요'); return; }
+ if (!url) { alert('?��?지 URL???�력?�세??); return; }
+ if (!url.startsWith('http')) { alert('?�바�?URL???�력?�세??); return; }
const code = imgModalBarcode || imgModalDrugCode;
const name = imgModalName;
closeImageModal();
- showToast(`"${name}" 이미지 다운로드 중...`);
+ showToast(`"${name}" ?��?지 ?�운로드 �?..`);
try {
const res = await fetch(`/api/admin/product-images/${code}/replace`, {
method: 'POST',
@@ -1330,9 +1341,9 @@
body: JSON.stringify({ image_url: url, product_name: name, drug_code: imgModalDrugCode })
});
const data = await res.json();
- if (data.success) { showToast('✅ 이미지 등록 완료!', 'success'); searchProducts(); }
- else showToast(data.error || '등록 실패', 'error');
- } catch (err) { showToast('오류: ' + err.message, 'error'); }
+ if (data.success) { showToast('???��?지 ?�록 ?�료!', 'success'); searchProducts(); }
+ else showToast(data.error || '?�록 ?�패', 'error');
+ } catch (err) { showToast('?�류: ' + err.message, 'error'); }
}
function showToast(msg, type = 'info') {
@@ -1348,25 +1359,25 @@
});
-
+
-
📷 제품 이미지 등록
+
?�� ?�품 ?��?지 ?�록
-
제품명
+
- 🔗 URL 입력
- 📸 촬영
+ ?�� URL ?�력
+ ?�� 촬영
@@ -1382,14 +1393,15 @@
취소
- 📸 촬영
+ ?�� 촬영
- 다시 촬영
- 저장하기
+ ?�시 촬영
+ ?�?�하�?/button>
+