feat(반품관리): 위치 컬럼 추가

- CSS: .location-badge (노란 배지 스타일)
- 테이블 헤더에 위치 컬럼 추가
- API의 location 필드 활용 (CD_item_position 조인)
- Edit으로 부분 수정하여 인코딩 유지
This commit is contained in:
thug0bin 2026-03-08 11:16:13 +09:00
parent eda0429a85
commit e82f4be4af

View File

@ -96,7 +96,7 @@
padding: 24px; padding: 24px;
} }
/* ══════════════════ 통계 카드 ══════════════════ */ /* ══════════════════ 통계 카드 (2줄) ══════════════════ */
.stats-row { .stats-row {
display: flex; display: flex;
gap: 16px; gap: 16px;
@ -129,17 +129,38 @@
.stat-card.purple::before { background: var(--accent-purple); } .stat-card.purple::before { background: var(--accent-purple); }
.stat-card.gold::before { background: var(--accent-gold); } .stat-card.gold::before { background: var(--accent-gold); }
.stat-icon { font-size: 20px; margin-bottom: 8px; } .stat-icon {
.stat-value { font-size: 24px; font-weight: 700; letter-spacing: -1px; margin-bottom: 2px; } font-size: 20px;
.stat-value.small { font-size: 18px; } margin-bottom: 8px;
}
.stat-value {
font-size: 24px;
font-weight: 700;
letter-spacing: -1px;
margin-bottom: 2px;
}
.stat-value.small {
font-size: 18px;
}
.stat-card.rose .stat-value { color: var(--accent-rose); } .stat-card.rose .stat-value { color: var(--accent-rose); }
.stat-card.amber .stat-value { color: var(--accent-amber); } .stat-card.amber .stat-value { color: var(--accent-amber); }
.stat-card.cyan .stat-value { color: var(--accent-cyan); } .stat-card.cyan .stat-value { color: var(--accent-cyan); }
.stat-card.emerald .stat-value { color: var(--accent-emerald); } .stat-card.emerald .stat-value { color: var(--accent-emerald); }
.stat-card.purple .stat-value { color: var(--accent-purple); } .stat-card.purple .stat-value { color: var(--accent-purple); }
.stat-card.gold .stat-value { color: var(--accent-gold); } .stat-card.gold .stat-value { color: var(--accent-gold); }
.stat-label { font-size: 11px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; }
.stat-sub { font-size: 10px; color: var(--text-muted); margin-top: 2px; } .stat-label {
font-size: 11px;
font-weight: 600;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.5px;
}
.stat-sub {
font-size: 10px;
color: var(--text-muted);
margin-top: 2px;
}
/* ══════════════════ 필터 바 ══════════════════ */ /* ══════════════════ 필터 바 ══════════════════ */
.filter-bar { .filter-bar {
@ -153,8 +174,18 @@
flex-wrap: wrap; flex-wrap: wrap;
align-items: flex-end; align-items: flex-end;
} }
.filter-group { display: flex; flex-direction: column; gap: 6px; } .filter-group {
.filter-group label { font-size: 11px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; } display: flex;
flex-direction: column;
gap: 6px;
}
.filter-group label {
font-size: 11px;
font-weight: 600;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.5px;
}
.filter-group select, .filter-group input { .filter-group select, .filter-group input {
padding: 10px 14px; padding: 10px 14px;
background: var(--bg-primary); background: var(--bg-primary);
@ -182,10 +213,17 @@
cursor: pointer; cursor: pointer;
transition: all 0.2s; transition: all 0.2s;
} }
.filter-btn:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(249, 115, 22, 0.4); } .filter-btn:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(249, 115, 22, 0.4);
}
/* ══════════════════ 긴급도 탭 ══════════════════ */ /* ══════════════════ 긴급도 탭 ══════════════════ */
.urgency-tabs { display: flex; gap: 8px; margin-bottom: 16px; } .urgency-tabs {
display: flex;
gap: 8px;
margin-bottom: 16px;
}
.urgency-tab { .urgency-tab {
padding: 10px 20px; padding: 10px 20px;
border-radius: 10px; border-radius: 10px;
@ -200,10 +238,23 @@
align-items: center; align-items: center;
gap: 6px; gap: 6px;
} }
.urgency-tab:hover { border-color: var(--text-muted); } .urgency-tab:hover {
.urgency-tab.active { background: linear-gradient(135deg, var(--accent-orange), #ea580c); border-color: transparent; color: #fff; } border-color: var(--text-muted);
.urgency-tab .count { background: rgba(255,255,255,0.2); padding: 2px 8px; border-radius: 100px; font-size: 11px; } }
.urgency-tab.active .count { background: rgba(255,255,255,0.3); } .urgency-tab.active {
background: linear-gradient(135deg, var(--accent-orange), #ea580c);
border-color: transparent;
color: #fff;
}
.urgency-tab .count {
background: rgba(255,255,255,0.2);
padding: 2px 8px;
border-radius: 100px;
font-size: 11px;
}
.urgency-tab.active .count {
background: rgba(255,255,255,0.3);
}
/* ══════════════════ 테이블 ══════════════════ */ /* ══════════════════ 테이블 ══════════════════ */
.table-wrap { .table-wrap {
@ -212,7 +263,10 @@
border: 1px solid var(--border); border: 1px solid var(--border);
overflow: hidden; overflow: hidden;
} }
.data-table { width: 100%; border-collapse: collapse; } .data-table {
width: 100%;
border-collapse: collapse;
}
.data-table th { .data-table th {
padding: 14px 12px; padding: 14px 12px;
font-size: 11px; font-size: 11px;
@ -229,15 +283,38 @@
} }
.data-table th.center { text-align: center; } .data-table th.center { text-align: center; }
.data-table th.right { text-align: right; } .data-table th.right { text-align: right; }
.data-table td { padding: 12px; font-size: 13px; border-bottom: 1px solid rgba(255,255,255,0.05); vertical-align: middle; } .data-table td {
.data-table tr:hover { background: rgba(255,255,255,0.02); } padding: 12px;
.data-table tr.urgent-critical { background: rgba(244, 63, 94, 0.08); } font-size: 13px;
.data-table tr.urgent-warning { background: rgba(249, 115, 22, 0.05); } border-bottom: 1px solid rgba(255,255,255,0.05);
vertical-align: middle;
}
.data-table tr:hover {
background: rgba(255,255,255,0.02);
}
.data-table tr.urgent-critical {
background: rgba(244, 63, 94, 0.08);
}
.data-table tr.urgent-warning {
background: rgba(249, 115, 22, 0.05);
}
/* 약품 셀 */ /* 약품 셀 */
.drug-cell { display: flex; flex-direction: column; gap: 2px; } .drug-cell {
.drug-name { font-weight: 600; color: var(--text-primary); font-size: 12px; } display: flex;
.drug-code { font-family: 'JetBrains Mono', monospace; font-size: 10px; color: var(--text-muted); } flex-direction: column;
gap: 2px;
}
.drug-name {
font-weight: 600;
color: var(--text-primary);
font-size: 12px;
}
.drug-code {
font-family: 'JetBrains Mono', monospace;
font-size: 10px;
color: var(--text-muted);
}
/* 위치 셀 */ /* 위치 셀 */
.location-cell { text-align: center; } .location-cell { text-align: center; }
@ -254,13 +331,36 @@
.location-empty { color: var(--text-muted); font-size: 12px; } .location-empty { color: var(--text-muted); font-size: 12px; }
/* 긴급도 배지 */ /* 긴급도 배지 */
.urgency-badge { display: inline-flex; align-items: center; gap: 4px; padding: 4px 8px; border-radius: 6px; font-size: 10px; font-weight: 600; } .urgency-badge {
.urgency-badge.critical { background: rgba(244, 63, 94, 0.2); color: var(--accent-rose); } display: inline-flex;
.urgency-badge.warning { background: rgba(249, 115, 22, 0.2); color: var(--accent-orange); } align-items: center;
.urgency-badge.normal { background: rgba(100, 116, 139, 0.2); color: var(--text-muted); } gap: 4px;
padding: 4px 8px;
border-radius: 6px;
font-size: 10px;
font-weight: 600;
}
.urgency-badge.critical {
background: rgba(244, 63, 94, 0.2);
color: var(--accent-rose);
}
.urgency-badge.warning {
background: rgba(249, 115, 22, 0.2);
color: var(--accent-orange);
}
.urgency-badge.normal {
background: rgba(100, 116, 139, 0.2);
color: var(--text-muted);
}
/* 상태 배지 */ /* 상태 배지 */
.status-badge { display: inline-block; padding: 4px 10px; border-radius: 6px; font-size: 11px; font-weight: 600; } .status-badge {
display: inline-block;
padding: 4px 10px;
border-radius: 6px;
font-size: 11px;
font-weight: 600;
}
.status-badge.pending { background: rgba(249, 115, 22, 0.2); color: var(--accent-orange); } .status-badge.pending { background: rgba(249, 115, 22, 0.2); color: var(--accent-orange); }
.status-badge.reviewed { background: rgba(59, 130, 246, 0.2); color: var(--accent-blue); } .status-badge.reviewed { background: rgba(59, 130, 246, 0.2); color: var(--accent-blue); }
.status-badge.returned { background: rgba(16, 185, 129, 0.2); color: var(--accent-emerald); } .status-badge.returned { background: rgba(16, 185, 129, 0.2); color: var(--accent-emerald); }
@ -269,48 +369,141 @@
.status-badge.resolved { background: rgba(100, 116, 139, 0.2); color: var(--text-muted); } .status-badge.resolved { background: rgba(100, 116, 139, 0.2); color: var(--text-muted); }
/* 수량/날짜/금액 셀 */ /* 수량/날짜/금액 셀 */
.qty-cell { font-family: 'JetBrains Mono', monospace; font-weight: 600; text-align: center; font-size: 12px; } .qty-cell {
.date-cell { font-size: 11px; color: var(--text-secondary); } font-family: 'JetBrains Mono', monospace;
.months-cell { font-family: 'JetBrains Mono', monospace; font-weight: 700; font-size: 12px; } font-weight: 600;
text-align: center;
font-size: 12px;
}
.date-cell {
font-size: 11px;
color: var(--text-secondary);
}
.months-cell {
font-family: 'JetBrains Mono', monospace;
font-weight: 700;
font-size: 12px;
}
.months-cell.critical { color: var(--accent-rose); } .months-cell.critical { color: var(--accent-rose); }
.months-cell.warning { color: var(--accent-orange); } .months-cell.warning { color: var(--accent-orange); }
.months-cell.normal { color: var(--text-muted); } .months-cell.normal { color: var(--text-muted); }
.amount-cell { font-family: 'JetBrains Mono', monospace; font-weight: 600; text-align: right; font-size: 12px; color: var(--accent-gold); }
.amount-cell.zero { color: var(--text-muted); } .amount-cell {
font-family: 'JetBrains Mono', monospace;
font-weight: 600;
text-align: right;
font-size: 12px;
color: var(--accent-gold);
}
.amount-cell.zero {
color: var(--text-muted);
}
/* 액션 버튼 */ /* 액션 버튼 */
.action-btn { padding: 6px 12px; border: none; border-radius: 6px; font-size: 11px; font-weight: 600; cursor: pointer; transition: all 0.2s; } .action-btn {
.action-btn.primary { background: linear-gradient(135deg, var(--accent-orange), #ea580c); color: #fff; } padding: 6px 12px;
.action-btn.primary:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(249, 115, 22, 0.4); } border: none;
border-radius: 6px;
font-size: 11px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
}
.action-btn.primary {
background: linear-gradient(135deg, var(--accent-orange), #ea580c);
color: #fff;
}
.action-btn.primary:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(249, 115, 22, 0.4);
}
/* ══════════════════ 페이지네이션 ══════════════════ */ /* ══════════════════ 페이지네이션 ══════════════════ */
.pagination { display: flex; justify-content: center; align-items: center; gap: 8px; padding: 20px; } .pagination {
.page-btn { padding: 8px 14px; border: 1px solid var(--border); border-radius: 8px; background: var(--bg-secondary); color: var(--text-secondary); font-size: 13px; font-weight: 500; cursor: pointer; transition: all 0.2s; } display: flex;
justify-content: center;
align-items: center;
gap: 8px;
padding: 20px;
}
.page-btn {
padding: 8px 14px;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--bg-secondary);
color: var(--text-secondary);
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
}
.page-btn:hover { border-color: var(--accent-orange); color: var(--accent-orange); } .page-btn:hover { border-color: var(--accent-orange); color: var(--accent-orange); }
.page-btn.active { background: linear-gradient(135deg, var(--accent-orange), #ea580c); border-color: transparent; color: #fff; } .page-btn.active { background: linear-gradient(135deg, var(--accent-orange), #ea580c); border-color: transparent; color: #fff; }
.page-btn:disabled { opacity: 0.3; cursor: not-allowed; } .page-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.page-info { color: var(--text-muted); font-size: 13px; } .page-info { color: var(--text-muted); font-size: 13px; }
/* ══════════════════ 모달 ══════════════════ */ /* ══════════════════ 모달 ══════════════════ */
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.7); display: none; align-items: center; justify-content: center; z-index: 1000; } .modal-overlay {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.7);
display: none;
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal-overlay.open { display: flex; } .modal-overlay.open { display: flex; }
.modal { background: var(--bg-card); border-radius: 20px; padding: 28px; width: 90%; max-width: 500px; border: 1px solid var(--border); box-shadow: 0 20px 60px rgba(0,0,0,0.5); } .modal {
.modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; } background: var(--bg-card);
border-radius: 20px;
padding: 28px;
width: 90%;
max-width: 500px;
border: 1px solid var(--border);
box-shadow: 0 20px 60px rgba(0,0,0,0.5);
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24px;
}
.modal-title { font-size: 18px; font-weight: 700; } .modal-title { font-size: 18px; font-weight: 700; }
.modal-close { background: none; border: none; color: var(--text-muted); font-size: 24px; cursor: pointer; } .modal-close { background: none; border: none; color: var(--text-muted); font-size: 24px; cursor: pointer; }
.modal-body { margin-bottom: 24px; } .modal-body { margin-bottom: 24px; }
.form-group { margin-bottom: 16px; } .form-group { margin-bottom: 16px; }
.form-group label { display: block; font-size: 12px; font-weight: 600; color: var(--text-secondary); margin-bottom: 8px; } .form-group label { display: block; font-size: 12px; font-weight: 600; color: var(--text-secondary); margin-bottom: 8px; }
.form-group select, .form-group textarea { width: 100%; padding: 12px 16px; background: var(--bg-primary); border: 1px solid var(--border); border-radius: 10px; font-size: 14px; font-family: inherit; color: var(--text-primary); } .form-group select, .form-group textarea {
width: 100%;
padding: 12px 16px;
background: var(--bg-primary);
border: 1px solid var(--border);
border-radius: 10px;
font-size: 14px;
font-family: inherit;
color: var(--text-primary);
}
.form-group textarea { min-height: 100px; resize: vertical; } .form-group textarea { min-height: 100px; resize: vertical; }
.form-group select:focus, .form-group textarea:focus { outline: none; border-color: var(--accent-orange); } .form-group select:focus, .form-group textarea:focus { outline: none; border-color: var(--accent-orange); }
.modal-footer { display: flex; justify-content: flex-end; gap: 12px; } .modal-footer { display: flex; justify-content: flex-end; gap: 12px; }
.modal-btn { padding: 12px 24px; border-radius: 10px; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.2s; } .modal-btn {
padding: 12px 24px;
border-radius: 10px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
}
.modal-btn.cancel { background: var(--bg-secondary); border: 1px solid var(--border); color: var(--text-secondary); } .modal-btn.cancel { background: var(--bg-secondary); border: 1px solid var(--border); color: var(--text-secondary); }
.modal-btn.submit { background: linear-gradient(135deg, var(--accent-orange), #ea580c); border: none; color: #fff; } .modal-btn.submit { background: linear-gradient(135deg, var(--accent-orange), #ea580c); border: none; color: #fff; }
.modal-btn.submit:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(249, 115, 22, 0.4); } .modal-btn.submit:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(249, 115, 22, 0.4); }
.drug-detail { background: var(--bg-secondary); border-radius: 12px; padding: 16px; margin-bottom: 20px; } .drug-detail {
background: var(--bg-secondary);
border-radius: 12px;
padding: 16px;
margin-bottom: 20px;
}
.drug-detail-name { font-size: 16px; font-weight: 700; margin-bottom: 8px; } .drug-detail-name { font-size: 16px; font-weight: 700; margin-bottom: 8px; }
.drug-detail-info { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; font-size: 13px; } .drug-detail-info { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; font-size: 13px; }
.drug-detail-item { display: flex; justify-content: space-between; } .drug-detail-item { display: flex; justify-content: space-between; }
@ -319,45 +512,184 @@
/* ══════════════════ 로딩/빈 상태 ══════════════════ */ /* ══════════════════ 로딩/빈 상태 ══════════════════ */
.loading-state, .empty-state { text-align: center; padding: 60px 20px; color: var(--text-muted); } .loading-state, .empty-state { text-align: center; padding: 60px 20px; color: var(--text-muted); }
.loading-spinner { width: 40px; height: 40px; border: 3px solid var(--border); border-top-color: var(--accent-orange); border-radius: 50%; animation: spin 1s linear infinite; margin: 0 auto 16px; } .loading-spinner {
width: 40px; height: 40px;
border: 3px solid var(--border);
border-top-color: var(--accent-orange);
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 16px;
}
@keyframes spin { to { transform: rotate(360deg); } } @keyframes spin { to { transform: rotate(360deg); } }
.empty-icon { font-size: 48px; margin-bottom: 16px; } .empty-icon { font-size: 48px; margin-bottom: 16px; }
/* ══════════════════ 토스트 ══════════════════ */ /* ══════════════════ 토스트 ══════════════════ */
.toast { position: fixed; bottom: 32px; left: 50%; transform: translateX(-50%) translateY(20px); padding: 14px 28px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px; color: var(--text-primary); font-size: 14px; font-weight: 500; box-shadow: 0 8px 32px rgba(0,0,0,0.3); opacity: 0; transition: all 0.3s; z-index: 300; } .toast {
position: fixed;
bottom: 32px;
left: 50%;
transform: translateX(-50%) translateY(20px);
padding: 14px 28px;
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 12px;
color: var(--text-primary);
font-size: 14px;
font-weight: 500;
box-shadow: 0 8px 32px rgba(0,0,0,0.3);
opacity: 0;
transition: all 0.3s;
z-index: 300;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); } .toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.success { border-color: var(--accent-emerald); } .toast.success { border-color: var(--accent-emerald); }
.toast.error { border-color: var(--accent-rose); } .toast.error { border-color: var(--accent-rose); }
/* ══════════════════ 반응형 ══════════════════ */ /* ══════════════════ 반응형 ══════════════════ */
@media (max-width: 1200px) { .stats-row { flex-wrap: wrap; } .stat-card { min-width: calc(33% - 12px); } } @media (max-width: 1200px) {
@media (max-width: 768px) { .stat-card { min-width: calc(50% - 8px); } .header-nav { display: none; } .filter-bar { flex-direction: column; } .filter-group { width: 100%; } .filter-group select, .filter-group input { width: 100%; } .urgency-tabs { flex-wrap: wrap; } } .stats-row { flex-wrap: wrap; }
.stat-card { min-width: calc(33% - 12px); }
}
@media (max-width: 768px) {
.stat-card { min-width: calc(50% - 8px); }
.header-nav { display: none; }
.filter-bar { flex-direction: column; }
.filter-group { width: 100%; }
.filter-group select, .filter-group input { width: 100%; }
.urgency-tabs { flex-wrap: wrap; }
}
/* ══════════════════ 입고이력 모달 ══════════════════ */ /* ══════════════════ 입고이력 모달 ══════════════════ */
.purchase-modal { position: fixed; inset: 0; background: rgba(0,0,0,0.8); display: none; align-items: center; justify-content: center; z-index: 1100; backdrop-filter: blur(4px); } .purchase-modal {
position: fixed;
inset: 0;
background: rgba(0,0,0,0.8);
display: none;
align-items: center;
justify-content: center;
z-index: 1100;
backdrop-filter: blur(4px);
}
.purchase-modal.open { display: flex; } .purchase-modal.open { display: flex; }
.purchase-modal-content { background: var(--bg-card); border-radius: 20px; width: 95%; max-width: 650px; max-height: 80vh; overflow: hidden; display: flex; flex-direction: column; border: 1px solid var(--border); box-shadow: 0 20px 60px rgba(0,0,0,0.5); } .purchase-modal-content {
.purchase-modal-header { padding: 20px 24px; background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%); color: #fff; } background: var(--bg-card);
.purchase-modal-header h3 { margin: 0 0 6px 0; font-size: 18px; display: flex; align-items: center; gap: 8px; } border-radius: 20px;
.purchase-modal-header .drug-name { font-size: 14px; opacity: 0.9; } width: 95%;
.purchase-modal-body { padding: 16px 24px 24px; overflow-y: auto; flex: 1; } max-width: 650px;
.purchase-history-table { width: 100%; border-collapse: collapse; } max-height: 80vh;
.purchase-history-table th { background: var(--bg-secondary); padding: 12px 10px; font-size: 12px; font-weight: 600; color: var(--text-secondary); text-align: left; border-bottom: 2px solid var(--border); position: sticky; top: 0; } overflow: hidden;
.purchase-history-table td { padding: 14px 10px; font-size: 13px; border-bottom: 1px solid var(--border); color: var(--text-primary); } display: flex;
.purchase-history-table tr:hover td { background: var(--bg-card-hover); } flex-direction: column;
.supplier-name { font-weight: 600; color: var(--accent-cyan); } border: 1px solid var(--border);
.supplier-tel { font-size: 12px; color: var(--accent-blue); cursor: pointer; } box-shadow: 0 20px 60px rgba(0,0,0,0.5);
.supplier-tel:hover { text-decoration: underline; } }
.purchase-date { color: var(--text-secondary); font-family: 'JetBrains Mono', monospace; font-size: 12px; } .purchase-modal-header {
.purchase-qty { font-weight: 600; color: var(--accent-emerald); } padding: 20px 24px;
.purchase-price { color: var(--accent-gold); font-family: 'JetBrains Mono', monospace; } background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
.purchase-empty { text-align: center; padding: 40px 20px; color: var(--text-muted); } color: #fff;
.purchase-empty .icon { font-size: 40px; margin-bottom: 12px; } }
.purchase-modal-footer { padding: 16px 24px; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; } .purchase-modal-header h3 {
.purchase-modal-btn { padding: 10px 24px; border: none; border-radius: 8px; cursor: pointer; font-weight: 500; font-size: 14px; background: var(--bg-secondary); color: var(--text-secondary); transition: all 0.15s; } margin: 0 0 6px 0;
.purchase-modal-btn:hover { background: var(--bg-card-hover); color: var(--text-primary); } font-size: 18px;
#dataTableBody tr { cursor: pointer; } display: flex;
#dataTableBody tr:active { background: var(--bg-card-hover) !important; } align-items: center;
gap: 8px;
}
.purchase-modal-header .drug-name {
font-size: 14px;
opacity: 0.9;
}
.purchase-modal-body {
padding: 16px 24px 24px;
overflow-y: auto;
flex: 1;
}
.purchase-history-table {
width: 100%;
border-collapse: collapse;
}
.purchase-history-table th {
background: var(--bg-secondary);
padding: 12px 10px;
font-size: 12px;
font-weight: 600;
color: var(--text-secondary);
text-align: left;
border-bottom: 2px solid var(--border);
position: sticky;
top: 0;
}
.purchase-history-table td {
padding: 14px 10px;
font-size: 13px;
border-bottom: 1px solid var(--border);
color: var(--text-primary);
}
.purchase-history-table tr:hover td {
background: var(--bg-card-hover);
}
.supplier-name {
font-weight: 600;
color: var(--accent-cyan);
}
.supplier-tel {
font-size: 12px;
color: var(--accent-blue);
cursor: pointer;
}
.supplier-tel:hover {
text-decoration: underline;
}
.purchase-date {
color: var(--text-secondary);
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
}
.purchase-qty {
font-weight: 600;
color: var(--accent-emerald);
}
.purchase-price {
color: var(--accent-gold);
font-family: 'JetBrains Mono', monospace;
}
.purchase-empty {
text-align: center;
padding: 40px 20px;
color: var(--text-muted);
}
.purchase-empty .icon {
font-size: 40px;
margin-bottom: 12px;
}
.purchase-modal-footer {
padding: 16px 24px;
border-top: 1px solid var(--border);
display: flex;
justify-content: flex-end;
}
.purchase-modal-btn {
padding: 10px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
font-weight: 500;
font-size: 14px;
background: var(--bg-secondary);
color: var(--text-secondary);
transition: all 0.15s;
}
.purchase-modal-btn:hover {
background: var(--bg-card-hover);
color: var(--text-primary);
}
/* 테이블 행 더블클릭 가능 표시 */
#dataTableBody tr {
cursor: pointer;
}
#dataTableBody tr:active {
background: var(--bg-card-hover) !important;
}
</style> </style>
</head> </head>
<body> <body>
@ -413,20 +745,20 @@
<div class="stat-card gold"> <div class="stat-card gold">
<div class="stat-icon">💰</div> <div class="stat-icon">💰</div>
<div class="stat-value" id="statTotalAmount">-</div> <div class="stat-value" id="statTotalAmount">-</div>
<div class="stat-label">회수가능 금액</div> <div class="stat-label">회수가능 금액</div>
<div class="stat-sub">전체 반품 가치</div> <div class="stat-sub">전체 반품 대상</div>
</div> </div>
<div class="stat-card rose"> <div class="stat-card rose">
<div class="stat-icon">🔴💰</div> <div class="stat-icon">🔴💵</div>
<div class="stat-value small" id="statCriticalAmount">-</div> <div class="stat-value small" id="statCriticalAmount">-</div>
<div class="stat-label">3년+ 금액</div> <div class="stat-label">3년+ 금액</div>
<div class="stat-sub">긴급 처리 가치</div> <div class="stat-sub">긴급 회수 대상</div>
</div> </div>
<div class="stat-card amber"> <div class="stat-card amber">
<div class="stat-icon">🟠💰</div> <div class="stat-icon">🟠💵</div>
<div class="stat-value small" id="statWarningAmount">-</div> <div class="stat-value small" id="statWarningAmount">-</div>
<div class="stat-label">2년+ 금액</div> <div class="stat-label">2년+ 금액</div>
<div class="stat-sub">검토 가치</div> <div class="stat-sub">주의 대상</div>
</div> </div>
</div> </div>
@ -496,20 +828,20 @@
<tr> <tr>
<th style="width:4%">긴급</th> <th style="width:4%">긴급</th>
<th style="width:20%">약품</th> <th style="width:20%">약품</th>
<th class="center" style="width:6%">위치</th> <th class="center" style="width:5%">위치</th>
<th class="center" style="width:5%">현재고</th> <th class="center" style="width:5%">현재고</th>
<th class="right" style="width:7%">단가</th> <th class="right" style="width:8%">단가</th>
<th class="right" style="width:9%">회수가능금액</th> <th class="right" style="width:10%">회수가능금액</th>
<th class="center" style="width:9%">마지막 처방</th> <th class="center" style="width:10%">마지막 처방</th>
<th class="center" style="width:7%">미사용</th> <th class="center" style="width:8%">미사용</th>
<th class="center" style="width:9%">마지막 입고</th> <th class="center" style="width:10%">마지막 입고</th>
<th class="center" style="width:6%">상태</th> <th class="center" style="width:7%">상태</th>
<th style="width:9%">액션</th> <th style="width:10%">액션</th>
</tr> </tr>
</thead> </thead>
<tbody id="dataTableBody"> <tbody id="dataTableBody">
<tr> <tr>
<td colspan="11"> <td colspan="10">
<div class="loading-state"> <div class="loading-state">
<div class="loading-spinner"></div> <div class="loading-spinner"></div>
<div>데이터 로딩 중...</div> <div>데이터 로딩 중...</div>
@ -603,7 +935,7 @@
async function loadData() { async function loadData() {
const tbody = document.getElementById('dataTableBody'); const tbody = document.getElementById('dataTableBody');
tbody.innerHTML = `<tr><td colspan="11"><div class="loading-state"><div class="loading-spinner"></div><div>데이터 로딩 중...</div></div></td></tr>`; tbody.innerHTML = `<tr><td colspan="10"><div class="loading-state"><div class="loading-spinner"></div><div>데이터 로딩 중...</div></div></td></tr>`;
const status = document.getElementById('filterStatus').value; const status = document.getElementById('filterStatus').value;
const urgency = document.getElementById('filterUrgency').value; const urgency = document.getElementById('filterUrgency').value;
@ -627,10 +959,10 @@
currentPage = 1; currentPage = 1;
renderTable(); renderTable();
} else { } else {
tbody.innerHTML = `<tr><td colspan="11"><div class="empty-state"><div class="empty-icon">⚠️</div><div>오류: ${data.error}</div></div></td></tr>`; tbody.innerHTML = `<tr><td colspan="10"><div class="empty-state"><div class="empty-icon">⚠️</div><div>오류: ${data.error}</div></div></td></tr>`;
} }
} catch (err) { } catch (err) {
tbody.innerHTML = `<tr><td colspan="11"><div class="empty-state"><div class="empty-icon"></div><div>데이터 로드 실패</div></div></td></tr>`; tbody.innerHTML = `<tr><td colspan="10"><div class="empty-state"><div class="empty-icon"></div><div>데이터 로드 실패</div></div></td></tr>`;
} }
} }
@ -641,6 +973,7 @@
document.getElementById('statProcessed').textContent = stats.processed || 0; document.getElementById('statProcessed').textContent = stats.processed || 0;
document.getElementById('statTotal').textContent = stats.total || 0; document.getElementById('statTotal').textContent = stats.total || 0;
// 금액 표시
document.getElementById('statTotalAmount').textContent = formatAmount(stats.total_amount || 0); document.getElementById('statTotalAmount').textContent = formatAmount(stats.total_amount || 0);
document.getElementById('statCriticalAmount').textContent = formatAmount(stats.critical_amount || 0); document.getElementById('statCriticalAmount').textContent = formatAmount(stats.critical_amount || 0);
document.getElementById('statWarningAmount').textContent = formatAmount(stats.warning_amount || 0); document.getElementById('statWarningAmount').textContent = formatAmount(stats.warning_amount || 0);
@ -698,7 +1031,7 @@
} }
if (filteredData.length === 0) { if (filteredData.length === 0) {
tbody.innerHTML = `<tr><td colspan="11"><div class="empty-state"><div class="empty-icon">📦</div><div>해당 조건의 반품 후보가 없습니다</div></div></td></tr>`; tbody.innerHTML = `<tr><td colspan="10"><div class="empty-state"><div class="empty-icon">📦</div><div>해당 조건의 반품 후보가 없습니다</div></div></td></tr>`;
document.getElementById('pagination').innerHTML = ''; document.getElementById('pagination').innerHTML = '';
return; return;
} }
@ -953,4 +1286,4 @@
}); });
</script> </script>
</body> </body>
</html> </html>