[st frontend] 저장시 picRvwCn 검토 내용을 추가 저장 로직
This commit is contained in:
@@ -88,6 +88,7 @@ export interface InstlSncnCklstResultSaveDto {
|
||||
cklstRvwSn: number;
|
||||
rvwStpComCd: string;
|
||||
selected: "Y" | "N" | null;
|
||||
picRvwCn?: string | null;
|
||||
}
|
||||
|
||||
/** 설치인가 신청 - 필수첨부파일 저장 DTO(배열 원소) */
|
||||
@@ -102,6 +103,7 @@ export interface InstlSncnApplySaveRequestDto {
|
||||
bzScaleList: InstlSncnBzScaleSaveDto[];
|
||||
bizCstList: InstlSncnBizCstSaveRequestDto[];
|
||||
cklstResultList: InstlSncnCklstResultSaveDto[];
|
||||
cklstResultMap?: Record<string, InstlSncnCklstResultSaveDto[]>;
|
||||
esntlAtchFileList: InstlSncnEsntlAtchFileSaveDto[];
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ const INSTL_PROGRESS_ORDER = [
|
||||
const getProgressStepCount = (prgrsSttsComCd?: string): number => {
|
||||
const idx = INSTL_PROGRESS_ORDER.indexOf(prgrsSttsComCd ?? "ST");
|
||||
if (idx <= INSTL_PROGRESS_ORDER.indexOf("ST")) return 1;
|
||||
if (idx <= INSTL_PROGRESS_ORDER.indexOf("TP")) return 2;
|
||||
if (idx <= INSTL_PROGRESS_ORDER.indexOf("ER")) return 2;
|
||||
return 3;
|
||||
};
|
||||
|
||||
@@ -152,7 +152,12 @@ const normalizeChecklistResultRows = (payload: any): any[] => {
|
||||
*/
|
||||
function CnfmRegistPage({ initialData }: { initialData?: any } = {}) {
|
||||
const router = useRouter();
|
||||
const userInfo = useUserStore((state) => state.userInfo);
|
||||
const userInfo2 = useUserStore((state) => state.userInfo);
|
||||
// userInfo?.dtlInstCd 테스트 코드 ENV.ROLE_USER03 , KECO 권한 테스트용 (실제 권한에 맞게 변경 필요)
|
||||
const userInfo = {
|
||||
...userInfo2,
|
||||
dtlInstCd: "ROLE_USER03",
|
||||
};
|
||||
const alert = useAlertStore((state) => state.setMessage);
|
||||
const qc = useQueryClient();
|
||||
const currentDet = useMemo(() => initialData?.detDto ?? initialData, [initialData]);
|
||||
@@ -177,14 +182,17 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) {
|
||||
|
||||
useEffect(() => {
|
||||
if (visibleReviewStepCodes.length === 0) return;
|
||||
if (editableReviewStep && selectedReviewStep !== editableReviewStep) {
|
||||
setSelectedReviewStep(editableReviewStep);
|
||||
return;
|
||||
}
|
||||
if (!visibleReviewStepCodes.includes(selectedReviewStep)) {
|
||||
setSelectedReviewStep(visibleReviewStepCodes[visibleReviewStepCodes.length - 1]);
|
||||
}
|
||||
}, [editableReviewStep, selectedReviewStep, visibleReviewStepCodes]);
|
||||
// Only set default/initial selection when visible steps or editable step change.
|
||||
// Do NOT include `selectedReviewStep` in deps to avoid overwriting user clicks.
|
||||
setSelectedReviewStep((current) => {
|
||||
// keep current if still visible
|
||||
if (current && visibleReviewStepCodes.includes(current)) return current;
|
||||
// prefer editable step if available
|
||||
if (editableReviewStep) return editableReviewStep;
|
||||
// otherwise pick the last visible step
|
||||
return visibleReviewStepCodes[visibleReviewStepCodes.length - 1];
|
||||
});
|
||||
}, [editableReviewStep, visibleReviewStepCodes]);
|
||||
|
||||
const docId = useMemo(() => {
|
||||
return currentDet?.instlSncnDocNo ?? "";
|
||||
@@ -594,6 +602,7 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) {
|
||||
/* ── 체크리스트 ── */
|
||||
type CheckResultVal = "Y" | "N" | null;
|
||||
const [checkResults, setCheckResults] = useState<Record<string, CheckResultVal>>({});
|
||||
const [checkComments, setCheckComments] = useState<Record<string, string>>({});
|
||||
const cklstRowRefs = useRef<Record<string, HTMLTableRowElement | null>>({});
|
||||
|
||||
const { data: cklstTree = [] } = useQuery<CklstTreeNode[]>({
|
||||
@@ -707,6 +716,7 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) {
|
||||
if (!Array.isArray(results) || results.length === 0) return;
|
||||
|
||||
const lookup = new Map<string, string>();
|
||||
const commentLookup = new Map<string, string>();
|
||||
const stepCodesInResult = new Set<ReviewStepCode>();
|
||||
for (const r of results) {
|
||||
const stepCode = (r.rvwStpComCd ?? DEFAULT_RVW_STP_COM_CD) as ReviewStepCode;
|
||||
@@ -714,6 +724,7 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) {
|
||||
stepCodesInResult.add(stepCode);
|
||||
const key = `${r.cklstSn}_${r.cklstArtclSn ?? ""}_${r.cklstRvwSn}_${stepCode}`;
|
||||
if (r.rvwRsltAnmlyYn === "Y" || r.rvwRsltAnmlyYn === "N") lookup.set(key, r.rvwRsltAnmlyYn);
|
||||
if (r.picRvwCn) commentLookup.set(key, String(r.picRvwCn));
|
||||
}
|
||||
|
||||
setCheckResults((prev) => {
|
||||
@@ -735,6 +746,18 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) {
|
||||
}
|
||||
return changed ? next : prev;
|
||||
});
|
||||
// set comment state separately to avoid rerendering conflicts
|
||||
setCheckComments((prev) => {
|
||||
const next: Record<string, string> = { ...prev };
|
||||
let changed = false;
|
||||
for (const [k, v] of commentLookup.entries()) {
|
||||
if (next[k] !== v) {
|
||||
next[k] = v;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed ? next : prev;
|
||||
});
|
||||
}, [initialData, cklstRows, visibleReviewStepCodes]);
|
||||
|
||||
const cklstStats = useMemo(() => {
|
||||
@@ -759,24 +782,19 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) {
|
||||
});
|
||||
visibleReviewStepCodes.forEach((code) => persistedStepCodeSet.add(code));
|
||||
|
||||
return Array.from(persistedStepCodeSet).flatMap((stepCode) =>
|
||||
return Array.from(persistedStepCodeSet).flatMap((rvwStpComCd) =>
|
||||
cklstRows.map((row) => ({
|
||||
cklstSn: row.cklstSn,
|
||||
cklstArtclSn: row.cklstArtclSn,
|
||||
cklstRvwSn: row.cklstRvwSn,
|
||||
rvwStpComCd: stepCode,
|
||||
selected: checkResults[cklstKey(row, stepCode)] ?? null,
|
||||
rvwStpComCd: rvwStpComCd,
|
||||
selected: checkResults[cklstKey(row, rvwStpComCd)] ?? null,
|
||||
picRvwCn: checkComments[cklstKey(row, rvwStpComCd)] ?? null,
|
||||
})),
|
||||
);
|
||||
};
|
||||
|
||||
// 맵 형식으로 저장할 경우(업서트 처리용) - 키는 상세 코드(EX: LOCAL.지자체) 포맷
|
||||
const REVIEW_STEP_FULL: Record<ReviewStepCode, string> = {
|
||||
LOCAL: "LOCAL.지자체",
|
||||
ENV: "ENV.환경청",
|
||||
KECO: "KECO.환경공단",
|
||||
};
|
||||
|
||||
// 맵 형식으로 저장할 경우(업서트 처리용) - 키는 검토단계 코드(LOCAL/ENV/KECO) 사용
|
||||
const toCklstSaveDtoMap = () => {
|
||||
const persistedStepCodeSet = new Set<ReviewStepCode>();
|
||||
normalizeChecklistResultRows(initialData).forEach((r: any) => {
|
||||
@@ -786,14 +804,15 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) {
|
||||
visibleReviewStepCodes.forEach((code) => persistedStepCodeSet.add(code));
|
||||
|
||||
const result: Record<string, any[]> = {};
|
||||
Array.from(persistedStepCodeSet).forEach((stepCode) => {
|
||||
const fullKey = REVIEW_STEP_FULL[stepCode];
|
||||
result[fullKey] = cklstRows.map((row) => ({
|
||||
Array.from(persistedStepCodeSet).forEach((rvwStpComCd) => {
|
||||
// use code as key (e.g., "LOCAL") and set rvwStpComCd to the same code
|
||||
result[rvwStpComCd] = cklstRows.map((row) => ({
|
||||
cklstSn: row.cklstSn,
|
||||
cklstArtclSn: row.cklstArtclSn,
|
||||
cklstRvwSn: row.cklstRvwSn,
|
||||
rvwStpComCd: fullKey,
|
||||
selected: checkResults[cklstKey(row, stepCode)] ?? null,
|
||||
rvwStpComCd: rvwStpComCd,
|
||||
selected: checkResults[cklstKey(row, rvwStpComCd)] ?? null,
|
||||
picRvwCn: checkComments[cklstKey(row, rvwStpComCd)] ?? null,
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -1525,6 +1544,11 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) {
|
||||
</th>
|
||||
<th rowSpan={2}>주요 검토내용</th>
|
||||
<th colSpan={2}>검토 결과(-)</th>
|
||||
{selectedReviewStep !== "LOCAL" ? (
|
||||
<th rowSpan={2} className="w-[20rem]">
|
||||
기술검토 의견
|
||||
</th>
|
||||
) : null}
|
||||
</tr>
|
||||
<tr>
|
||||
<th className="w-[9rem]">
|
||||
@@ -1611,6 +1635,18 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) {
|
||||
/>
|
||||
</label>
|
||||
</td>
|
||||
{selectedReviewStep !== "LOCAL" ? (
|
||||
<td className="text-left">
|
||||
<textarea
|
||||
className="cnfm-input w-full h-20"
|
||||
value={checkComments[key] ?? ""}
|
||||
readOnly={editableReviewStep !== selectedReviewStep}
|
||||
onChange={(e) =>
|
||||
setCheckComments((prev) => ({ ...prev, [key]: e.target.value }))
|
||||
}
|
||||
/>
|
||||
</td>
|
||||
) : null}
|
||||
</tr>
|
||||
);
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user