From ddba17ae08039b4f1a4ef49ea6b8805d5aeb389d Mon Sep 17 00:00:00 2001 From: thug0bin Date: Fri, 6 Mar 2026 13:41:39 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=B2=98=EB=B0=A9=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EB=9F=89=20=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90=20=EC=95=BD?= =?UTF-8?q?=ED=92=88=20=EC=9C=84=EC=B9=98=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - rx-usage API에 CD_item_position.CD_NM_sale 조인 추가 - 제품코드 옆에 위치 배지 표시 (📍A-1 형태) - 인디고 색상 작은 배지로 UI 해치지 않게 --- backend/app.py | 9 ++++++--- backend/baekje_api.py | 27 +++++++++++++++++++++++++++ backend/templates/admin_rx_usage.html | 13 ++++++++++++- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/backend/app.py b/backend/app.py index bd29ab6..e94084a 100644 --- a/backend/app.py +++ b/backend/app.py @@ -4085,7 +4085,7 @@ def api_rx_usage(): mssql_session = db_manager.get_session('PM_PRES') - # 전문의약품 품목별 사용량 집계 쿼리 (현재고: IM_total.IM_QT_sale_debit) + # 전문의약품 품목별 사용량 집계 쿼리 (현재고: IM_total.IM_QT_sale_debit, 위치: CD_item_position.CD_NM_sale) rx_query = text(""" SELECT P.DrugCode as drug_code, @@ -4096,13 +4096,15 @@ def api_rx_usage(): SUM(ISNULL(P.DRUPRICE, 0) * ISNULL(P.QUAN, 1) * ISNULL(P.Days, 1)) as total_amount, COUNT(DISTINCT P.PreSerial) as prescription_count, COALESCE(NULLIF(G.BARCODE, ''), '') as barcode, - ISNULL(IT.IM_QT_sale_debit, 0) as current_stock + ISNULL(IT.IM_QT_sale_debit, 0) as current_stock, + ISNULL(POS.CD_NM_sale, '') as location FROM PS_sub_pharm P LEFT JOIN PM_DRUG.dbo.CD_GOODS G ON P.DrugCode = G.DrugCode LEFT JOIN PM_DRUG.dbo.IM_total IT ON P.DrugCode = IT.DrugCode + LEFT JOIN PM_DRUG.dbo.CD_item_position POS ON P.DrugCode = POS.DrugCode WHERE P.Indate >= :start_date AND P.Indate <= :end_date - GROUP BY P.DrugCode, G.GoodsName, G.SplName, G.BARCODE, IT.IM_QT_sale_debit + GROUP BY P.DrugCode, G.GoodsName, G.SplName, G.BARCODE, IT.IM_QT_sale_debit, POS.CD_NM_sale ORDER BY SUM(ISNULL(P.QUAN, 1) * ISNULL(P.Days, 1)) DESC """) @@ -4143,6 +4145,7 @@ def api_rx_usage(): 'total_amount': int(amount), 'prescription_count': rx_count, 'current_stock': int(row.current_stock or 0), # 현재고 + 'location': row.location or '', # 약국 내 위치 'thumbnail': None }) diff --git a/backend/baekje_api.py b/backend/baekje_api.py index 94e70a0..a4417c7 100644 --- a/backend/baekje_api.py +++ b/backend/baekje_api.py @@ -26,6 +26,7 @@ baekje_bp = Blueprint('baekje', __name__, url_prefix='/api/baekje') # ========== 세션 관리 ========== _baekje_session = None +_init_started = False def get_baekje_session(): global _baekje_session @@ -34,6 +35,32 @@ def get_baekje_session(): return _baekje_session +def init_baekje_session(): + """앱 시작 시 백그라운드에서 로그인 시작""" + global _init_started + if _init_started: + return + _init_started = True + + session = get_baekje_session() + + # 저장된 토큰이 있으면 즉시 사용 가능 + if session._logged_in: + logger.info(f"백제약품: 저장된 토큰 사용 중") + return + + # 백그라운드 로그인 시작 + session.start_background_login() + logger.info(f"백제약품: 백그라운드 로그인 시작됨") + + +# 모듈 로드 시 자동 시작 +try: + init_baekje_session() +except Exception as e: + logger.warning(f"백제약품 초기화 오류: {e}") + + def search_baekje_stock(keyword: str): """백제약품 재고 검색""" try: diff --git a/backend/templates/admin_rx_usage.html b/backend/templates/admin_rx_usage.html index cca3598..4e7c534 100644 --- a/backend/templates/admin_rx_usage.html +++ b/backend/templates/admin_rx_usage.html @@ -379,6 +379,17 @@ font-size: 11px; color: var(--text-muted); } + .location-badge { + display: inline-block; + background: rgba(99, 102, 241, 0.15); + color: var(--accent-indigo); + font-size: 10px; + font-weight: 500; + padding: 1px 5px; + border-radius: 4px; + margin-left: 4px; + font-family: inherit; + } /* 수량 관련 */ .qty-cell { @@ -926,7 +937,7 @@ }
${escapeHtml(item.product_name)} - ${item.drug_code}${item.supplier ? ` · ${escapeHtml(item.supplier)}` : ''} + ${item.drug_code}${item.supplier ? ` · ${escapeHtml(item.supplier)}` : ''}${item.location ? ` 📍${escapeHtml(item.location)}` : ''}