From cb7450f6540865d1a808ade04b7996c899191a82 Mon Sep 17 00:00:00 2001 From: thug0bin Date: Sat, 14 Mar 2026 00:18:58 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20OTC=20=EB=9D=BC=EB=B2=A8=20=EB=B0=94?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=EC=87=84=20API=20=EC=B6=94=EA=B0=80=20(CO?= =?UTF-8?q?RS=20=EC=A7=80=EC=9B=90)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - GET /api/otc-label-print/{barcode} - 바로 인쇄 - 프리셋 있으면 해당 데이터로, 없으면 약품명만으로 인쇄 - 인쇄 횟수 자동 카운트 --- backend/app.py | 130 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/backend/app.py b/backend/app.py index 401bc44..c0141c6 100644 --- a/backend/app.py +++ b/backend/app.py @@ -7846,6 +7846,136 @@ def api_print_otc_label(): return jsonify({'success': False, 'error': str(e)}), 500 +# ═══════════════════════════════════════════════════════════════════════════════ +# OTC 라벨 바로 인쇄 API (GET - URL로 바로 인쇄) - 외부 CORS 지원 +# ═══════════════════════════════════════════════════════════════════════════════ + +@app.route('/api/otc-label-print/') +def api_otc_label_print_by_barcode(barcode): + """ + OTC 라벨 바로 인쇄 (GET 방식) + GET /api/otc-label-print/8806436044814 + + - CORS 지원 (외부에서 호출 가능) + - 저장된 프리셋이 있으면 해당 데이터로 인쇄 + - 프리셋이 없으면 MSSQL에서 약품명 조회 후 기본 라벨 인쇄 + """ + try: + if not OTC_LABEL_AVAILABLE: + response = jsonify({'success': False, 'error': 'OTC 라벨 모듈이 로드되지 않았습니다.'}) + response.headers['Access-Control-Allow-Origin'] = '*' + return response, 500 + + # 1. 프리셋 조회 + conn = db_manager.get_sqlite_connection() + cursor = conn.cursor() + + cursor.execute(""" + SELECT display_name, effect, dosage_instruction, usage_tip + FROM otc_label_presets + WHERE barcode = ? + """, (barcode,)) + + preset = cursor.fetchone() + + if preset: + # 프리셋 있음 → 프리셋 데이터로 인쇄 + drug_name = preset['display_name'] + effect = preset['effect'] or '' + dosage_instruction = preset['dosage_instruction'] or '' + usage_tip = preset['usage_tip'] or '' + else: + # 프리셋 없음 → MSSQL에서 약품명 조회 + try: + import pyodbc + mssql_conn = pyodbc.connect( + 'DRIVER={ODBC Driver 17 for SQL Server};' + 'SERVER=192.168.0.4\\PM2014;' + 'DATABASE=PM_DRUG;' + 'UID=sa;' + 'PWD=tmddls214!%(;' + 'TrustServerCertificate=yes', + timeout=10 + ) + mssql_cursor = mssql_conn.cursor() + + mssql_cursor.execute(""" + SELECT TOP 1 G.GoodsName + FROM CD_GOODS G + LEFT JOIN CD_ITEM_UNIT_MEMBER U ON G.DrugCode = U.DRUGCODE + WHERE G.BARCODE = ? OR U.CD_CD_BARCODE = ? + """, (barcode, barcode)) + + row = mssql_cursor.fetchone() + mssql_conn.close() + + if row: + drug_name = row.GoodsName + else: + response = jsonify({ + 'success': False, + 'error': f'바코드 {barcode}에 해당하는 제품을 찾을 수 없습니다. 프리셋을 먼저 등록해주세요.' + }) + response.headers['Access-Control-Allow-Origin'] = '*' + return response, 404 + + except Exception as e: + logging.error(f"MSSQL 조회 오류: {e}") + response = jsonify({'success': False, 'error': f'DB 조회 오류: {str(e)}'}) + response.headers['Access-Control-Allow-Origin'] = '*' + return response, 500 + + # 기본값으로 인쇄 (효능/용법 없음) + effect = '' + dosage_instruction = '' + usage_tip = '' + + # 2. 인쇄 실행 + success = print_otc_label(drug_name, effect, dosage_instruction, usage_tip) + + if success: + # 인쇄 횟수 업데이트 (프리셋 있는 경우) + if preset: + cursor.execute(""" + UPDATE otc_label_presets + SET print_count = print_count + 1, last_printed_at = CURRENT_TIMESTAMP + WHERE barcode = ? + """, (barcode,)) + conn.commit() + + response = jsonify({ + 'success': True, + 'message': f'OTC 라벨 인쇄 완료: {drug_name}', + 'barcode': barcode, + 'drug_name': drug_name, + 'has_preset': preset is not None + }) + response.headers['Access-Control-Allow-Origin'] = '*' + return response + else: + response = jsonify({'success': False, 'error': '프린터 전송 실패'}) + response.headers['Access-Control-Allow-Origin'] = '*' + return response, 500 + + except Exception as e: + logging.error(f"OTC 라벨 GET 인쇄 오류: {e}") + import traceback + traceback.print_exc() + response = jsonify({'success': False, 'error': str(e)}) + response.headers['Access-Control-Allow-Origin'] = '*' + return response, 500 + + +@app.route('/api/otc-label-print/', methods=['OPTIONS']) +def api_otc_label_print_options(barcode): + """CORS preflight 요청 처리""" + response = make_response() + response.headers['Access-Control-Allow-Origin'] = '*' + response.headers['Access-Control-Allow-Methods'] = 'GET, OPTIONS' + response.headers['Access-Control-Allow-Headers'] = 'Content-Type' + return response + + @app.route('/api/admin/otc-labels/search-mssql', methods=['GET']) def api_search_mssql_drug(): """MSSQL에서 약품 검색 (바코드 또는 이름)"""