feat: 판매내역 페이지에 제품 썸네일 이미지 표시

- app.py: /api/sales-detail에서 product_images.db 조회하여 thumbnail 반환
- admin_sales_pos.html: 거래별/목록 뷰에 36x36 썸네일 표시
- 이미지 없는 제품은 📦 플레이스홀더 표시
- barcode 우선, drug_code 폴백으로 이미지 매칭
This commit is contained in:
thug0bin
2026-03-04 12:19:06 +09:00
parent 9ce7e884d7
commit fa4e87b461
6 changed files with 223 additions and 6 deletions

View File

@@ -3555,7 +3555,8 @@ def api_sales_detail():
'supplier': row.supplier or '',
'quantity': quantity,
'unit_price': int(unit_price),
'total_price': int(total_price)
'total_price': int(total_price),
'thumbnail': None # 나중에 채워짐
})
total_amount += total_price
@@ -3563,9 +3564,57 @@ def api_sales_detail():
barcode_count += 1
unique_products.add(drug_code)
# 제품 이미지 조회 (product_images.db에서)
try:
images_db_path = Path(__file__).parent / 'db' / 'product_images.db'
if images_db_path.exists():
img_conn = sqlite3.connect(str(images_db_path))
img_cursor = img_conn.cursor()
# barcode와 drug_code 수집
barcodes = [item['barcode'] for item in items if item['barcode']]
drug_codes = [item['drug_code'] for item in items if item['drug_code']]
# 이미지 조회 (barcode 또는 drug_code로 매칭)
image_map = {}
if barcodes:
placeholders = ','.join(['?' for _ in barcodes])
img_cursor.execute(f'''
SELECT barcode, thumbnail_base64
FROM product_images
WHERE barcode IN ({placeholders}) AND thumbnail_base64 IS NOT NULL
''', barcodes)
for row in img_cursor.fetchall():
image_map[f'bc:{row[0]}'] = row[1]
if drug_codes:
placeholders = ','.join(['?' for _ in drug_codes])
img_cursor.execute(f'''
SELECT drug_code, thumbnail_base64
FROM product_images
WHERE drug_code IN ({placeholders}) AND thumbnail_base64 IS NOT NULL
''', drug_codes)
for row in img_cursor.fetchall():
if f'dc:{row[0]}' not in image_map: # barcode 우선
image_map[f'dc:{row[0]}'] = row[1]
img_conn.close()
# 아이템에 썸네일 매핑
for item in items:
thumb = image_map.get(f'bc:{item["barcode"]}') or image_map.get(f'dc:{item["drug_code"]}')
if thumb:
item['thumbnail'] = thumb
except Exception as img_err:
logging.warning(f"제품 이미지 조회 오류: {img_err}")
# 바코드 매핑률 계산
barcode_rate = round(barcode_count / len(items) * 100, 1) if items else 0
# 이미지 매핑률 계산
image_count = sum(1 for item in items if item.get('thumbnail'))
image_rate = round(image_count / len(items) * 100, 1) if items else 0
return jsonify({
'success': True,
'items': items[:500], # 최대 500건
@@ -3573,6 +3622,7 @@ def api_sales_detail():
'total_count': len(items),
'total_amount': int(total_amount),
'barcode_rate': barcode_rate,
'image_rate': image_rate,
'unique_products': len(unique_products)
}
})