fix(purchase): 네비 명칭/권한 수정 + 검색 재선택 가능하도록 개선

- 네비: '소모품 관리' → '소모품 구매 관리'(admin only), 일반 사용자는 '소모품 신청'만 표시
- 권한: purchase.request_mobile → purchase.request alias 등록 (비관리자 접근 가능)
- 검색: 품목 선택 후 다시 입력하면 이전 선택 자동 해제 (데스크탑+모바일)
- 모바일: selectSearchItem에서 불필요한 API 재호출 제거, 로컬 캐시 활용

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-04-01 09:50:15 +09:00
parent 798cc38945
commit dcd40e692f
5 changed files with 37 additions and 23 deletions

View File

@@ -6,8 +6,8 @@
<title>소모품 신청 - TK 공장관리</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="/static/css/tkfb.css?v=2026040101">
<link rel="stylesheet" href="/css/purchase-mobile.css?v=2026040101">
<link rel="stylesheet" href="/static/css/tkfb.css?v=2026040102">
<link rel="stylesheet" href="/css/purchase-mobile.css?v=2026040102">
<script src="https://cdn.jsdelivr.net/npm/heic2any@0.0.4/dist/heic2any.min.js"></script>
</head>
<body class="bg-gray-50">
@@ -140,8 +140,8 @@
<div class="pm-sheet-body" id="detailContent"></div>
</div>
<script src="/static/js/tkfb-core.js?v=2026040101"></script>
<script src="/static/js/purchase-request-mobile.js?v=2026040101"></script>
<script src="/static/js/shared-bottom-nav.js?v=2026040101"></script>
<script src="/static/js/tkfb-core.js?v=2026040102"></script>
<script src="/static/js/purchase-request-mobile.js?v=2026040102"></script>
<script src="/static/js/shared-bottom-nav.js?v=2026040102"></script>
</body>
</html>

View File

@@ -310,7 +310,7 @@
</div>
</div>
</div>
<script src="/static/js/tkfb-core.js?v=2026040101"></script>
<script src="/static/js/purchase-request.js?v=2026040101"></script>
<script src="/static/js/tkfb-core.js?v=2026040102"></script>
<script src="/static/js/purchase-request.js?v=2026040102"></script>
</body>
</html>

View File

@@ -191,6 +191,14 @@ document.addEventListener('DOMContentLoaded', () => {
const input = document.getElementById('searchInput');
input.addEventListener('input', () => {
clearTimeout(searchTimer);
// 검색어 입력 시 이전 선택 자동 해제
if (document.getElementById('selectedItemId').value || document.getElementById('selectedCustomName').value) {
document.getElementById('selectedItemWrap').classList.add('hidden');
document.getElementById('selectedItemId').value = '';
document.getElementById('selectedCustomName').value = '';
document.getElementById('newItemForm').classList.add('hidden');
isRegisterMode = false;
}
const q = input.value.trim();
if (q.length === 0) {
document.getElementById('searchResults').classList.remove('open');
@@ -212,6 +220,7 @@ document.addEventListener('DOMContentLoaded', () => {
});
function renderSearchResults(items, query) {
lastSearchResults = items;
const container = document.getElementById('searchResults');
let html = '';
@@ -240,23 +249,20 @@ function renderSearchResults(items, query) {
}
/* ===== 품목 선택 ===== */
let searchItemsCache = [];
let lastSearchResults = [];
function selectSearchItem(itemId) {
// API 검색 결과에서 선택 — searchResults에서 데이터 가져오기
api('/purchase-requests/search?q=' + encodeURIComponent(document.getElementById('searchInput').value.trim()))
.then(res => {
const item = (res.data || []).find(i => i.item_id === itemId);
if (!item) return;
document.getElementById('selectedItemId').value = item.item_id;
document.getElementById('selectedCustomName').value = '';
document.getElementById('selectedItemName').textContent = item.item_name + (item.spec ? ' [' + item.spec + ']' : '') + (item.maker ? ' (' + item.maker + ')' : '');
document.getElementById('selectedItemMeta').textContent = (CAT_LABELS[item.category] || '') + (item.base_price ? ' · ' + Number(item.base_price).toLocaleString() + '원' : '');
document.getElementById('selectedItemWrap').classList.remove('hidden');
document.getElementById('searchResults').classList.remove('open');
document.getElementById('newItemForm').classList.add('hidden');
isRegisterMode = false;
});
const item = lastSearchResults.find(i => i.item_id === itemId);
if (!item) return;
document.getElementById('selectedItemId').value = item.item_id;
document.getElementById('selectedCustomName').value = '';
document.getElementById('selectedItemName').textContent = item.item_name + (item.spec ? ' [' + item.spec + ']' : '') + (item.maker ? ' (' + item.maker + ')' : '');
document.getElementById('selectedItemMeta').textContent = (CAT_LABELS[item.category] || '') + (item.base_price ? ' · ' + Number(item.base_price).toLocaleString() + '원' : '');
document.getElementById('selectedItemWrap').classList.remove('hidden');
document.getElementById('searchResults').classList.remove('open');
document.getElementById('searchInput').value = '';
document.getElementById('newItemForm').classList.add('hidden');
isRegisterMode = false;
}
function selectNewItem() {

View File

@@ -51,6 +51,13 @@ function initItemSearch() {
input.addEventListener('input', () => {
clearTimeout(searchDebounceTimer);
// 검색어 변경 시 이전 선택 자동 해제
if (document.getElementById('prItemId').value) {
document.getElementById('prItemId').value = '';
document.getElementById('prCustomItemName').value = '';
document.getElementById('prItemPreview').classList.add('hidden');
document.getElementById('prCustomCategoryWrap').classList.add('hidden');
}
searchDebounceTimer = setTimeout(() => {
const query = input.value.trim();
if (query.length === 0) {

View File

@@ -134,7 +134,7 @@ const NAV_MENU = [
]},
{ cat: '소모품 관리', items: [
{ href: '/pages/purchase/request-mobile.html', icon: 'fa-shopping-cart', label: '소모품 신청', key: 'purchase.request_mobile' },
{ href: '/pages/purchase/request.html', icon: 'fa-clipboard-list', label: '소모품 관리', key: 'purchase.request' },
{ href: '/pages/purchase/request.html', icon: 'fa-clipboard-list', label: '소모품 구매 관리', key: 'purchase.request', admin: true },
{ href: '/pages/admin/purchase-analysis.html', icon: 'fa-chart-line', label: '소모품 분석', key: 'purchase.analysis', admin: true },
]},
{ cat: '근태 관리', items: [
@@ -170,6 +170,7 @@ const PAGE_KEY_ALIASES = {
'attendance.work_status': 'inspection.work_status',
'work.meeting_detail': 'work.meetings',
'work.proxy_input': 'work.daily_status',
'purchase.request_mobile': 'purchase.request',
};
function _getCurrentPageKey() {