feat: 전화접수 관리에 [개발용 임시] 스캔 가능 바코드 후보 표 추가
지정판매소 판매의 dev-saleable-barcodes API를 재사용해, 주문 선택 시 그 판매소·주문 기준의 판매 테스트용 바코드 후보를 표로 표시한다. 바코드를 클릭하면 봉투코드 스캔칸에 자동 입력되어 테스트가 쉬워진다. 스캔 성공 시 후보 목록도 갱신(판매된 팩 제외). 개발 완료 후 제거 예정.
This commit is contained in:
@@ -114,6 +114,31 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- [개발용 임시] 선택 주문 판매소 기준 스캔 가능 바코드 후보 (개발 완료 후 이 블록 제거) -->
|
||||||
|
<div id="dev-saleable-panel" class="mt-2 hidden border border-amber-400 bg-amber-50/50 p-2 rounded-sm">
|
||||||
|
<p class="text-[11px] text-amber-900 mb-1 leading-relaxed">
|
||||||
|
<strong class="text-amber-950">[개발용 임시]</strong> 선택 주문의 판매소 기준 판매 테스트용 바코드 후보. <strong>바코드를 클릭하면 위 스캔칸에 입력</strong>됩니다. 개발 완료 후 이 블록과 API를 제거하세요.
|
||||||
|
</p>
|
||||||
|
<div class="max-h-52 overflow-auto border border-amber-300 bg-white">
|
||||||
|
<table class="w-full data-table text-xs">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="w-28 text-left">출처</th>
|
||||||
|
<th class="w-44 text-center">바코드(대표)</th>
|
||||||
|
<th class="text-left">봉투 종류</th>
|
||||||
|
<th class="w-20 text-center">포장</th>
|
||||||
|
<th class="w-12 text-right">수량</th>
|
||||||
|
<th class="w-14 text-center">상태</th>
|
||||||
|
<th class="text-left">비고(낱장범위 등)</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="dev-saleable-tbody">
|
||||||
|
<tr><td colspan="7" class="text-center text-gray-400 py-4">주문을 선택하면 목록이 표시됩니다.</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mt-3">
|
<div class="mt-3">
|
||||||
<div class="flex items-center justify-between px-1 mb-1 text-sm">
|
<div class="flex items-center justify-between px-1 mb-1 text-sm">
|
||||||
<span class="font-semibold text-gray-700">포장 명세</span>
|
<span class="font-semibold text-gray-700">포장 명세</span>
|
||||||
@@ -153,6 +178,8 @@
|
|||||||
// 봉투코드 스캔(판매/포장) — CSRF 토큰(쿠키 방식, 매 요청 갱신)
|
// 봉투코드 스캔(판매/포장) — CSRF 토큰(쿠키 방식, 매 요청 갱신)
|
||||||
// base_url() 절대경로를 현재 문서(동일 출처) 기준 경로로 변환 → 워크스페이스 iframe/다른 호스트 접근에도 안전
|
// base_url() 절대경로를 현재 문서(동일 출처) 기준 경로로 변환 → 워크스페이스 iframe/다른 호스트 접근에도 안전
|
||||||
const scanApi = new URL('<?= base_url('bag/order/phone/manage/scan') ?>', window.location.href).pathname;
|
const scanApi = new URL('<?= base_url('bag/order/phone/manage/scan') ?>', window.location.href).pathname;
|
||||||
|
// [개발용 임시] 판매 가능 바코드 후보 API (지정판매소 판매의 dev API 재사용)
|
||||||
|
const devSaleableApi = new URL('<?= base_url('bag/sale/designated/dev-saleable-barcodes') ?>', window.location.href).pathname;
|
||||||
const csrfName = '<?= csrf_token() ?>';
|
const csrfName = '<?= csrf_token() ?>';
|
||||||
let csrfHash = '<?= csrf_hash() ?>';
|
let csrfHash = '<?= csrf_hash() ?>';
|
||||||
|
|
||||||
@@ -319,10 +346,56 @@
|
|||||||
const msg = document.getElementById('scan-msg');
|
const msg = document.getElementById('scan-msg');
|
||||||
if (msg) msg.textContent = '';
|
if (msg) msg.textContent = '';
|
||||||
}
|
}
|
||||||
|
// [개발용 임시] 선택 주문 판매소 기준 후보 바코드 표
|
||||||
|
loadDevSaleable(order.so_ds_idx, order.so_idx);
|
||||||
|
|
||||||
syncListHeight(); // 상세 카드 높이 확정 후 접수 리스트 높이를 맞춘다
|
syncListHeight(); // 상세 카드 높이 확정 후 접수 리스트 높이를 맞춘다
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [개발용 임시] 스캔 가능 바코드 후보 로딩(선택 주문 판매소·주문 기준)
|
||||||
|
const devPanelEl = document.getElementById('dev-saleable-panel');
|
||||||
|
const devTbodyEl = document.getElementById('dev-saleable-tbody');
|
||||||
|
async function loadDevSaleable(dsIdx, soIdx) {
|
||||||
|
if (!devPanelEl || !devTbodyEl) return;
|
||||||
|
const idx = Number(dsIdx || 0);
|
||||||
|
if (!idx) { devPanelEl.classList.add('hidden'); return; }
|
||||||
|
devPanelEl.classList.remove('hidden');
|
||||||
|
devTbodyEl.innerHTML = '<tr><td colspan="7" class="text-center text-gray-400 py-4">불러오는 중…</td></tr>';
|
||||||
|
try {
|
||||||
|
let url = devSaleableApi + '?ds_idx=' + encodeURIComponent(String(idx));
|
||||||
|
if (Number(soIdx || 0) > 0) url += '&so_idx=' + encodeURIComponent(String(soIdx));
|
||||||
|
const res = await fetch(url, { credentials: 'same-origin' });
|
||||||
|
const data = await res.json();
|
||||||
|
if (!data.ok) { devTbodyEl.innerHTML = '<tr><td colspan="7" class="text-center text-red-600 py-4">' + esc(data.message || '조회 실패') + '</td></tr>'; return; }
|
||||||
|
const rows = Array.isArray(data.rows) ? data.rows : [];
|
||||||
|
if (!rows.length) { devTbodyEl.innerHTML = '<tr><td colspan="7" class="text-center text-gray-400 py-4">표시할 바코드가 없습니다.</td></tr>'; return; }
|
||||||
|
devTbodyEl.innerHTML = rows.map((r) => {
|
||||||
|
const code = String(r.code || '');
|
||||||
|
const codeCell = (code && code !== '-')
|
||||||
|
? '<button type="button" class="dev-pick text-blue-600 hover:underline font-mono" data-code="' + esc(code) + '">' + esc(code) + '</button>'
|
||||||
|
: '<span class="text-gray-400">' + esc(code) + '</span>';
|
||||||
|
return '<tr>'
|
||||||
|
+ '<td class="text-left pl-1">' + esc(r.source || '') + '</td>'
|
||||||
|
+ '<td class="text-center">' + codeCell + '</td>'
|
||||||
|
+ '<td class="text-left pl-1">' + esc((r.bag_code || '') + ' ' + (r.bag_name || '')) + '</td>'
|
||||||
|
+ '<td class="text-center">' + esc(r.unit || '') + '</td>'
|
||||||
|
+ '<td class="text-right pr-1">' + nf(r.qty || 0) + '</td>'
|
||||||
|
+ '<td class="text-center">' + esc(r.state || '') + '</td>'
|
||||||
|
+ '<td class="text-left pl-1">' + esc(r.extra || '') + '</td>'
|
||||||
|
+ '</tr>';
|
||||||
|
}).join('');
|
||||||
|
} catch (e) {
|
||||||
|
devTbodyEl.innerHTML = '<tr><td colspan="7" class="text-center text-red-600 py-4">네트워크 오류</td></tr>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 후보 바코드 클릭 → 스캔칸에 입력(개발 편의)
|
||||||
|
devTbodyEl?.addEventListener('click', (e) => {
|
||||||
|
const btn = e.target.closest('.dev-pick');
|
||||||
|
if (!btn) return;
|
||||||
|
const inp = document.getElementById('scan-input');
|
||||||
|
if (inp && !inp.disabled) { inp.value = btn.getAttribute('data-code') || ''; inp.focus(); }
|
||||||
|
});
|
||||||
|
|
||||||
// 봉투코드 스캔 → 즉시 판매·포장 처리 후 화면 갱신
|
// 봉투코드 스캔 → 즉시 판매·포장 처리 후 화면 갱신
|
||||||
const scanInputEl = document.getElementById('scan-input');
|
const scanInputEl = document.getElementById('scan-input');
|
||||||
const scanMsgEl = document.getElementById('scan-msg');
|
const scanMsgEl = document.getElementById('scan-msg');
|
||||||
@@ -386,6 +459,8 @@
|
|||||||
}
|
}
|
||||||
// 접수 리스트의 '포장' 표시(O/X) 갱신
|
// 접수 리스트의 '포장' 표시(O/X) 갱신
|
||||||
renderList();
|
renderList();
|
||||||
|
// [개발용 임시] 후보 목록 갱신(방금 판매된 팩 제외)
|
||||||
|
loadDevSaleable(order.so_ds_idx, order.so_idx);
|
||||||
}
|
}
|
||||||
scanInputEl.value = '';
|
scanInputEl.value = '';
|
||||||
scanInputEl.focus();
|
scanInputEl.focus();
|
||||||
|
|||||||
Reference in New Issue
Block a user