192 lines
5.2 KiB
Python
192 lines
5.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
공통 메서드 모듈
|
|
여러 모듈에서 반복 사용되는 공통 기능을 제공합니다.
|
|
"""
|
|
|
|
from typing import List, Optional
|
|
from datetime import date
|
|
|
|
from PySide6.QtCore import QPoint
|
|
|
|
from database.crud import CRUDManager
|
|
from database.models import Fault
|
|
from core.signals import GlobalSignals
|
|
from core.logger import get_logger
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
class TrainInfoMixin:
|
|
"""
|
|
편성 정보 관련 공통 기능을 제공하는 Mixin 클래스
|
|
|
|
편성번호 필드가 있는 위젯에서 사용합니다.
|
|
마우스 호버 시 최근 고장 목록 팝업을 표시합니다.
|
|
|
|
Examples:
|
|
>>> class MyTable(QTableWidget, TrainInfoMixin):
|
|
... def __init__(self):
|
|
... super().__init__()
|
|
... self.setup_train_info()
|
|
"""
|
|
|
|
def setup_train_info(self):
|
|
"""편성 정보 기능 초기화"""
|
|
self.crud = CRUDManager()
|
|
self.signals = GlobalSignals()
|
|
self._train_popup = None
|
|
|
|
def get_recent_faults(self, train_number: str, limit: int = 10) -> List[Fault]:
|
|
"""
|
|
특정 편성의 최근 고장 목록 조회
|
|
|
|
Args:
|
|
train_number: 편성번호
|
|
limit: 최대 개수
|
|
|
|
Returns:
|
|
고장 리스트
|
|
"""
|
|
if not hasattr(self, 'crud'):
|
|
self.crud = CRUDManager()
|
|
|
|
return self.crud.get_faults_by_train(train_number, limit)
|
|
|
|
def show_train_popup(self, train_number: str, position: QPoint):
|
|
"""
|
|
편성 정보 팝업 표시
|
|
|
|
Args:
|
|
train_number: 편성번호
|
|
position: 표시 위치
|
|
"""
|
|
if not train_number:
|
|
return
|
|
|
|
# 팝업이 없으면 생성
|
|
if self._train_popup is None:
|
|
from ui.components.train_info_popup import TrainInfoPopup
|
|
self._train_popup = TrainInfoPopup()
|
|
self._train_popup.detail_requested.connect(self.open_train_detail)
|
|
|
|
self._train_popup.show_train_info(train_number, position)
|
|
|
|
def hide_train_popup(self):
|
|
"""편성 팝업 숨기기"""
|
|
if self._train_popup:
|
|
self._train_popup.hide_popup()
|
|
|
|
def open_train_detail(self, train_number: str):
|
|
"""
|
|
편성 상세 정보 다이얼로그 열기
|
|
|
|
Args:
|
|
train_number: 편성번호
|
|
"""
|
|
logger.info(f"편성 상세 정보 요청: {train_number}")
|
|
# TODO: 편성 상세 다이얼로그 구현
|
|
|
|
def check_train_has_work(self, train_number: str, target_date: date = None) -> bool:
|
|
"""
|
|
해당 편성에 작업이 있는지 확인
|
|
|
|
Args:
|
|
train_number: 편성번호
|
|
target_date: 확인 날짜 (기본: 오늘)
|
|
|
|
Returns:
|
|
작업 존재 여부
|
|
"""
|
|
if not hasattr(self, 'crud'):
|
|
self.crud = CRUDManager()
|
|
|
|
if target_date is None:
|
|
target_date = date.today()
|
|
|
|
return self.crud.check_train_has_work(train_number, target_date)
|
|
|
|
def on_train_hover(self, train_number: str, x: int, y: int):
|
|
"""
|
|
편성 필드 위에 마우스 호버 시 호출
|
|
|
|
시그널을 통해 팝업 표시를 요청합니다.
|
|
|
|
Args:
|
|
train_number: 편성번호
|
|
x: 마우스 X 좌표
|
|
y: 마우스 Y 좌표
|
|
"""
|
|
if not hasattr(self, 'signals'):
|
|
self.signals = GlobalSignals()
|
|
|
|
self.signals.show_train_popup.emit(train_number, x, y)
|
|
|
|
def on_train_leave(self):
|
|
"""편성 필드에서 마우스가 벗어났을 때 호출"""
|
|
if not hasattr(self, 'signals'):
|
|
self.signals = GlobalSignals()
|
|
|
|
self.signals.hide_train_popup.emit()
|
|
|
|
|
|
def format_fault_summary(fault: Fault) -> str:
|
|
"""
|
|
고장 요약 문자열 생성
|
|
|
|
Args:
|
|
fault: 고장 객체
|
|
|
|
Returns:
|
|
요약 문자열
|
|
"""
|
|
parts = []
|
|
|
|
if fault.occurrence_date:
|
|
if isinstance(fault.occurrence_date, date):
|
|
parts.append(fault.occurrence_date.strftime("%m/%d"))
|
|
else:
|
|
parts.append(str(fault.occurrence_date)[:5])
|
|
|
|
if fault.car_number:
|
|
parts.append(f"{fault.car_number}호차")
|
|
|
|
if fault.device_category:
|
|
parts.append(fault.device_category)
|
|
|
|
content = fault.fault_content or ""
|
|
if len(content) > 30:
|
|
content = content[:30] + "..."
|
|
parts.append(content)
|
|
|
|
return " | ".join(parts)
|
|
|
|
|
|
def create_fault_popup_content(faults: List[Fault]) -> str:
|
|
"""
|
|
팝업에 표시할 고장 목록 HTML 생성
|
|
|
|
Args:
|
|
faults: 고장 리스트
|
|
|
|
Returns:
|
|
HTML 문자열
|
|
"""
|
|
if not faults:
|
|
return "<p>최근 고장 기록이 없습니다.</p>"
|
|
|
|
html_parts = ["<ul>"]
|
|
|
|
for fault in faults[:5]: # 최대 5개
|
|
summary = format_fault_summary(fault)
|
|
html_parts.append(f"<li>{summary}</li>")
|
|
|
|
html_parts.append("</ul>")
|
|
|
|
if len(faults) > 5:
|
|
html_parts.append(f"<p>... 외 {len(faults) - 5}건</p>")
|
|
|
|
return "\n".join(html_parts)
|
|
|
|
|