From 4944669470b37bc7466dcddb2a1032492ce07fbf Mon Sep 17 00:00:00 2001 From: thug0bin Date: Thu, 12 Mar 2026 17:26:05 +0900 Subject: [PATCH] =?UTF-8?q?feat(pmr):=20=EB=9D=BC=EB=B2=A8=EC=97=90=20?= =?UTF-8?q?=EB=B3=B4=EA=B4=80=EC=A1=B0=EA=B1=B4=20=ED=91=9C=EC=8B=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - get_conversion_factor()에서 storage_conditions 함께 반환 - PostgreSQL 조회 결과 없으면 '실온보관' 기본값 - create_label_image()에 storage_conditions 파라미터 추가 - 용법 박스 아래, 조제일 위 여백에 보관조건 표시 - 모든 약품에 보관조건 표시 (실온보관 포함) --- backend/db/dbsetup.py | 13 +++++++++---- backend/pmr_api.py | 34 ++++++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/backend/db/dbsetup.py b/backend/db/dbsetup.py index 371a7b2..fe0b154 100644 --- a/backend/db/dbsetup.py +++ b/backend/db/dbsetup.py @@ -305,7 +305,7 @@ class DatabaseManager: def get_conversion_factor(self, sung_code): """ - 건조시럽 환산계수 조회 + 건조시럽 환산계수 및 보관조건 조회 Args: sung_code: SUNG_CODE (예: "535000ASY") @@ -314,13 +314,15 @@ class DatabaseManager: dict: { 'conversion_factor': float 또는 None, 'ingredient_name': str 또는 None, - 'product_name': str 또는 None + 'product_name': str 또는 None, + 'storage_conditions': str (기본값 '실온보관') } """ result = { 'conversion_factor': None, 'ingredient_name': None, - 'product_name': None + 'product_name': None, + 'storage_conditions': '실온보관' # 기본값 } session = self.get_postgres_session() @@ -329,7 +331,7 @@ class DatabaseManager: try: query = text(""" - SELECT conversion_factor, ingredient_name, product_name + SELECT conversion_factor, ingredient_name, product_name, storage_conditions FROM drysyrup WHERE ingredient_code = :sung_code LIMIT 1 @@ -340,6 +342,9 @@ class DatabaseManager: result['conversion_factor'] = float(row[0]) if row[0] is not None else None result['ingredient_name'] = row[1] result['product_name'] = row[2] + # storage_conditions: 값이 있으면 사용, 없으면 기본값 '실온보관' 유지 + if row[3]: + result['storage_conditions'] = row[3] except Exception as e: print(f"[DB Manager] 환산계수 조회 실패 (SUNG_CODE={sung_code}): {e}") # 세션 롤백 diff --git a/backend/pmr_api.py b/backend/pmr_api.py index 21f5fc3..c298a04 100644 --- a/backend/pmr_api.py +++ b/backend/pmr_api.py @@ -589,13 +589,15 @@ def preview_label(): unit = data.get('unit', '정') sung_code = data.get('sung_code', '') - # 환산계수 조회 (sung_code가 있는 경우) + # 환산계수 및 보관조건 조회 (sung_code가 있는 경우) conversion_factor = None + storage_conditions = '실온보관' 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') + storage_conditions = cf_result.get('storage_conditions', '실온보관') except Exception as cf_err: logging.warning(f"환산계수 조회 실패 (무시): {cf_err}") @@ -608,7 +610,8 @@ def preview_label(): frequency=frequency, duration=duration, unit=unit, - conversion_factor=conversion_factor + conversion_factor=conversion_factor, + storage_conditions=storage_conditions ) # Base64 인코딩 @@ -620,7 +623,8 @@ def preview_label(): return jsonify({ 'success': True, 'image': f'data:image/png;base64,{img_base64}', - 'conversion_factor': conversion_factor + 'conversion_factor': conversion_factor, + 'storage_conditions': storage_conditions }) except Exception as e: @@ -670,13 +674,15 @@ def print_label(): printer_ip = '192.168.0.168' printer_model = 'QL-810W' - # 환산계수 조회 + # 환산계수 및 보관조건 조회 conversion_factor = None + storage_conditions = '실온보관' 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') + storage_conditions = cf_result.get('storage_conditions', '실온보관') except Exception as cf_err: logging.warning(f"환산계수 조회 실패 (무시): {cf_err}") @@ -689,7 +695,8 @@ def print_label(): frequency=frequency, duration=duration, unit=unit, - conversion_factor=conversion_factor + conversion_factor=conversion_factor, + storage_conditions=storage_conditions ) # 2. 방향 설정 (portrait: 회전 없음, landscape: 90도 회전) @@ -802,7 +809,7 @@ def draw_scissor_border(draw, width, height, edge_size=5, steps=20): draw.line(right_points, fill="black", width=2) -def create_label_image(patient_name, med_name, add_info='', dosage=0, frequency=0, duration=0, unit='정', conversion_factor=None): +def create_label_image(patient_name, med_name, add_info='', dosage=0, frequency=0, duration=0, unit='정', conversion_factor=None, storage_conditions='실온보관'): """ 라벨 이미지 생성 (29mm 용지 기준) - 레거시 디자인 적용 @@ -810,6 +817,8 @@ def create_label_image(patient_name, med_name, add_info='', dosage=0, frequency= conversion_factor: 건조시럽 환산계수 (mL→g 변환용, 선택) - 예: 0.11이면 120ml * 0.11 = 13.2g - 총량 옆에 괄호로 표시: "총120mL (13.2g)/5일분" + storage_conditions: 보관조건 (예: '냉장보관', '실온보관') + - 용법 박스와 조제일 사이 여백에 표시 """ # 약품명 정제 (밀리그램 → mg 등) med_name = normalize_medication_name(med_name) @@ -1000,6 +1009,19 @@ def create_label_image(patient_name, med_name, add_info='', dosage=0, frequency= y = box_bottom + 10 + # 보관조건 표시 (용법 박스와 조제일 사이 여백) + if storage_conditions: + # 모든 보관조건 표시 (실온보관, 냉장보관 등) + storage_text = f"* {storage_conditions}" + try: + storage_font = ImageFont.truetype(font_path, 22) + except: + storage_font = ImageFont.load_default() + bbox_storage = draw.textbbox((0, 0), storage_text, font=storage_font) + storage_w = bbox_storage[2] - bbox_storage[0] + draw.text(((label_width - storage_w) / 2, y), storage_text, font=storage_font, fill="black") + y += 25 + # 조제일 (시그니처 위쪽에 배치) today = datetime.now().strftime('%Y-%m-%d') print_date_text = f"조제일 : {today}"