feat: AI 기반 제품 카테고리 자동 태깅 및 UI 표시

- OpenAI GPT-4o-mini로 31개 제품 자동 분류 (100% 커버리지)
- 관리자 페이지 사용자 상세 모달에 카테고리 뱃지 추가
- BARCODE 기반 제품-카테고리 매핑 (many-to-many)
- 카테고리별 색상 구분 (10가지 그라디언트 디자인)
- 제품 수동 분류 도구 추가 (update_product_category.py)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-23 23:56:28 +09:00
parent 6026f0aae8
commit 70d18a1954
4 changed files with 411 additions and 9 deletions

View File

@@ -352,6 +352,38 @@
display: none;
}
}
/* 카테고리 뱃지 스타일 */
.category-badge {
display: inline-block;
padding: 4px 10px;
margin: 2px 4px 2px 0;
border-radius: 12px;
font-size: 11px;
font-weight: 600;
white-space: nowrap;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #ffffff;
box-shadow: 0 2px 4px rgba(102, 126, 234, 0.3);
transition: all 0.2s ease;
}
.category-badge:hover {
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(102, 126, 234, 0.4);
}
/* 제품 카테고리별 색상 */
.category-badge.cat-진통제 { background: linear-gradient(135deg, #f06292 0%, #e91e63 100%); }
.category-badge.cat-소화제 { background: linear-gradient(135deg, #64b5f6 0%, #1976d2 100%); }
.category-badge.cat-감기약 { background: linear-gradient(135deg, #4db6ac 0%, #00796b 100%); }
.category-badge.cat-복합비타민 { background: linear-gradient(135deg, #ffb74d 0%, #f57c00 100%); }
.category-badge.cat-피로회복제 { background: linear-gradient(135deg, #a1887f 0%, #6d4c41 100%); }
.category-badge.cat-소염제 { background: linear-gradient(135deg, #ff8a65 0%, #d84315 100%); }
.category-badge.cat-연고 { background: linear-gradient(135deg, #90a4ae 0%, #546e7a 100%); }
.category-badge.cat-파스 { background: linear-gradient(135deg, #81c784 0%, #388e3c 100%); }
.category-badge.cat-간영양제 { background: linear-gradient(135deg, #ba68c8 0%, #8e24aa 100%); }
.category-badge.cat-위장약 { background: linear-gradient(135deg, #4fc3f7 0%, #0288d1 100%); }
</style>
</head>
<body>
@@ -960,10 +992,21 @@
`;
purchase.items.forEach(item => {
// 카테고리 뱃지 생성
let categoriesBadges = '';
if (item.categories && item.categories.length > 0) {
item.categories.forEach(cat => {
categoriesBadges += `<span class="category-badge cat-${cat.name}">${cat.name}</span>`;
});
}
html += `
<tr style="border-bottom: 1px solid #f1f3f5;">
<td style="padding: 10px; font-size: 13px; color: #495057;">${item.code}</td>
<td style="padding: 10px; font-size: 13px; color: #212529; font-weight: 500;">${item.name}</td>
<td style="padding: 10px; font-size: 13px; color: #212529; font-weight: 500;">
<div style="margin-bottom: 4px;">${item.name}</div>
${categoriesBadges ? `<div style="margin-top: 6px;">${categoriesBadges}</div>` : ''}
</td>
<td style="padding: 10px; text-align: right; font-size: 13px; color: #495057;">${item.qty}</td>
<td style="padding: 10px; text-align: right; font-size: 13px; color: #495057;">${item.price.toLocaleString()}원</td>
<td style="padding: 10px; text-align: right; font-size: 13px; color: #6366f1; font-weight: 600;">${item.total.toLocaleString()}원</td>