diff --git a/resources/views/juil/workflow.blade.php b/resources/views/juil/workflow.blade.php index 9a8cf9c1..19c3480a 100644 --- a/resources/views/juil/workflow.blade.php +++ b/resources/views/juil/workflow.blade.php @@ -13,412 +13,857 @@ @verbatim const { useState, useRef, useEffect } = React; -// --- 업무 프로세스 데이터 --- +// --- 업무 프로세스 데이터 (상세 서브플로우 포함) --- const processes = [ { - id: 1, - phase: 'sales', - name: '영업/수주', - icon: '📋', - dept: '영업팀', - color: '#3B82F6', - bgColor: '#EFF6FF', + id: 1, phase: 'sales', name: '영업/수주', icon: '📋', dept: '영업팀', + color: '#3B82F6', bgColor: '#EFF6FF', description: '건설사/시행사로부터 프로젝트 정보 수집 및 수주 활동', - details: [ - '건설사 입찰공고 모니터링', - '현장 실측 및 요구사항 파악', - '고객사 미팅 및 관계 관리', - ], documents: ['입찰공고문', '현장조사서', '고객 요구사항서'], - samLink: null, - samMenu: null, + samLink: null, samMenu: null, + subSteps: [ + { + id: 'S1-1', name: '정보 수집', icon: '🔎', + description: '나라장터, 건설사 공고, 인맥 등을 통해 프로젝트 정보를 수집한다.', + input: ['나라장터 공고', '건설사 입찰 안내', '업계 네트워크 정보'], + output: ['프로젝트 리스트 (엑셀)'], + responsible: '영업 담당자', + tips: ['주 2회 이상 나라장터/건설사 사이트 모니터링', '기존 거래처 정기 연락 유지'], + duration: '수시', + }, + { + id: 'S1-2', name: '현장 실측', icon: '📐', + description: '프로젝트 대상 현장을 방문하여 실측하고 요구사항을 파악한다.', + input: ['도면 (건설사 제공)', '현장 위치 정보'], + output: ['현장조사서', '실측 데이터', '현장 사진'], + responsible: '영업 담당자 + 기술팀', + tips: ['도면과 현장 차이 반드시 확인', '사진은 전경/상세 모두 촬영'], + duration: '1~2일', + }, + { + id: 'S1-3', name: '고객 미팅', icon: '🤝', + description: '건설사 담당자와 미팅하여 요구사항, 예산, 일정 등을 협의한다.', + input: ['현장조사서', '회사 소개서', '시공 포트폴리오'], + output: ['미팅 기록', '고객 요구사항서'], + responsible: '영업 담당자', + tips: ['고객 예산 범위를 사전에 파악', '경쟁사 동향 정보 수집'], + duration: '1~3시간', + }, + { + id: 'S1-4', name: '수주 가능성 평가', icon: '📊', + description: '수집된 정보를 바탕으로 수주 가능성과 수익성을 평가하여 입찰 참여 여부를 결정한다.', + input: ['고객 요구사항서', '예상 공사비', '경쟁 현황'], + output: ['수주 검토서 (Go/No-Go 결정)'], + responsible: '영업팀장', + tips: ['수익률 10% 미만 프로젝트는 팀장 승인 필요', '리스크 요소 반드시 기재'], + duration: '1일', + }, + ], }, { - id: 2, - phase: 'estimate', - name: '견적서 작성', - icon: '🧮', - dept: '견적팀', - color: '#8B5CF6', - bgColor: '#F5F3FF', + id: 2, phase: 'estimate', name: '견적서 작성', icon: '🧮', dept: '견적팀', + color: '#8B5CF6', bgColor: '#F5F3FF', description: '자재/인건비/경비를 산출하여 견적서 작성', - details: [ - '자재 단가 산출 (블라인드, 스크린, 셔터)', - '인건비/시공비 산정', - '이윤율 적용 및 최종 견적가 확정', - ], documents: ['견적서', '단가산출서', '자재목록'], - samLink: '/juil/estimate', - samMenu: '견적/입찰/공사관리', + samLink: '/juil/estimate', samMenu: '견적/입찰/공사관리', + subSteps: [ + { + id: 'S2-1', name: '물량 산출', icon: '📏', + description: '도면과 실측 데이터를 기반으로 자재별 물량(수량)을 산출한다.', + input: ['도면', '실측 데이터', '현장조사서'], + output: ['물량산출서 (자재별 수량)'], + responsible: '견적 담당자', + tips: ['로스율(5~10%) 반드시 반영', '현장 여건에 따른 추가 물량 고려'], + duration: '2~3일', + }, + { + id: 'S2-2', name: '단가 산정', icon: '💵', + description: '자재 단가, 인건비, 장비비, 경비 등 각 항목의 단가를 산정한다.', + input: ['물량산출서', '최근 자재 시세', '노무단가표'], + output: ['단가산출서'], + responsible: '견적 담당자', + tips: ['자재 시세는 최근 3개월 평균 적용', '노무단가는 대한건설협회 기준 참조'], + duration: '1~2일', + }, + { + id: 'S2-3', name: '견적가 산출', icon: '🧮', + description: '물량 x 단가를 계산하고, 이윤율/관리비를 적용하여 최종 견적가를 산출한다.', + input: ['물량산출서', '단가산출서', '이윤율 기준'], + output: ['원가계산서', '내부 견적서'], + responsible: '견적팀장', + tips: ['이윤율은 프로젝트 규모별 차등 적용', '원가 대비 견적가 검증 필수'], + duration: '1일', + }, + { + id: 'S2-4', name: '견적서 작성/검토', icon: '📋', + description: '고객 제출용 견적서를 작성하고, 팀장 검토 후 최종 확정한다.', + input: ['원가계산서', '고객 요구 양식'], + output: ['공식 견적서 (PDF)'], + responsible: '견적팀장 → 대표이사 승인', + tips: ['고객사 양식이 별도로 있는지 확인', '견적 유효기간 명시 (보통 30일)'], + duration: '1일', + }, + ], }, { - id: 3, - phase: 'bid', - name: '입찰 참여', - icon: '🏷️', - dept: '영업팀', - color: '#EC4899', - bgColor: '#FDF2F8', + id: 3, phase: 'bid', name: '입찰 참여', icon: '🏷️', dept: '영업팀', + color: '#EC4899', bgColor: '#FDF2F8', description: '견적서 기반으로 입찰에 참여', - details: [ - '입찰서류 준비 및 제출', - '기술제안서 작성', - '가격 협상', - ], documents: ['입찰서', '기술제안서', '사업자등록증 사본'], - samLink: '/juil/estimate', - samMenu: '견적/입찰/공사관리', + samLink: '/juil/estimate', samMenu: '견적/입찰/공사관리', branch: true, + subSteps: [ + { + id: 'S3-1', name: '입찰서류 준비', icon: '📂', + description: '입찰 참여에 필요한 서류(사업자등록증, 실적증명, 재무제표 등)를 준비한다.', + input: ['입찰 공고문 (필요서류 목록)', '회사 기본서류'], + output: ['입찰서류 패키지'], + responsible: '영업 담당자 + 경영지원팀', + tips: ['서류 유효기간 확인 (인감증명 등 3개월)', '전자입찰 시 공인인증서 사전 확인'], + duration: '2~3일', + }, + { + id: 'S3-2', name: '기술제안서 작성', icon: '📝', + description: '시공 방법, 품질관리 계획, 안전관리 계획 등을 포함한 기술제안서를 작성한다.', + input: ['현장조사서', '시공 실적', '품질/안전 매뉴얼'], + output: ['기술제안서'], + responsible: '기술팀 + 영업팀', + tips: ['유사 프로젝트 실적 강조', '차별화 포인트 명확히 기술'], + duration: '3~5일', + }, + { + id: 'S3-3', name: '입찰가 결정', icon: '🎯', + description: '견적가를 기반으로 경쟁 상황을 고려한 최종 입찰가를 결정한다.', + input: ['내부 견적서', '경쟁사 동향', '예정가 분석'], + output: ['최종 입찰가 결정서'], + responsible: '대표이사 승인', + tips: ['예정가 대비 적정 투찰률 분석', '최저가 낙찰 vs 종합심사 방식 확인'], + duration: '당일', + }, + { + id: 'S3-4', name: '입찰서 제출', icon: '📮', + description: '준비된 서류와 입찰가를 포함하여 입찰서를 제출한다.', + input: ['입찰서류 패키지', '최종 입찰가', '입찰보증금'], + output: ['입찰 접수증', '입찰 결과 대기'], + responsible: '영업 담당자', + tips: ['마감시간 최소 2시간 전 제출', '전자입찰 시스템 사전 테스트'], + duration: '당일', + }, + ], }, { - id: 4, - phase: 'contract', - name: '낙찰/계약', - icon: '📝', - dept: '영업팀', - color: '#10B981', - bgColor: '#ECFDF5', + id: 4, phase: 'contract', name: '낙찰/계약', icon: '📝', dept: '영업팀', + color: '#10B981', bgColor: '#ECFDF5', description: '낙찰 후 공사 계약 체결', - details: [ - '계약서 작성 및 검토', - '계약금 수령', - '프로젝트 등록 및 담당자 배정', - ], documents: ['공사계약서', '착공계', '공정표'], - samLink: '/juil/project', - samMenu: '프로젝트관리/기성청구', + samLink: '/juil/project', samMenu: '프로젝트관리/기성청구', + subSteps: [ + { + id: 'S4-1', name: '낙찰 통보 확인', icon: '🏆', + description: '입찰 결과를 확인하고, 낙찰 통보서를 수령한다.', + input: ['입찰 결과 공고', '낙찰 통보서'], + output: ['낙찰 확인 (사내 공유)'], + responsible: '영업 담당자', + tips: ['낙찰 후 계약 기한 확인 (보통 7~10일)', '유찰 시 원인 분석하여 다음 입찰에 반영'], + duration: '당일', + }, + { + id: 'S4-2', name: '계약서 검토/체결', icon: '🖊️', + description: '계약 조건(금액, 공기, 하자보증 등)을 검토하고 계약서에 서명한다.', + input: ['계약서 초안 (발주처 제공)', '낙찰 내역서'], + output: ['공사계약서 (날인본)', '계약보증금 납부 영수증'], + responsible: '대표이사 + 경영지원팀', + tips: ['지체상금 조항 반드시 확인', '하자보증기간/비율 확인', '대금지급 조건 확인'], + duration: '3~5일', + }, + { + id: 'S4-3', name: '프로젝트 등록', icon: '💻', + description: 'SAM 시스템에 프로젝트를 등록하고 담당자를 배정한다.', + input: ['공사계약서', '공정표'], + output: ['프로젝트 등록 완료 (SAM)', '담당자 배정표'], + responsible: '영업팀장 → PM', + tips: ['계약 금액/공기 정확히 입력', '하도급 계획이 있으면 동시 등록'], + duration: '1일', + }, + { + id: 'S4-4', name: '착공 준비', icon: '🚧', + description: '착공계를 제출하고, 현장 착공에 필요한 사전 준비를 완료한다.', + input: ['공사계약서', '현장 배치도'], + output: ['착공계', '현장 투입 계획서', '안전관리 계획서'], + responsible: 'PM + 안전관리자', + tips: ['착공 전 현장 안전교육 필수', '인근 주민 민원 사전 확인'], + duration: '2~3일', + }, + ], }, { - id: 5, - phase: 'order', - name: '자재 발주', - icon: '📦', - dept: '구매팀', - color: '#F59E0B', - bgColor: '#FFFBEB', + id: 5, phase: 'order', name: '자재 발주', icon: '📦', dept: '구매팀', + color: '#F59E0B', bgColor: '#FFFBEB', description: '시공에 필요한 자재를 발주', - details: [ - 'BOM(자재명세서) 기반 발주량 산정', - '협력업체 발주서 발행', - '납기일 관리', - ], documents: ['발주서', 'BOM', '납품요청서'], - samLink: null, - samMenu: null, + samLink: null, samMenu: null, + subSteps: [ + { + id: 'S5-1', name: 'BOM 작성', icon: '📋', + description: '프로젝트에 필요한 자재 명세서(BOM)를 작성한다.', + input: ['도면', '물량산출서', '시방서'], + output: ['BOM (자재명세서)'], + responsible: '기술팀 + 구매 담당자', + tips: ['규격/색상/사양 정확히 기재', '예비 자재(로스분) 포함'], + duration: '2~3일', + }, + { + id: 'S5-2', name: '공급사 선정/견적 비교', icon: '🔄', + description: '2개 이상 공급사로부터 견적을 받아 비교하고 공급사를 선정한다.', + input: ['BOM', '기존 거래처 목록', '시세 정보'], + output: ['공급사 비교표', '공급사 선정 품의서'], + responsible: '구매 담당자 → 구매팀장 승인', + tips: ['기존 거래처 우선 검토', '납기 준수율 이력 확인'], + duration: '2~3일', + }, + { + id: 'S5-3', name: '발주서 발행', icon: '📤', + description: '선정된 공급사에 발주서를 발행하고, 납기일을 확정한다.', + input: ['공급사 선정 결과', 'BOM'], + output: ['발주서', '발주 확인서 (공급사)'], + responsible: '구매 담당자', + tips: ['시공일 기준 최소 1주 전 입고되도록 납기 설정', '분할 납품 시 일정 명확히'], + duration: '1일', + }, + { + id: 'S5-4', name: '납기 관리', icon: '📅', + description: '발주 후 공급사의 생산/배송 진행 상황을 추적한다.', + input: ['발주서', '납기 일정'], + output: ['납기 진행현황표'], + responsible: '구매 담당자', + tips: ['납기 3일 전 공급사에 확인 연락', '지연 시 즉시 PM에게 보고'], + duration: '발주~입고 기간 중 수시', + }, + ], }, { - id: 6, - phase: 'receive', - name: '자재 입고/검수', - icon: '🔍', - dept: '자재팀', - color: '#06B6D4', - bgColor: '#ECFEFF', + id: 6, phase: 'receive', name: '자재 입고/검수', icon: '🔍', dept: '자재팀', + color: '#06B6D4', bgColor: '#ECFEFF', description: '입고된 자재의 수량/품질 검수', - details: [ - '입고 수량 확인', - '품질 검사 (규격, 색상, 하자)', - '불량 자재 반품 처리', - ], documents: ['입고검수서', '거래명세서', '반품요청서'], - samLink: null, - samMenu: null, + samLink: null, samMenu: null, + subSteps: [ + { + id: 'S6-1', name: '입고 접수', icon: '🚛', + description: '공급사로부터 자재가 도착하면 거래명세서와 대조하여 접수한다.', + input: ['발주서', '거래명세서 (공급사)', '납품 자재'], + output: ['입고 접수 기록'], + responsible: '자재 담당자', + tips: ['거래명세서와 발주서 수량 대조 필수', '포장 상태 외관 확인'], + duration: '당일', + }, + { + id: 'S6-2', name: '수량 검수', icon: '🔢', + description: '입고된 자재의 수량이 발주 수량과 일치하는지 전수 검사한다.', + input: ['발주서', '입고 자재'], + output: ['수량 검수 체크리스트'], + responsible: '자재 담당자', + tips: ['부족분 즉시 공급사에 연락', '과다 입고 시에도 기록 후 보고'], + duration: '당일', + }, + { + id: 'S6-3', name: '품질 검사', icon: '🔬', + description: '자재의 규격, 색상, 기능 등 품질 기준에 부합하는지 검사한다.', + input: ['자재 시방서 (규격 기준)', '샘플'], + output: ['품질검사 성적서'], + responsible: '품질 담당자', + tips: ['블라인드: 색상/슬랫 간격 확인', '셔터: 개폐 동작 테스트 필수'], + duration: '1~2일', + }, + { + id: 'S6-4', name: '입고 확정/불량 처리', icon: '✅', + description: '검수 합격 자재는 입고 확정, 불량 자재는 반품 처리한다.', + input: ['수량 검수 결과', '품질검사 결과'], + output: ['입고검수서 (확정)', '반품요청서 (불량 시)'], + responsible: '자재팀장', + tips: ['불량률 3% 이상 시 공급사 품질 회의 요청', '입고 확정 후 재고에 즉시 반영'], + duration: '당일', + }, + ], }, { - id: 7, - phase: 'construct', - name: '현장 시공', - icon: '🔧', - dept: '시공팀', - color: '#EF4444', - bgColor: '#FEF2F2', + id: 7, phase: 'construct', name: '현장 시공', icon: '🔧', dept: '시공팀', + color: '#EF4444', bgColor: '#FEF2F2', description: '현장에서 블라인드/스크린/셔터 설치 시공', - details: [ - '시공 일정 조율 (건설사와 협의)', - '현장 설치 작업', - '시공 사진 촬영 및 기록', - ], documents: ['시공계획서', '작업일보', '시공사진'], - samLink: '/juil/construction-photos', - samMenu: '공사현장 사진대지', + samLink: '/juil/construction-photos', samMenu: '공사현장 사진대지', + subSteps: [ + { + id: 'S7-1', name: '시공 계획 수립', icon: '📅', + description: '건설사 공정표에 맞춰 시공 일정, 인력, 장비 계획을 수립한다.', + input: ['건설사 공정표', '자재 입고 일정', '인력 가용 현황'], + output: ['시공계획서', '인력/장비 투입 계획'], + responsible: 'PM + 현장소장', + tips: ['건설사 타 공종과 간섭 구간 사전 확인', '우천 시 대체 일정 수립'], + duration: '2~3일', + }, + { + id: 'S7-2', name: '자재 반출/현장 배송', icon: '🚚', + description: '창고에서 필요 자재를 반출하여 현장에 배송한다.', + input: ['시공계획서', '자재 재고 현황'], + output: ['자재 반출 전표', '현장 입고 확인서'], + responsible: '자재 담당자 + 운송팀', + tips: ['현장 반입 가능 시간 확인 (아파트: 주로 오전)', '양중 장비 필요 여부 사전 확인'], + duration: '시공일 1~2일 전', + }, + { + id: 'S7-3', name: '설치 시공', icon: '🔧', + description: '현장에서 블라인드/스크린/셔터를 설치한다.', + input: ['도면', '시공계획서', '자재'], + output: ['작업일보', '시공 진행률'], + responsible: '현장소장 + 시공기사', + tips: ['안전장구 착용 필수 (안전모, 안전화, 안전벨트)', '일일 작업일보 당일 작성'], + duration: '프로젝트 규모에 따라 상이', + }, + { + id: 'S7-4', name: '시공 사진 촬영/기록', icon: '📸', + description: '시공 전/중/후 사진을 촬영하고, SAM 시스템에 등록한다.', + input: ['시공 현장'], + output: ['시공사진 (SAM 등록)', '시공 진행 보고서'], + responsible: '현장소장', + tips: ['공정별 Before/After 반드시 촬영', 'SAM 공사현장 사진대지에 당일 업로드'], + duration: '시공 기간 중 매일', + }, + ], }, { - id: 8, - phase: 'inspect', - name: '시공 검수', - icon: '✅', - dept: '현장팀', - color: '#14B8A6', - bgColor: '#F0FDFA', + id: 8, phase: 'inspect', name: '시공 검수', icon: '✅', dept: '현장팀', + color: '#14B8A6', bgColor: '#F0FDFA', description: '시공 완료 후 품질 검수 및 하자 보수', - details: [ - '건설사 합동 검수', - '하자 사항 보수', - '검수 완료 확인서 수령', - ], documents: ['검수확인서', '하자보수보고서', '준공사진'], - samLink: '/juil/construction-photos', - samMenu: '공사현장 사진대지', + samLink: '/juil/construction-photos', samMenu: '공사현장 사진대지', + subSteps: [ + { + id: 'S8-1', name: '자체 검수', icon: '🔎', + description: '건설사 합동검수 전, 시공팀 자체적으로 시공 품질을 점검한다.', + input: ['시공 도면', '시방서', '시공 체크리스트'], + output: ['자체 검수 보고서', '보수 필요 항목 리스트'], + responsible: '현장소장', + tips: ['체크리스트 기반 전수 검사', '사소한 하자도 미리 보수'], + duration: '1~2일', + }, + { + id: 'S8-2', name: '하자 보수', icon: '🔨', + description: '자체 검수에서 발견된 하자 사항을 보수한다.', + input: ['보수 필요 항목 리스트', '보수 자재'], + output: ['하자보수 완료 보고서'], + responsible: '시공기사', + tips: ['보수 전/후 사진 촬영 필수', '동일 하자 재발 방지 대책 수립'], + duration: '1~3일', + }, + { + id: 'S8-3', name: '합동 검수', icon: '👥', + description: '건설사(감리) 담당자와 합동으로 시공 품질을 검수한다.', + input: ['시공 완료 현장', '검수 체크리스트', '시공사진'], + output: ['합동검수 확인서', '추가 보수 요청 (있을 경우)'], + responsible: '현장소장 + 건설사 감리', + tips: ['검수 일정 최소 3일 전 건설사와 협의', '추가 보수 요청 시 기한/범위 명확히 합의'], + duration: '당일', + }, + { + id: 'S8-4', name: '준공 확인', icon: '🏁', + description: '모든 검수를 완료하고 준공 확인서를 수령한다.', + input: ['합동검수 확인서', '준공사진'], + output: ['준공확인서', '준공도서'], + responsible: 'PM', + tips: ['준공확인서 수령 후 기성청구 가능', '준공도서(도면, 매뉴얼) 제출 확인'], + duration: '1~2일', + }, + ], }, { - id: 9, - phase: 'billing', - name: '기성 청구', - icon: '💰', - dept: '경리팀', - color: '#7C3AED', - bgColor: '#F5F3FF', + id: 9, phase: 'billing', name: '기성 청구', icon: '💰', dept: '경리팀', + color: '#7C3AED', bgColor: '#F5F3FF', description: '시공 진행률에 따른 기성금 청구', - details: [ - '기성 내역서 작성', - '세금계산서 발행', - '기성금 청구서 제출', - ], documents: ['기성내역서', '세금계산서', '기성청구서'], - samLink: '/juil/project', - samMenu: '프로젝트관리/기성청구', + samLink: '/juil/project', samMenu: '프로젝트관리/기성청구', + subSteps: [ + { + id: 'S9-1', name: '기성 내역서 작성', icon: '📊', + description: '시공 진행률에 따라 청구할 기성금 내역을 작성한다.', + input: ['계약서 (계약금액)', '시공 진행률', '기 청구 내역'], + output: ['기성내역서'], + responsible: '경리 담당자 + PM', + tips: ['계약 조건의 기성 산정 기준 확인 (월별/단계별)', '기 청구분 공제 정확히'], + duration: '1~2일', + }, + { + id: 'S9-2', name: '세금계산서 발행', icon: '🧾', + description: '기성금에 대한 세금계산서를 발행한다.', + input: ['기성내역서', '사업자등록 정보'], + output: ['전자세금계산서'], + responsible: '경리 담당자', + tips: ['발행일과 기성 승인일 맞추기', '수정 세금계산서 발행 시 사유 기재'], + duration: '당일', + }, + { + id: 'S9-3', name: '청구서 제출', icon: '📮', + description: '기성내역서, 세금계산서 등 청구 서류를 건설사에 제출한다.', + input: ['기성내역서', '세금계산서', '시공사진', '검수확인서'], + output: ['기성청구서 (접수 확인)'], + responsible: '경리 담당자', + tips: ['건설사별 청구 마감일 확인', '첨부서류 누락 없이 제출'], + duration: '당일', + }, + { + id: 'S9-4', name: '입금 추적', icon: '🔄', + description: '청구 후 입금 일정을 추적하고, 지연 시 독촉한다.', + input: ['기성청구서 제출 내역', '계약상 지급 기한'], + output: ['입금 예정일 관리표'], + responsible: '경리 담당자', + tips: ['지급 기한 초과 시 3일 내 독촉', '장기 미수금은 월간 보고에 포함'], + duration: '청구 후 지속', + }, + ], }, { - id: 10, - phase: 'payment', - name: '입금 확인', - icon: '🏦', - dept: '경리팀', - color: '#059669', - bgColor: '#ECFDF5', + id: 10, phase: 'payment', name: '입금 확인', icon: '🏦', dept: '경리팀', + color: '#059669', bgColor: '#ECFDF5', description: '기성금 입금 확인 및 매출 처리', - details: [ - '입금 내역 대사', - '미수금 관리', - '매출 장부 기록', - ], documents: ['입금확인서', '매출대장'], - samLink: null, - samMenu: null, + samLink: null, samMenu: null, + subSteps: [ + { + id: 'S10-1', name: '입금 확인', icon: '💳', + description: '은행 계좌에 기성금이 입금되었는지 확인한다.', + input: ['은행 거래내역', '기성청구 내역'], + output: ['입금 확인 기록'], + responsible: '경리 담당자', + tips: ['청구 금액과 입금액 일치 여부 확인', '부분 입금 시 잔액 별도 관리'], + duration: '당일', + }, + { + id: 'S10-2', name: '매출 전표 처리', icon: '📑', + description: '입금 확인 후 회계 시스템에 매출 전표를 기록한다.', + input: ['입금 확인 기록', '세금계산서'], + output: ['매출 전표', '매출대장 업데이트'], + responsible: '경리 담당자', + tips: ['매출 인식 시점 확인 (발생주의/현금주의)', '부가세 신고 일정과 연계'], + duration: '당일', + }, + { + id: 'S10-3', name: '미수금 관리', icon: '📊', + description: '미입금 건을 관리하고, 장기 미수금은 별도 조치한다.', + input: ['기성청구 내역', '입금 내역'], + output: ['미수금 현황표', '독촉장 (필요 시)'], + responsible: '경리팀장', + tips: ['30일 이상 미수금은 주간 보고', '60일 이상 시 법적 조치 검토'], + duration: '월간', + }, + { + id: 'S10-4', name: '프로젝트 수익 정산', icon: '📈', + description: '프로젝트 완료 시 총 매출/비용을 정산하여 최종 수익을 산출한다.', + input: ['총 매출 내역', '총 비용 내역 (자재+인건비+경비)'], + output: ['프로젝트 수익 정산서'], + responsible: '경리팀장 → 대표이사 보고', + tips: ['예정 이익률 대비 실제 이익률 비교 분석', '손실 프로젝트 원인 분석 필수'], + duration: '프로젝트 완료 후 1주일', + }, + ], }, { - id: 11, - phase: 'as', - name: 'A/S 관리', - icon: '🛠️', - dept: '시공팀', - color: '#6B7280', - bgColor: '#F9FAFB', + id: 11, phase: 'as', name: 'A/S 관리', icon: '🛠️', dept: '시공팀', + color: '#6B7280', bgColor: '#F9FAFB', description: '하자보수기간 내 A/S 대응', - details: [ - 'A/S 접수 및 처리', - '하자보수 비용 관리', - '보증기간 만료 관리', - ], documents: ['A/S 접수대장', '하자보수 보고서'], - samLink: null, - samMenu: null, + samLink: null, samMenu: null, + subSteps: [ + { + id: 'S11-1', name: 'A/S 접수', icon: '📞', + description: '건설사/입주자로부터 A/S 요청을 접수한다.', + input: ['A/S 요청 (전화/메일/문서)'], + output: ['A/S 접수 기록'], + responsible: '영업 담당자 → 시공팀', + tips: ['접수 즉시 SAM에 등록', '긴급 A/S(누수 등)는 24시간 내 대응'], + duration: '당일', + }, + { + id: 'S11-2', name: '현장 확인/진단', icon: '🔍', + description: 'A/S 현장을 방문하여 하자 원인을 진단한다.', + input: ['A/S 접수 기록', '시공 이력'], + output: ['하자 진단 보고서'], + responsible: '시공기사', + tips: ['시공 하자 vs 사용자 과실 판단 명확히', '사진/영상 촬영 필수'], + duration: '접수 후 2~3일 이내', + }, + { + id: 'S11-3', name: '보수 작업', icon: '🔧', + description: '진단 결과에 따라 하자 보수를 실시한다.', + input: ['하자 진단 보고서', '보수 자재'], + output: ['보수 완료 보고서', '보수 전/후 사진'], + responsible: '시공기사', + tips: ['보수 완료 후 고객 확인 서명 수령', '동일 부위 재발 방지 조치'], + duration: '1~3일', + }, + { + id: 'S11-4', name: '이력 관리/보증기간', icon: '📂', + description: 'A/S 이력을 관리하고, 하자보증기간 만료를 추적한다.', + input: ['A/S 완료 기록', '계약서 (보증기간)'], + output: ['A/S 이력대장', '보증기간 만료 알림'], + responsible: '영업팀 + 경영지원팀', + tips: ['하자보증기간: 보통 1~3년 (항목별 상이)', '만료 1개월 전 최종 점검 실시'], + duration: '보증기간 종료까지', + }, + ], }, ]; // --- 화살표 컴포넌트 --- -function Arrow({ direction = 'right', branch = false }) { - if (direction === 'down') { - return ( -
-
-
- ); - } +function Arrow() { return (
+
-
); } +// --- 미니 화살표 (모달 서브플로우용) --- +function MiniArrow() { + return ( +
+
+
+
+ ); +} + +function DownArrow() { + return ( +
+
+
+
+ ); +} + // --- 프로세스 노드 컴포넌트 --- function ProcessNode({ process, isActive, onClick }) { return (
onClick(process)} style={{ - minWidth: '140px', - maxWidth: '160px', - padding: '12px', + minWidth: '140px', maxWidth: '160px', padding: '12px', borderRadius: '12px', border: `2px solid ${isActive ? process.color : '#E5E7EB'}`, backgroundColor: isActive ? process.bgColor : '#FFFFFF', - cursor: 'pointer', - transition: 'all 0.2s ease', + cursor: 'pointer', transition: 'all 0.2s ease', boxShadow: isActive ? `0 4px 12px ${process.color}33` : '0 1px 3px rgba(0,0,0,0.1)', - textAlign: 'center', - position: 'relative', + textAlign: 'center', position: 'relative', }} >
{process.icon}
+
+ {process.name} +
{process.name}
-
{process.dept}
{process.branch && (
)}
); } -// --- 상세 패널 컴포넌트 --- -function DetailPanel({ process, onClose }) { - if (!process) return null; +// --- 서브스텝 상세 카드 --- +function SubStepDetail({ sub, index, color, bgColor, isExpanded, onToggle }) { return (
- - - {/* 헤더 */} -
+ >
{process.icon}
-
-
- {process.id} - {process.name} -
-
- 담당: {process.dept} -
+ width: '28px', height: '28px', borderRadius: '50%', + backgroundColor: isExpanded ? color : '#E5E7EB', + color: isExpanded ? '#FFF' : '#6B7280', + display: 'flex', alignItems: 'center', justifyContent: 'center', + fontSize: '12px', fontWeight: 700, flexShrink: 0, + }}>{index + 1}
+ {sub.icon} +
+
{sub.name}
+
{sub.responsible}
+
{sub.duration}
+
- {/* 설명 */} -
- {process.description} -
- - {/* 3컬럼 그리드 */} -
- {/* 상세 업무 */} -
+ {/* 상세 내용 (펼침) */} + {isExpanded && ( +
+ {/* 설명 */}
- 상세 업무 + fontSize: '13px', color: '#374151', padding: '12px', + backgroundColor: bgColor, borderRadius: '8px', + borderLeft: `3px solid ${color}`, margin: '4px 0 12px', + }}>{sub.description}
+ + {/* Input → Output */} +
+
+
+ INPUT (필요 자료) +
+ {sub.input.map((item, i) => ( +
+ + {item} +
+ ))} +
+
+
+
+ OUTPUT (산출물) +
+ {sub.output.map((item, i) => ( +
+ + {item} +
+ ))} +
-
    - {process.details.map((d, i) => ( -
  • +
    + TIP / 주의사항 +
    + {sub.tips.map((tip, i) => ( +
    - - - {d} -
  • + 💡 + {tip} +
))} - -
- - {/* 필요 서류 */} -
-
- 필요 서류
-
- {process.documents.map((doc, i) => ( - {doc} +
+ )} +
+ ); +} + +// --- 상세 모달 컴포넌트 --- +function DetailModal({ process, onClose }) { + const [expandedSub, setExpandedSub] = useState(0); // 첫번째 펼침 + const modalRef = useRef(null); + + useEffect(() => { + const handleEsc = (e) => { if (e.key === 'Escape') onClose(); }; + document.addEventListener('keydown', handleEsc); + return () => document.removeEventListener('keydown', handleEsc); + }, [onClose]); + + if (!process) return null; + + return ( +
{ if (e.target === e.currentTarget) onClose(); }} + style={{ + position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, + backgroundColor: 'rgba(0,0,0,0.5)', zIndex: 9999, + display: 'flex', alignItems: 'center', justifyContent: 'center', + padding: '20px', + }} + > +
+ {/* 모달 헤더 */} +
+
+
+
{process.icon}
+
+
+ {process.id} + + {process.name} + +
+
+ 담당: {process.dept} + {' · '}상세 업무 {process.subSteps.length}단계 +
+
+
+ +
+ + {/* 프로세스 설명 */} +
{process.description}
+ + {/* 미니 서브플로우 다이어그램 */} +
+ {process.subSteps.map((sub, i) => ( + +
setExpandedSub(i)} + style={{ + padding: '4px 10px', borderRadius: '8px', cursor: 'pointer', + backgroundColor: expandedSub === i ? process.color : '#FFFFFF', + color: expandedSub === i ? '#FFFFFF' : '#374151', + fontSize: '11px', fontWeight: 600, whiteSpace: 'nowrap', + border: `1px solid ${expandedSub === i ? process.color : '#D1D5DB'}`, + transition: 'all 0.15s ease', + }} + >{sub.name}
+ {i < process.subSteps.length - 1 && } +
))}
- {/* SAM 연동 */} -
-
- SAM 연동 + {/* 모달 본문 (스크롤) */} +
+ {/* 서브스텝 목록 */} +
+ {process.subSteps.map((sub, i) => ( + + setExpandedSub(expandedSub === i ? -1 : i)} + /> + {i < process.subSteps.length - 1 && } + + ))} +
+ + {/* 하단 - 필요서류 + SAM 연동 */} +
+
+
+ 주요 서류 +
+
+ {process.documents.map((doc, i) => ( + {doc} + ))} +
+
+
+
+ SAM 연동 +
+ {process.samLink ? ( + ↗ {process.samMenu} + ) : ( + + 추후 연동 예정 + + )} +
- {process.samLink ? ( - - ↗ {process.samMenu} - - ) : ( - 추후 연동 예정 - )}
@@ -428,52 +873,41 @@ function DetailPanel({ process, onClose }) { // --- 입찰 분기 표시 --- function BranchInfo() { return ( -
- 낙찰 → 계약 진행 - 유찰 → 재입찰/종료 +
+ + 낙찰 → 계약 진행 + + + 유찰 → 재입찰/종료 +
); } // --- 메인 앱 --- function App() { - const [selected, setSelected] = useState(null); + const [modalProcess, setModalProcess] = useState(null); - const topRow = processes.slice(0, 6); // 영업~입고검수 - const bottomRow = processes.slice(6); // 시공~A/S + const topRow = processes.slice(0, 6); + const bottomRow = processes.slice(6); return (
{/* 헤더 */} -
+
-

