feat(purchase): 카테고리 테이블 분리 + 동적 로드 + tkuser 관리
- DB: consumable_categories 테이블 생성, ENUM→VARCHAR 변환, 시드 4개 - API: GET/POST/PUT/DEACTIVATE /api/consumable-categories - 프론트: 3개 JS 하드코딩 CAT_LABELS 제거 → API loadCategories() 동적 로드 - tkuser: 카테고리 관리 섹션 추가, select 옵션 동적 생성 - 별칭 시드 SQL (INSERT IGNORE 기반) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,14 @@ const TKUSER_BASE_URL = location.hostname.includes('technicalkorea.net')
|
||||
? 'https://tkuser.technicalkorea.net'
|
||||
: location.protocol + '//' + location.hostname + ':30180';
|
||||
|
||||
const CAT_LABELS = { consumable: '소모품', safety: '안전용품', repair: '수선비', equipment: '설비' };
|
||||
// 카테고리 — API 동적 로드
|
||||
let _categories = null;
|
||||
async function loadCategories() {
|
||||
if (_categories) return _categories;
|
||||
try { const r = await api('/consumable-categories'); _categories = r.data || []; } catch(e) { _categories = []; }
|
||||
return _categories;
|
||||
}
|
||||
function getCatLabel(code) { return (_categories || []).find(c => c.category_code === code)?.category_name || code || ''; }
|
||||
const STATUS_LABELS = { pending: '대기', grouped: '구매진행중', purchased: '구매완료', received: '입고완료', cancelled: '취소', returned: '반품', hold: '보류' };
|
||||
const STATUS_COLORS = { pending: 'badge-amber', grouped: 'badge-blue', purchased: 'badge-green', received: 'badge-teal', cancelled: 'badge-red', returned: 'badge-red', hold: 'badge-gray' };
|
||||
const MATCH_LABELS = { exact: '정확', name: '이름', alias: '별칭', spec: '규격', chosung: '초성', chosung_alias: '초성' };
|
||||
@@ -55,7 +62,7 @@ function renderCards() {
|
||||
container.innerHTML = requestsList.map(r => {
|
||||
const itemName = r.item_name || r.custom_item_name || '-';
|
||||
const category = r.category || r.custom_category;
|
||||
const catLabel = CAT_LABELS[category] || category || '';
|
||||
const catLabel = getCatLabel(category);
|
||||
const statusLabel = STATUS_LABELS[r.status] || r.status;
|
||||
const statusColor = STATUS_COLORS[r.status] || 'badge-gray';
|
||||
const isCustom = !r.item_id && r.custom_item_name;
|
||||
@@ -96,7 +103,7 @@ function openDetail(requestId) {
|
||||
if (!r) return;
|
||||
const itemName = r.item_name || r.custom_item_name || '-';
|
||||
const category = r.category || r.custom_category;
|
||||
const catLabel = CAT_LABELS[category] || category || '-';
|
||||
const catLabel = getCatLabel(category);
|
||||
const statusLabel = STATUS_LABELS[r.status] || r.status;
|
||||
const statusColor = STATUS_COLORS[r.status] || 'badge-gray';
|
||||
|
||||
@@ -182,7 +189,7 @@ function renderSearchResults(items, query) {
|
||||
const container = document.getElementById('searchResults');
|
||||
let html = '';
|
||||
items.forEach(item => {
|
||||
const catLabel = CAT_LABELS[item.category] || '';
|
||||
const catLabel = getCatLabel(item.category);
|
||||
const matchLabel = MATCH_LABELS[item._matchType] || '';
|
||||
const spec = item.spec ? ' [' + escapeHtml(item.spec) + ']' : '';
|
||||
const maker = item.maker ? ' (' + escapeHtml(item.maker) + ')' : '';
|
||||
@@ -288,7 +295,7 @@ function renderCart() {
|
||||
list.innerHTML = cartItems.map((c, idx) => {
|
||||
const spec = c.spec ? ' [' + escapeHtml(c.spec) + ']' : '';
|
||||
const maker = c.maker ? ' (' + escapeHtml(c.maker) + ')' : '';
|
||||
const catLabel = CAT_LABELS[c.category] || '';
|
||||
const catLabel = getCatLabel(c.category);
|
||||
|
||||
// 사진 썸네일
|
||||
let thumbHtml = '';
|
||||
@@ -478,6 +485,7 @@ function checkViewParam() {
|
||||
/* ===== Init ===== */
|
||||
(async function() {
|
||||
if (!await initAuth()) return;
|
||||
await loadCategories();
|
||||
await loadRequests();
|
||||
checkViewParam();
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user