diff --git a/backend/database/__pycache__/models.cpython-311.pyc b/backend/database/__pycache__/models.cpython-311.pyc index 2a4b533..b9ca9e2 100644 Binary files a/backend/database/__pycache__/models.cpython-311.pyc and b/backend/database/__pycache__/models.cpython-311.pyc differ diff --git a/backend/database/__pycache__/schemas.cpython-311.pyc b/backend/database/__pycache__/schemas.cpython-311.pyc index 0470dc2..1895807 100644 Binary files a/backend/database/__pycache__/schemas.cpython-311.pyc and b/backend/database/__pycache__/schemas.cpython-311.pyc differ diff --git a/backend/database/models.py b/backend/database/models.py index 5bdcbe4..14c0c21 100644 --- a/backend/database/models.py +++ b/backend/database/models.py @@ -138,6 +138,12 @@ class Issue(Base): additional_info_updated_at = Column(DateTime) # 추가 정보 입력 시간 additional_info_updated_by_id = Column(Integer, ForeignKey("users.id")) # 추가 정보 입력자 + # 완료 신청 관련 필드들 + completion_requested_at = Column(DateTime) # 완료 신청 시간 + completion_requested_by_id = Column(Integer, ForeignKey("users.id")) # 완료 신청자 + completion_photo_path = Column(String(500)) # 완료 사진 경로 + completion_comment = Column(Text) # 완료 코멘트 + # Relationships reporter = relationship("User", back_populates="issues", foreign_keys=[reporter_id]) reviewer = relationship("User", foreign_keys=[reviewed_by_id], overlaps="reviewed_issues") diff --git a/backend/database/schemas.py b/backend/database/schemas.py index 711143f..d89bed5 100644 --- a/backend/database/schemas.py +++ b/backend/database/schemas.py @@ -147,6 +147,12 @@ class Issue(IssueBase): additional_info_updated_at: Optional[datetime] = None # 추가 정보 입력 시간 additional_info_updated_by_id: Optional[int] = None # 추가 정보 입력자 + # 완료 신청 관련 필드들 + completion_requested_at: Optional[datetime] = None # 완료 신청 시간 + completion_requested_by_id: Optional[int] = None # 완료 신청자 + completion_photo_path: Optional[str] = None # 완료 사진 경로 + completion_comment: Optional[str] = None # 완료 코멘트 + class Config: from_attributes = True @@ -189,6 +195,11 @@ class AdditionalInfoUpdateRequest(BaseModel): responsible_person_detail: Optional[str] = None # 해당자 상세 정보 cause_detail: Optional[str] = None # 원인 상세 정보 +class CompletionRequestRequest(BaseModel): + """완료 신청 요청""" + completion_photo: str # 완료 사진 (Base64) + completion_comment: Optional[str] = None # 완료 코멘트 + class InboxIssue(BaseModel): """수신함용 부적합 정보 (간소화된 버전)""" id: int diff --git a/backend/routers/__pycache__/issues.cpython-311.pyc b/backend/routers/__pycache__/issues.cpython-311.pyc index 6115acb..0973e38 100644 Binary files a/backend/routers/__pycache__/issues.cpython-311.pyc and b/backend/routers/__pycache__/issues.cpython-311.pyc differ diff --git a/backend/routers/issues.py b/backend/routers/issues.py index e10054e..317d787 100644 --- a/backend/routers/issues.py +++ b/backend/routers/issues.py @@ -4,7 +4,7 @@ from typing import List, Optional from datetime import datetime from database.database import get_db -from database.models import Issue, IssueStatus, User, UserRole +from database.models import Issue, IssueStatus, User, UserRole, ReviewStatus from database import schemas from routers.auth import get_current_user, get_current_admin from routers.page_permissions import check_page_access @@ -288,3 +288,58 @@ async def update_issue_management( "issue_id": issue.id, "updated_fields": list(update_data.keys()) } + +@router.post("/{issue_id}/completion-request") +async def request_completion( + issue_id: int, + request: schemas.CompletionRequestRequest, + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db) +): + """ + 완료 신청 - 담당자가 작업 완료 후 완료 신청 + """ + # 이슈 조회 + issue = db.query(Issue).filter(Issue.id == issue_id).first() + if not issue: + raise HTTPException(status_code=404, detail="부적합을 찾을 수 없습니다.") + + # 진행 중 상태인지 확인 + if issue.review_status != ReviewStatus.in_progress: + raise HTTPException(status_code=400, detail="진행 중 상태의 부적합만 완료 신청할 수 있습니다.") + + # 이미 완료 신청된 경우 확인 + if issue.completion_requested_at: + raise HTTPException(status_code=400, detail="이미 완료 신청된 부적합입니다.") + + try: + # 완료 사진 저장 + completion_photo_path = None + if request.completion_photo: + completion_photo_path = save_base64_image(request.completion_photo, "completion") + + # 완료 신청 정보 업데이트 + issue.completion_requested_at = datetime.now() + issue.completion_requested_by_id = current_user.id + issue.completion_photo_path = completion_photo_path + issue.completion_comment = request.completion_comment + + db.commit() + db.refresh(issue) + + return { + "message": "완료 신청이 성공적으로 제출되었습니다.", + "issue_id": issue.id, + "completion_requested_at": issue.completion_requested_at, + "completion_photo_path": completion_photo_path + } + + except Exception as e: + db.rollback() + # 업로드된 파일이 있다면 삭제 + if completion_photo_path: + try: + delete_file(completion_photo_path) + except: + pass + raise HTTPException(status_code=500, detail=f"완료 신청 처리 중 오류가 발생했습니다: {str(e)}") diff --git a/frontend/issues-dashboard.html b/frontend/issues-dashboard.html index 0765a20..d7feb4d 100644 --- a/frontend/issues-dashboard.html +++ b/frontend/issues-dashboard.html @@ -828,6 +828,17 @@ console.log('✅ API 스크립트 로드 완료 (issues-dashboard.html)'); } + // 현황판 새로고침 함수 + function refreshDashboard() { + // 현재 선택된 프로젝트 기준으로 다시 로드 + const selectedProject = document.getElementById('projectFilter').value; + if (selectedProject) { + filterByProject(); + } else { + loadDashboardData(); + } + } + // 완료 신청 관련 함수들 let selectedCompletionIssueId = null; let completionPhotoBase64 = null;