업무 Workflow

+

+ 업무 Workflow +

- 주일기업 업무처리과정 플로우차트 — 각 단계를 클릭하면 상세 정보를 확인할 수 있습니다 + 주일기업 업무처리과정 플로우차트 — 각 단계를 클릭하면 상세 업무 흐름을 확인할 수 있습니다

-
+
{['영업', '견적', '시공', '정산'].map((label, i) => ( {label} ))}
@@ -481,73 +915,50 @@ function App() { {/* 플로우차트 영역 */}
- {/* 상단 행: 영업 → 입고검수 */} + {/* 상단 행 */}
{topRow.map((p, i) => ( - + {i < topRow.length - 1 && } ))}
- {/* 입찰 분기 표시 (3번째 노드 아래) */} - {/* 연결 화살표 (상단 → 하단) */} -
-
+ {/* 연결 화살표 */} +
+
- {/* 하단 행: 시공 → A/S */} + {/* 하단 행 */}
{bottomRow.map((p, i) => ( - + {i < bottomRow.length - 1 && } ))}
- {/* 상세 패널 */} - {selected && ( - setSelected(null)} /> - )} - {/* 범례 */}
범례: - 클릭 → 상세 보기 + 클릭 → 상세 업무 모달 ⑂ 분기점 (입찰 결과) ↗ SAM 메뉴 바로가기 + ESC 키로 모달 닫기
+ + {/* 상세 모달 */} + {modalProcess && ( + setModalProcess(null)} /> + )}
); }