docs(manual): 실 캡처 10장 임베딩 + 자재관리·구매관리 신규 기능 반영
Build and Push Images / build-and-push (push) Has been cancelled
Build and Push Images / build-and-push (push) Has been cancelled
캡처 이미지 (Playwright 자동 캡처, docs/manual/screenshots/): - 01 로그인 → 02 메인 진입 - 03 견적관리 그리드 → 04 행 선택 + 결재상신 활성화 - 05 외부 커넥션 관리 (DB 연결 탭) - 08 화면 관리 목록 → 09 화면 상세 (디자이너 패널) - 10 사용자 대시보드 - 11 반제품검사 → 12 공정검사 + _capture.mjs / _capture_retry.mjs (재실행 스크립트, 1600x900 viewport) 매뉴얼 본문 업데이트: - §1 시스템 개요: 로그인 절차 + 그림 1·2 추가 - §3.1 영업·수주: 견적관리/행 선택 그림 3·4 - §3.3 구매·입고: 발주서 양식(일반/외주/영문) + 메일·PDF + 직인, 입고관리 3뷰 + 매입마감 신규 항목 보강 - §3.4 자재관리 신규 섹션 (자재리스트 + 불출의뢰서, StockRegister/MaterialMove/InventoryHistory/IssueDispatch 다이얼로그) - §4.1 외부 커넥션 그림 5, §5 대시보드 그림 6, §6 화면관리 그림 7·8, §6.3·6.4 품질관리 그림 9·10 - §2 카드 자재관리(NEW)·구매관리(메일·PDF·3양식) 보강 - 좌측 목차에 자재관리 항목 추가, 3.5→3.5 생산 / 3.6 품질 / 3.7 매출·CS 재번호 figure.shot CSS 추가 (1100px 폭, 부드러운 그림자).
This commit is contained in:
@@ -94,6 +94,10 @@
|
||||
details { background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 12px 16px; margin: 8px 0; }
|
||||
details summary { cursor: pointer; font-weight: 500; }
|
||||
details[open] summary { margin-bottom: 10px; }
|
||||
figure.shot { margin: 16px 0; padding: 0; }
|
||||
figure.shot img { width: 100%; max-width: 1100px; height: auto; display: block; border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 4px 12px rgba(15, 23, 42, 0.08); }
|
||||
figure.shot figcaption { margin-top: 8px; font-size: 13px; color: var(--muted); text-align: center; }
|
||||
figure.shot figcaption strong { color: var(--text); }
|
||||
@media print {
|
||||
.layout { grid-template-columns: 1fr; }
|
||||
nav.toc { display: none; }
|
||||
@@ -115,6 +119,7 @@
|
||||
<li><a href="#proc-sales">영업·수주</a></li>
|
||||
<li><a href="#proc-dev">개발·설계</a></li>
|
||||
<li><a href="#proc-purchase">구매·입고</a></li>
|
||||
<li><a href="#proc-material">자재관리</a></li>
|
||||
<li><a href="#proc-production">생산</a></li>
|
||||
<li><a href="#proc-quality">품질</a></li>
|
||||
<li><a href="#proc-revenue">매출·CS</a></li>
|
||||
@@ -180,6 +185,23 @@
|
||||
<tr><td>인증</td><td>JWT + Refresh Token</td><td>로그인 세션, 401 자동 갱신</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>로그인</h3>
|
||||
<p>브라우저로 접속하면 가장 먼저 로그인 화면이 표시됩니다.</p>
|
||||
<figure class="shot">
|
||||
<img src="screenshots/01_login.png" alt="로그인 화면">
|
||||
<figcaption><strong>그림 1.</strong> 로그인 화면 — 사용자 ID 와 비밀번호 입력.</figcaption>
|
||||
</figure>
|
||||
<ol>
|
||||
<li>사용자 ID 와 비밀번호를 입력하고 [로그인] 클릭.</li>
|
||||
<li>인증 성공 시 사용자에게 할당된 첫 메뉴(예: 영업관리 > 견적관리)로 자동 이동합니다.</li>
|
||||
<li>잘못된 자격증명이면 "패스워드가 일치하지 않습니다." 메시지가 표시됩니다.</li>
|
||||
</ol>
|
||||
|
||||
<figure class="shot">
|
||||
<img src="screenshots/02_main.png" alt="로그인 직후 메인 화면">
|
||||
<figcaption><strong>그림 2.</strong> 로그인 직후 메인 화면 — 좌측 모듈 메뉴 + 자동 진입된 첫 화면.</figcaption>
|
||||
</figure>
|
||||
|
||||
<!-- ======================================================== -->
|
||||
<h2 class="section" id="menu">2. 전체 메뉴 구조</h2>
|
||||
|
||||
@@ -215,17 +237,18 @@
|
||||
<h4>🛒 구매관리</h4>
|
||||
<ul>
|
||||
<li>M-BOM 관리</li>
|
||||
<li>구매리스트 / 견적요청서 / 품의서 / 발주서</li>
|
||||
<li>입고관리 (3가지 뷰)</li>
|
||||
<li>구매리스트 / 견적요청서 / 품의서</li>
|
||||
<li>발주서관리 <span class="badge success">메일·PDF·3양식</span></li>
|
||||
<li>입고관리 (3가지 뷰 + 매입마감)</li>
|
||||
<li>프로젝트별 발주/입고 현황</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card compact">
|
||||
<h4>📦 자재관리</h4>
|
||||
<h4>📦 자재관리 <span class="badge success">NEW</span></h4>
|
||||
<ul>
|
||||
<li>자재리스트</li>
|
||||
<li>불출의뢰서</li>
|
||||
<li>자재리스트 — 재고등록/이동/이력 다이얼로그</li>
|
||||
<li>불출의뢰서 — 작성·불출처리</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -318,6 +341,17 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<figure class="shot">
|
||||
<img src="screenshots/03_estimate_list.png" alt="견적관리 그리드">
|
||||
<figcaption><strong>그림 3.</strong> 견적관리 그리드 — 12 컬럼 (영업번호 / 주문유형 / 접수일 / 고객사 / 품명 / 견적수량 / 유무상 / 공급가액 등).
|
||||
상단 액션: [삭제] [+ 견적요청등록] [✎ 견적작성] [✈ 결재상신] [📧 메일발송] [초기화] [검색].</figcaption>
|
||||
</figure>
|
||||
|
||||
<figure class="shot">
|
||||
<img src="screenshots/04_estimate_selected.png" alt="견적 행 선택 시 상태">
|
||||
<figcaption><strong>그림 4.</strong> 견적 행을 체크하면 [✈ 결재상신] 버튼이 활성화됩니다. 행 더블클릭 시 수정 모달이 열립니다.</figcaption>
|
||||
</figure>
|
||||
|
||||
<!-- 3.2 개발·설계 -->
|
||||
<h3 id="proc-dev">3.2 개발·설계</h3>
|
||||
<div class="card">
|
||||
@@ -354,8 +388,67 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 3.4 생산 -->
|
||||
<h3 id="proc-production">3.4 생산</h3>
|
||||
<h4>발주서관리 — 양식 선택 / 메일 발송 / PDF (신규)</h4>
|
||||
<div class="card">
|
||||
<p>발주서관리에서 행을 선택하면 다음 액션이 가능합니다:</p>
|
||||
<ul>
|
||||
<li><strong>양식 선택</strong> — [발주서 작성] 클릭 시 양식 선택 모달이 뜹니다.
|
||||
<ul>
|
||||
<li><span class="badge primary">일반 양식</span> — 국내 표준 한글 양식</li>
|
||||
<li><span class="badge primary">외주 양식</span> — 외주 가공 협력사용 양식</li>
|
||||
<li><span class="badge primary">영문 양식</span> — 해외 거래처용 영문 발주서</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>로고 / 직인</strong> — 폼 상단에 RPS 로고, 하단에 자동으로 회사 직인 이미지가 합쳐집니다 (<code>frontend/public/images/rps-stamp-seal.png</code>).</li>
|
||||
<li><strong>📄 PDF 다운로드</strong> — 양식 미리보기에서 [PDF 다운로드] 클릭 → 발주번호로 파일 저장.</li>
|
||||
<li><strong>📧 메일 발송</strong> — [메일발송] 버튼 → 거래처 메일 자동 첨부 + PDF 동봉. SMTP_SEND_SWITCH 활성 시 실 발송.</li>
|
||||
<li><strong>읽기전용 모드</strong> — 결재 완료된 발주서는 자동으로 읽기전용으로 잠금.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h4>입고관리 — 3가지 뷰 + 입고등록 / 매입마감 (신규)</h4>
|
||||
<div class="card">
|
||||
<ul>
|
||||
<li><code>/purchase/inbound</code> — <strong>전체 입고 리스트</strong>. 상단 [+ 입고등록] 으로 발주서 행 선택 → 수량 / 입고일 / 검사여부 입력.</li>
|
||||
<li><code>/purchase/inbound-by-item</code> — <strong>품목별 집계</strong>. 같은 part_no 의 분할 입고를 한 행에 합산.</li>
|
||||
<li><code>/purchase/inbound-by-date</code> — <strong>입고일별 마감</strong>. 일자 단위 [마감정보입력] → 매입 마감 처리 + Amaranth 계정과목 연계.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 3.4 자재관리 (신규) -->
|
||||
<h3 id="proc-material">3.4 자재관리 (신규)</h3>
|
||||
<div class="card">
|
||||
<p>입고 후 창고로 들어온 자재를 관리합니다. 두 메뉴 모두 풀-CRUD + 인라인 액션을 지원합니다.</p>
|
||||
<table>
|
||||
<tr><th width="180">메뉴</th><th>경로</th><th>핵심 다이얼로그</th></tr>
|
||||
<tr>
|
||||
<td>자재리스트</td>
|
||||
<td><code>/material/list</code></td>
|
||||
<td>
|
||||
<span class="badge primary">재고등록</span> StockRegisterDialog ·
|
||||
<span class="badge primary">자재이동</span> MaterialMoveDialog ·
|
||||
<span class="badge primary">재고이력</span> InventoryHistoryDialog
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>불출의뢰서</td>
|
||||
<td><code>/material/issue-request</code></td>
|
||||
<td>
|
||||
<span class="badge primary">의뢰서 작성</span> IssueRequestCreateDialog ·
|
||||
<span class="badge success">불출 처리</span> IssueDispatchDialog
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p class="callout success">
|
||||
<strong>✓ 흐름</strong>
|
||||
① 입고 확정 → 자재리스트 자동 추가
|
||||
② 생산팀 [불출의뢰서] 작성 → 부서/창고/품목/수량 지정
|
||||
③ 자재팀 [불출 처리] → 실제 출고 + 재고 차감 + 이력 기록
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 3.5 생산 -->
|
||||
<h3 id="proc-production">3.5 생산</h3>
|
||||
<div class="card">
|
||||
<p>
|
||||
M-BOM 으로 생산계획을 수립하고 작업지시번호 단위로 실적을 입력합니다.
|
||||
@@ -368,8 +461,8 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 3.5 품질 -->
|
||||
<h3 id="proc-quality">3.5 품질</h3>
|
||||
<!-- 3.6 품질 -->
|
||||
<h3 id="proc-quality">3.6 품질</h3>
|
||||
<div class="card">
|
||||
<p>품질관리는 4단계로 흐릅니다:</p>
|
||||
<div class="flow">
|
||||
@@ -384,8 +477,8 @@
|
||||
<p style="margin-top: 12px;">불량 발생 → 책임부서로 통보 → 수정완료 시 재생수량 가산 → 최종양품수량 자동 산정. 자세한 내용은 <a href="#quality">6. 품질관리 메뉴 가이드</a>.</p>
|
||||
</div>
|
||||
|
||||
<!-- 3.6 매출·CS -->
|
||||
<h3 id="proc-revenue">3.6 매출·CS</h3>
|
||||
<!-- 3.7 매출·CS -->
|
||||
<h3 id="proc-revenue">3.7 매출·CS</h3>
|
||||
<div class="card">
|
||||
<p>출하 완료 → 매출 인식 → Amaranth 로 세금계산서 발행. 고객 클레임은 CS 메뉴로 접수되어 분석/조치 후 종결됩니다.</p>
|
||||
<div class="flow">
|
||||
@@ -415,6 +508,10 @@
|
||||
<div class="card">
|
||||
<p>위치: <code>관리자 > 자동화 관리 > 외부 커넥션 관리</code></p>
|
||||
<p>외부 시스템(ERP / 마스터 / 공공 API) 과의 모든 연결을 한 곳에서 관리합니다. 두 종류의 탭이 있습니다:</p>
|
||||
<figure class="shot">
|
||||
<img src="screenshots/05_excon_db_tab.png" alt="외부 커넥션 관리 - 데이터베이스 연결 탭">
|
||||
<figcaption><strong>그림 5.</strong> 외부 커넥션 관리 — [데이터베이스 연결] / [REST API 연결] 탭 전환. 각 행의 [테스트] 버튼으로 즉시 검증.</figcaption>
|
||||
</figure>
|
||||
<pre style="white-space: pre; line-height: 1.4;">┌────────────────────────────────────────────────────────────────────────────┐
|
||||
│ 외부 커넥션 관리 외부 데이터베이스 및 REST API 연결 정보를 관리합니다. │
|
||||
├────────────────────────────────────────────────────────────────────────────┤
|
||||
@@ -651,6 +748,10 @@ const url = conn.baseUrl + "/apiproxy/api99u02A01";</pre>
|
||||
<li><strong>To-Do</strong> — 결재 대기, 마감 임박 견적, 미입고 발주</li>
|
||||
</ul>
|
||||
</div>
|
||||
<figure class="shot">
|
||||
<img src="screenshots/10_dashboard.png" alt="사용자 대시보드">
|
||||
<figcaption><strong>그림 6.</strong> 사용자 대시보드 — 매출/수주 / 리스크 알림 / To-Do 위젯 통합.</figcaption>
|
||||
</figure>
|
||||
|
||||
<h3>5.2 모니터링 보드</h3>
|
||||
<table>
|
||||
@@ -697,6 +798,14 @@ const url = conn.baseUrl + "/apiproxy/api99u02A01";</pre>
|
||||
</p>
|
||||
|
||||
<h3 id="sd-overview">6.1 화면 디자이너 개요</h3>
|
||||
<figure class="shot">
|
||||
<img src="screenshots/08_screen_mng_list.png" alt="화면 관리 목록">
|
||||
<figcaption><strong>그림 7.</strong> 화면 관리 — 좌측 그룹 트리 + 우측 화면 카드 목록. 각 화면 카드의 회색 영역을 누르면 상세가 열립니다.</figcaption>
|
||||
</figure>
|
||||
<figure class="shot">
|
||||
<img src="screenshots/09_screen_detail.png" alt="화면 상세 — 디자이너 패널">
|
||||
<figcaption><strong>그림 8.</strong> 화면 상세 — 메인 테이블 / 버튼 / 데이터 흐름 / 우측 미리보기가 한 화면에 통합. 우하단 [화면 디자이너에서 편집] 으로 풀스크린 편집 진입.</figcaption>
|
||||
</figure>
|
||||
<div class="card">
|
||||
<p>위치: <code>관리자 > 화면 관리 > 화면관리</code></p>
|
||||
<pre style="white-space: pre; line-height: 1.4;">┌─────────────────────────────────────────────────────────────────────────┐
|
||||
@@ -867,6 +976,10 @@ const url = conn.baseUrl + "/apiproxy/api99u02A01";</pre>
|
||||
</div>
|
||||
|
||||
<h3>6.3 공정검사 관리</h3>
|
||||
<figure class="shot">
|
||||
<img src="screenshots/12_quality_process.png" alt="공정검사 관리">
|
||||
<figcaption><strong>그림 9.</strong> 공정검사 관리 — 검사일/검사자(자동산정)/프로젝트번호/품번/품명/검사수량 합계 등 9컬럼.</figcaption>
|
||||
</figure>
|
||||
<div class="card">
|
||||
<p><strong>경로</strong>: <code>/COMPANY_16/quality/process-inspection</code></p>
|
||||
<p>작업 중 SPC 검사. 마스터 1건당 디테일 N건(검사항목)을 SUM 으로 집계하여 한 줄로 표시.</p>
|
||||
@@ -880,6 +993,10 @@ const url = conn.baseUrl + "/apiproxy/api99u02A01";</pre>
|
||||
</div>
|
||||
|
||||
<h3>6.4 반제품검사 관리</h3>
|
||||
<figure class="shot">
|
||||
<img src="screenshots/11_quality_semi.png" alt="반제품검사 관리">
|
||||
<figcaption><strong>그림 10.</strong> 반제품검사 관리 — 14컬럼. 입고/양품/불량/재생/최종양품 SUM 자동 산정 + 불량률(%) 계산.</figcaption>
|
||||
</figure>
|
||||
<div class="card">
|
||||
<p><strong>경로</strong>: <code>/COMPANY_16/quality/semi-product-inspection</code></p>
|
||||
<p>반제품 입고에 대한 양품/불량 판정. 단일 테이블(<code>pms_quality_semi_product_inspection</code>)에 양품 마스터(<code>DATA_TYPE='GOOD'</code>)와 불량 행(<code>'DEFECT'</code>)을 동일 <code>INSPECTION_GROUP_ID</code> 로 묶어 저장합니다.</p>
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* RPS PLM 시스템 메뉴얼용 화면 캡처 스크립트.
|
||||
*
|
||||
* 사용:
|
||||
* node docs/manual/screenshots/_capture.mjs
|
||||
*
|
||||
* 전제: rps-front (localhost:9781) + rps_backend (localhost:8090) 실행 중.
|
||||
* Playwright 는 /Users/chpark/invyone/frontend/node_modules/playwright 를 재사용.
|
||||
*/
|
||||
import { chromium } from "/Users/chpark/invyone/frontend/node_modules/playwright/index.mjs";
|
||||
import { writeFileSync } from "fs";
|
||||
import path from "path";
|
||||
|
||||
const FRONT = "http://localhost:9781";
|
||||
const OUT = "/Users/chpark/vexplor_rps/docs/manual/screenshots";
|
||||
const SHOTS = [];
|
||||
|
||||
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
|
||||
async function shot(page, name, description) {
|
||||
const file = path.join(OUT, `${name}.png`);
|
||||
await page.screenshot({ path: file, fullPage: false });
|
||||
SHOTS.push({ name, description, file });
|
||||
console.log(` 📸 ${name} — ${description}`);
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true });
|
||||
const ctx = await browser.newContext({ viewport: { width: 1600, height: 900 }, locale: "ko-KR" });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
try {
|
||||
// 1. 로그인 화면
|
||||
console.log("→ 로그인 화면");
|
||||
await page.goto(`${FRONT}/login`, { waitUntil: "domcontentloaded", timeout: 60000 });
|
||||
await page.waitForLoadState("networkidle", { timeout: 30000 });
|
||||
await wait(800);
|
||||
await shot(page, "01_login", "로그인 화면 (사용자 ID / 비밀번호 입력)");
|
||||
|
||||
// 2. 로그인 진행
|
||||
console.log("→ 로그인");
|
||||
await page.getByPlaceholder("사용자 ID").fill("wace");
|
||||
await page.getByPlaceholder("비밀번호").fill("qlalfqjsgh11");
|
||||
await Promise.all([
|
||||
page.waitForURL((u) => !u.toString().includes("/login"), { timeout: 180000 }),
|
||||
page.getByRole("button", { name: "로그인" }).click(),
|
||||
]);
|
||||
await page.waitForLoadState("networkidle", { timeout: 120000 }).catch(() => {});
|
||||
await wait(6000);
|
||||
await shot(page, "02_main", "로그인 직후 메인 화면 — 좌측 모듈 메뉴 + 견적관리 자동 진입");
|
||||
|
||||
// 3. 견적관리 (이미 로그인 후 첫 화면이 견적관리)
|
||||
console.log("→ 견적관리 그리드");
|
||||
await page.goto(`${FRONT}/main`, { waitUntil: "networkidle", timeout: 60000 });
|
||||
await wait(6000);
|
||||
// 영업관리 → 견적관리 클릭
|
||||
try {
|
||||
await page.getByText("영업관리", { exact: true }).first().click({ timeout: 5000 });
|
||||
await wait(500);
|
||||
await page.getByText("견적관리", { exact: true }).first().click({ timeout: 5000 });
|
||||
await wait(3000);
|
||||
} catch { /* already there */ }
|
||||
await shot(page, "03_estimate_list", "견적관리 — 12컬럼 그리드 + 검색 필터 + 결재상신 버튼");
|
||||
|
||||
// 4. 견적 행 선택 → 결재상신 버튼 활성화 상태 캡처
|
||||
console.log("→ 견적 행 선택");
|
||||
try {
|
||||
const firstRow = page.locator("table tbody tr").first();
|
||||
if (await firstRow.isVisible({ timeout: 5000 })) {
|
||||
await firstRow.click({ timeout: 3000 });
|
||||
await wait(800);
|
||||
await shot(page, "04_estimate_selected", "견적 행 선택 시 상단 액션 버튼 활성화 (결재상신 강조)");
|
||||
}
|
||||
} catch (e) { console.warn(" ⚠ skip 행선택:", e.message); }
|
||||
|
||||
// 5. 외부 커넥션 관리 (REST API 탭)
|
||||
console.log("→ 외부 커넥션 관리");
|
||||
await page.goto(`${FRONT}/admin/automaticMng/exconList`, { waitUntil: "networkidle", timeout: 60000 });
|
||||
await wait(6000);
|
||||
await shot(page, "05_excon_db_tab", "외부 커넥션 관리 — 데이터베이스 연결 탭 (기본)");
|
||||
|
||||
// REST API 탭 클릭
|
||||
try {
|
||||
await page.getByText("REST API 연결", { exact: true }).click({ timeout: 5000 });
|
||||
await wait(3000);
|
||||
await shot(page, "06_excon_rest_tab", "외부 커넥션 관리 — REST API 연결 탭 (Amaranth 7종)");
|
||||
} catch (e) { console.warn(" ⚠ skip REST 탭:", e.message); }
|
||||
|
||||
// 6. + 새 연결 버튼 클릭 → 등록 모달
|
||||
console.log("→ REST API 등록 모달");
|
||||
try {
|
||||
const newBtn = page.getByRole("button", { name: /새 연결|새 REST|새로 추가|\+ 새/ }).first();
|
||||
if (await newBtn.isVisible({ timeout: 5000 })) {
|
||||
await newBtn.click({ timeout: 3000 });
|
||||
await wait(2500);
|
||||
await shot(page, "07_excon_rest_create", "REST API 신규 등록 모달 — 연결명/URL/인증 정보 입력");
|
||||
// ESC 닫기
|
||||
await page.keyboard.press("Escape");
|
||||
await wait(500);
|
||||
}
|
||||
} catch (e) { console.warn(" ⚠ skip 등록모달:", e.message); }
|
||||
|
||||
// 7. 화면 관리 (Screen Designer 진입점)
|
||||
console.log("→ 화면 관리");
|
||||
await page.goto(`${FRONT}/admin/screenMng/screenMngList`, { waitUntil: "networkidle", timeout: 60000 });
|
||||
await wait(6000);
|
||||
await shot(page, "08_screen_mng_list", "화면 관리 — 등록된 화면 목록 (그룹 트리 + 카드)");
|
||||
|
||||
// 8. 화면 한개 클릭 → 설정 패널
|
||||
try {
|
||||
const firstCard = page.locator(".cursor-pointer, [role=button]").filter({ hasText: /화면|sales|order|관리/ }).first();
|
||||
if (await firstCard.isVisible({ timeout: 4000 })) {
|
||||
await firstCard.click({ timeout: 3000 });
|
||||
await wait(2500);
|
||||
await shot(page, "09_screen_detail", "화면 상세 — 메인 테이블 + 버튼 + 데이터 흐름 + 미리보기");
|
||||
}
|
||||
} catch (e) { console.warn(" ⚠ skip 화면상세:", e.message); }
|
||||
|
||||
// 9. 대시보드
|
||||
console.log("→ 대시보드");
|
||||
await page.goto(`${FRONT}/dashboard`, { waitUntil: "domcontentloaded", timeout: 30000 });
|
||||
await wait(3000);
|
||||
await shot(page, "10_dashboard", "사용자 대시보드 — 매출/수주 위젯 + 모니터링");
|
||||
|
||||
// 10. 품질관리 - 반제품검사 (데이터 보임)
|
||||
console.log("→ 반제품검사");
|
||||
await page.goto(`${FRONT}/COMPANY_16/quality/semi-product-inspection`, { waitUntil: "domcontentloaded", timeout: 30000 });
|
||||
await wait(3500);
|
||||
await shot(page, "11_quality_semi", "품질관리 — 반제품검사 (waceplm 운영 데이터 82행)");
|
||||
|
||||
// 11. 공정검사
|
||||
console.log("→ 공정검사");
|
||||
await page.goto(`${FRONT}/COMPANY_16/quality/process-inspection`, { waitUntil: "domcontentloaded", timeout: 30000 });
|
||||
await wait(3500);
|
||||
await shot(page, "12_quality_process", "품질관리 — 공정검사 (3행, 검사자 자동 산정)");
|
||||
|
||||
console.log("\n✅ 캡처 완료");
|
||||
console.log(`총 ${SHOTS.length} 장`);
|
||||
SHOTS.forEach((s) => console.log(` - ${s.name}.png : ${s.description}`));
|
||||
|
||||
// 인덱스 JSON 출력
|
||||
writeFileSync(
|
||||
path.join(OUT, "_index.json"),
|
||||
JSON.stringify(SHOTS.map((s) => ({ name: s.name, description: s.description })), null, 2),
|
||||
);
|
||||
} catch (err) {
|
||||
console.error("❌ 캡처 실패:", err.message);
|
||||
process.exit(1);
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 부족한 캡처 재시도 — 02_main (로딩만 캡처됨), 06_excon_rest_tab (탭 클릭 실패).
|
||||
*/
|
||||
import { chromium } from "/Users/chpark/invyone/frontend/node_modules/playwright/index.mjs";
|
||||
import path from "path";
|
||||
|
||||
const FRONT = "http://localhost:9781";
|
||||
const OUT = "/Users/chpark/vexplor_rps/docs/manual/screenshots";
|
||||
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true });
|
||||
const ctx = await browser.newContext({ viewport: { width: 1600, height: 900 }, locale: "ko-KR" });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
try {
|
||||
// 로그인
|
||||
await page.goto(`${FRONT}/login`, { waitUntil: "domcontentloaded", timeout: 60000 });
|
||||
await page.waitForLoadState("networkidle", { timeout: 30000 }).catch(() => {});
|
||||
await wait(2000);
|
||||
await page.getByPlaceholder("사용자 ID").fill("wace");
|
||||
await page.getByPlaceholder("비밀번호").fill("qlalfqjsgh11");
|
||||
await page.getByRole("button", { name: "로그인" }).click({ timeout: 120000 });
|
||||
await page.waitForURL((u) => !u.toString().includes("/login"), { timeout: 180000 });
|
||||
await page.waitForLoadState("networkidle", { timeout: 120000 }).catch(() => {});
|
||||
await wait(15000); // 메인 진입 후 견적관리 페이지까지 완전 렌더 대기
|
||||
console.log("→ 메인 화면 재캡처");
|
||||
await page.screenshot({ path: path.join(OUT, "02_main.png"), fullPage: false });
|
||||
|
||||
// REST API 탭 재시도
|
||||
console.log("→ REST API 탭");
|
||||
await page.goto(`${FRONT}/admin/automaticMng/exconList`, { waitUntil: "networkidle", timeout: 60000 });
|
||||
await wait(6000);
|
||||
// 다양한 셀렉터 시도
|
||||
try {
|
||||
await page.locator('[role="tab"]').filter({ hasText: "REST API" }).click({ timeout: 5000 });
|
||||
} catch {
|
||||
await page.locator('button:has-text("REST API 연결")').click({ timeout: 5000 });
|
||||
}
|
||||
await wait(4000);
|
||||
await page.screenshot({ path: path.join(OUT, "06_excon_rest_tab.png"), fullPage: false });
|
||||
console.log(" ✓ 06_excon_rest_tab.png");
|
||||
|
||||
// REST API 신규 등록 모달
|
||||
console.log("→ + 새 연결 버튼");
|
||||
try {
|
||||
await page.getByRole("button", { name: /^\+/ }).first().click({ timeout: 4000 });
|
||||
await wait(3000);
|
||||
await page.screenshot({ path: path.join(OUT, "07_excon_rest_create.png"), fullPage: false });
|
||||
console.log(" ✓ 07_excon_rest_create.png");
|
||||
} catch (e) { console.warn(" ⚠ 모달 클릭 실패:", e.message); }
|
||||
|
||||
} catch (e) {
|
||||
console.error("FAIL:", e.message);
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,42 @@
|
||||
[
|
||||
{
|
||||
"name": "01_login",
|
||||
"description": "로그인 화면 (사용자 ID / 비밀번호 입력)"
|
||||
},
|
||||
{
|
||||
"name": "02_main",
|
||||
"description": "로그인 직후 메인 화면 — 좌측 모듈 메뉴 + 견적관리 자동 진입"
|
||||
},
|
||||
{
|
||||
"name": "03_estimate_list",
|
||||
"description": "견적관리 — 12컬럼 그리드 + 검색 필터 + 결재상신 버튼"
|
||||
},
|
||||
{
|
||||
"name": "04_estimate_selected",
|
||||
"description": "견적 행 선택 시 상단 액션 버튼 활성화 (결재상신 강조)"
|
||||
},
|
||||
{
|
||||
"name": "05_excon_db_tab",
|
||||
"description": "외부 커넥션 관리 — 데이터베이스 연결 탭 (기본)"
|
||||
},
|
||||
{
|
||||
"name": "08_screen_mng_list",
|
||||
"description": "화면 관리 — 등록된 화면 목록 (그룹 트리 + 카드)"
|
||||
},
|
||||
{
|
||||
"name": "09_screen_detail",
|
||||
"description": "화면 상세 — 메인 테이블 + 버튼 + 데이터 흐름 + 미리보기"
|
||||
},
|
||||
{
|
||||
"name": "10_dashboard",
|
||||
"description": "사용자 대시보드 — 매출/수주 위젯 + 모니터링"
|
||||
},
|
||||
{
|
||||
"name": "11_quality_semi",
|
||||
"description": "품질관리 — 반제품검사 (waceplm 운영 데이터 82행)"
|
||||
},
|
||||
{
|
||||
"name": "12_quality_process",
|
||||
"description": "품질관리 — 공정검사 (3행, 검사자 자동 산정)"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user