feat(pmr): 라벨 인쇄 기능 구현 및 환산계수 개선

- Brother QL 라벨 인쇄 API 추가 (POST /pmr/api/label/print)
- PMR 라벨 인쇄 버튼 동작 구현 (QL-810W)
- 환산계수 sung_code 프론트→백엔드 전달 추가
- 환산계수 모달 제품명 readonly 처리 (MSSQL 원본 보호)
- Pillow 10+ 호환성 패치 (ANTIALIAS → LANCZOS)
This commit is contained in:
thug0bin
2026-03-12 13:41:16 +09:00
parent 98d370104b
commit 17a29f05b8
2 changed files with 168 additions and 7 deletions

View File

@@ -36,6 +36,10 @@ from pathlib import Path
from datetime import datetime, date
import logging
from PIL import Image, ImageDraw, ImageFont
# Pillow 10+ 호환성 패치 (brother_ql용)
if not hasattr(Image, 'ANTIALIAS'):
Image.ANTIALIAS = Image.Resampling.LANCZOS
import io
import base64
import os
@@ -624,6 +628,101 @@ def preview_label():
return jsonify({'success': False, 'error': str(e)}), 500
# API: 라벨 인쇄 (Brother QL 프린터)
# ─────────────────────────────────────────────────────────────
@pmr_bp.route('/api/label/print', methods=['POST'])
def print_label():
"""
라벨 인쇄 (PIL 렌더링 → Brother QL 프린터 전송)
Request Body:
- patient_name, med_name, dosage, frequency, duration, unit, sung_code
- printer: 프린터 선택 (선택, 기본값 '168')
- '121': QL-710W (192.168.0.121)
- '168': QL-810W (192.168.0.168)
"""
try:
from brother_ql.raster import BrotherQLRaster
from brother_ql.conversion import convert
from brother_ql.backends.helpers import send
data = request.get_json()
patient_name = data.get('patient_name', '')
med_name = data.get('med_name', '')
add_info = data.get('add_info', '')
dosage = float(data.get('dosage', 0))
frequency = int(data.get('frequency', 0))
duration = int(data.get('duration', 0))
unit = data.get('unit', '')
sung_code = data.get('sung_code', '')
printer = data.get('printer', '168') # 기본값: QL-810W
# 프린터 설정
if printer == '121':
printer_ip = '192.168.0.121'
printer_model = 'QL-710W'
else:
printer_ip = '192.168.0.168'
printer_model = 'QL-810W'
# 환산계수 조회
conversion_factor = None
if sung_code:
try:
from db.dbsetup import db_manager
cf_result = db_manager.get_conversion_factor(sung_code)
conversion_factor = cf_result.get('conversion_factor')
except Exception as cf_err:
logging.warning(f"환산계수 조회 실패 (무시): {cf_err}")
# 1. 라벨 이미지 생성
label_image = create_label_image(
patient_name=patient_name,
med_name=med_name,
add_info=add_info,
dosage=dosage,
frequency=frequency,
duration=duration,
unit=unit,
conversion_factor=conversion_factor
)
# 2. 이미지 90도 회전 (Brother QL이 세로 방향 기준이므로)
label_rotated = label_image.rotate(90, expand=True)
# 3. Brother QL 프린터로 전송
qlr = BrotherQLRaster(printer_model)
instructions = convert(
qlr=qlr,
images=[label_rotated],
label='29',
rotate='0',
threshold=70.0,
dither=False,
compress=False,
red=False,
dpi_600=False,
hq=True,
cut=True
)
send(instructions, printer_identifier=f"tcp://{printer_ip}:9100")
logging.info(f"[SUCCESS] PMR 라벨 인쇄 성공: {med_name}{printer_model}")
return jsonify({
'success': True,
'message': f'{med_name} 라벨 인쇄 완료 ({printer_model})',
'printer': printer_model
})
except ImportError as e:
logging.error(f"brother_ql 라이브러리 없음: {e}")
return jsonify({'success': False, 'error': 'brother_ql 라이브러리가 설치되지 않았습니다'}), 500
except Exception as e:
logging.error(f"라벨 인쇄 오류: {e}")
return jsonify({'success': False, 'error': str(e)}), 500
def normalize_medication_name(med_name):
"""
약품명 정제 - 밀리그램 등을 mg로 변환, 불필요한 부분 제거