Merge branch 'iipbs/as/dev' of https://www.onasys.co.kr:3000/ONAANDALL/frontend into iipbs/as/dev
This commit is contained in:
@@ -8,7 +8,8 @@ import axios from "axios";
|
||||
import { type HttpResponse, Upload } from "tus-js-client";
|
||||
|
||||
import { AUTH_USER_ID, CLAIM_NAME, ENDPOINT, PROXY_HOST } from "@/shared/config";
|
||||
import { getCookie, setCookie } from "@/shared/lib";
|
||||
import { getCookie, setCookie, useAlertStore, useUserStore } from "@/shared/lib";
|
||||
import { deleteAttachment } from "@/shared/lib/attach";
|
||||
import type { AcntgSeMngTreeDto } from "@/entities/acntg";
|
||||
import { acntgService } from "@/entities/acntg";
|
||||
import type { CklstTreeNode } from "@/entities/cklst";
|
||||
@@ -85,6 +86,9 @@ const ReadCell = ({ value }: { value: string | number }) => (
|
||||
/* ------------------------------------------------------------------ */
|
||||
function CnfmRegistPage() {
|
||||
const router = useRouter();
|
||||
const userInfo = useUserStore((state) => state.userInfo);
|
||||
const alert = useAlertStore((state) => state.setMessage);
|
||||
|
||||
const [docSeComCd] = useState("INSTL");
|
||||
const [taskSeComCdNm, setTaskSeComCdNm] = useState("재이용수");
|
||||
const [taskSeComCd, setTaskSeComCd] = useState("RE");
|
||||
@@ -227,6 +231,28 @@ function CnfmRegistPage() {
|
||||
upload.start();
|
||||
};
|
||||
|
||||
/** 기타첨부파일 삭제 핸들러: 백엔드에 DELETE 요청을 보내 소프트삭제 처리 후 상태 갱신 */
|
||||
const handleDeleteEtcFile = async (fileId: string, atflId: string) => {
|
||||
try {
|
||||
if (atflId) {
|
||||
await deleteAttachment(atflId);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("기타 첨부파일 삭제 실패", error);
|
||||
alert("파일 삭제 중 오류가 발생했습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
setEtcFiles((prev) => {
|
||||
const next = prev.filter((x) => x.id !== fileId);
|
||||
if (next.length === 0) {
|
||||
setEtcFileGroupId("");
|
||||
etcFileGroupIdRef.current = "";
|
||||
}
|
||||
return next;
|
||||
});
|
||||
};
|
||||
|
||||
const handleRequiredFileChange = (
|
||||
key: RequiredAttachKey,
|
||||
e: React.ChangeEvent<HTMLInputElement>,
|
||||
@@ -280,7 +306,7 @@ function CnfmRegistPage() {
|
||||
name: file.name,
|
||||
ext,
|
||||
size: toFileSizeText(file.size),
|
||||
uploader: "(로그인 사용자)",
|
||||
uploader: userInfo?.userName ?? "알 수 없음",
|
||||
atflCd: uploadedAtflCd,
|
||||
atflId: uploadedAtflId,
|
||||
});
|
||||
@@ -737,10 +763,10 @@ function CnfmRegistPage() {
|
||||
<table className="cnfm-form-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
<th style={{ textAlign: "center" }}>
|
||||
<span className="text-red-500">*</span> 사업명
|
||||
</th>
|
||||
<td colSpan={3}>
|
||||
<td>
|
||||
<div className="flex gap-2">
|
||||
<Input
|
||||
placeholder="사업명을 입력하거나 사업찾기를 이용하세요"
|
||||
@@ -751,12 +777,10 @@ function CnfmRegistPage() {
|
||||
<button className="cnfm-btn-search whitespace-nowrap">🔍 사업찾기</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<th style={{ textAlign: "center" }}>
|
||||
<span className="text-red-500">*</span> 사업기간
|
||||
</th>
|
||||
<td colSpan={3}>
|
||||
<td>
|
||||
<div className="flex items-center gap-2">
|
||||
<Input
|
||||
placeholder="시작연도(YYYY)"
|
||||
@@ -775,7 +799,7 @@ function CnfmRegistPage() {
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<th style={{ textAlign: "center" }}>
|
||||
<span className="text-red-500">*</span> 사업내용
|
||||
</th>
|
||||
<td colSpan={3}>
|
||||
@@ -788,19 +812,23 @@ function CnfmRegistPage() {
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>구분</th>
|
||||
<th style={{ textAlign: "center" }}>구분</th>
|
||||
<td>
|
||||
<div className="flex gap-4 text-[1.3rem]">{taskSeComCdNm}</div>
|
||||
<input type="hidden" name="taskSeComCd" value={taskSeComCd} />
|
||||
</td>
|
||||
<th>신청 지자체</th>
|
||||
<th style={{ textAlign: "center" }}>신청 지자체</th>
|
||||
<td>
|
||||
<span className="text-[1.3rem] text-gray-500">(로그인 정보 자동 세팅)</span>
|
||||
<span className="inline-block min-w-[16rem] whitespace-nowrap text-[1.3rem] text-gray-500">
|
||||
{userInfo?.enoNm ?? "\u00A0"}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>사업구분</th>
|
||||
<td>
|
||||
<th style={{ textAlign: "center" }}>
|
||||
<span className="text-red-500">*</span>사업구분
|
||||
</th>
|
||||
<td colSpan={3}>
|
||||
<div className="flex gap-4 text-[1.3rem]">
|
||||
{[
|
||||
["CNFM", "설치인가"],
|
||||
@@ -831,27 +859,45 @@ function CnfmRegistPage() {
|
||||
<table className="cnfm-form-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>신청자 이름</th>
|
||||
<th
|
||||
rowSpan={2}
|
||||
style={{ textAlign: "center" }}
|
||||
className="w-[6.5rem] text-center align-middle"
|
||||
>
|
||||
신청자
|
||||
</th>
|
||||
<th style={{ textAlign: "center" }}>이름</th>
|
||||
<td>
|
||||
<span className="text-[1.3rem] text-gray-500">(로그인 사용자 자동 세팅)</span>
|
||||
<span className="inline-block min-w-[16rem] whitespace-nowrap text-[1.3rem] text-gray-500">
|
||||
{userInfo?.userName ?? "\u00A0"}
|
||||
</span>
|
||||
</td>
|
||||
<th>전화번호</th>
|
||||
<th style={{ textAlign: "center" }}>전화번호</th>
|
||||
<td>
|
||||
<span className="text-[1.3rem] text-gray-500">(로그인 사용자 자동 세팅)</span>
|
||||
<span className="inline-block min-w-[16rem] whitespace-nowrap text-[1.3rem] text-gray-500">
|
||||
{userInfo?.mphn ?? userInfo?.telno ?? "\u00A0"}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>부서</th>
|
||||
<th style={{ textAlign: "center" }}>부서</th>
|
||||
<td>
|
||||
<span className="text-[1.3rem] text-gray-500">(로그인 사용자 자동 세팅)</span>
|
||||
<span className="text-[1.3rem] text-gray-500">
|
||||
{userInfo?.instSeNm ?? "\u00A0"}
|
||||
</span>
|
||||
</td>
|
||||
<th>이메일</th>
|
||||
|
||||
<th style={{ textAlign: "center" }}>이메일</th>
|
||||
<td>
|
||||
<span className="text-[1.3rem] text-gray-500">(로그인 사용자 자동 세팅)</span>
|
||||
<span className="text-[1.3rem] text-gray-500">{userInfo?.email ?? "\u00A0"}</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>설계자 이름</th>
|
||||
<th rowSpan={2} style={{ textAlign: "center" }}>
|
||||
설계자
|
||||
</th>
|
||||
<th style={{ textAlign: "center" }}>이름</th>
|
||||
<td>
|
||||
<Input
|
||||
placeholder="설계자 성명"
|
||||
@@ -860,7 +906,7 @@ function CnfmRegistPage() {
|
||||
onChange={(e) => setDsgnrNm(e.target.value)}
|
||||
/>
|
||||
</td>
|
||||
<th>전화번호</th>
|
||||
<th style={{ textAlign: "center" }}>전화번호</th>
|
||||
<td>
|
||||
<Input
|
||||
placeholder="설계자 전화번호"
|
||||
@@ -871,16 +917,17 @@ function CnfmRegistPage() {
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>소속(용역사)</th>
|
||||
<th style={{ textAlign: "center" }}>소속</th>
|
||||
<td>
|
||||
<Input
|
||||
placeholder="용역사명"
|
||||
placeholder="소속명"
|
||||
className="!text-[1.3rem]"
|
||||
value={dsgnrPsitn}
|
||||
onChange={(e) => setDsgnrPsitn(e.target.value)}
|
||||
/>
|
||||
</td>
|
||||
<th>이메일</th>
|
||||
|
||||
<th style={{ textAlign: "center" }}>이메일</th>
|
||||
<td>
|
||||
<Input
|
||||
placeholder="설계자 이메일"
|
||||
@@ -897,19 +944,42 @@ function CnfmRegistPage() {
|
||||
{/* ── 개인정보 동의 ── */}
|
||||
<div className="cnfm-card p-4">
|
||||
<h3 className="mb-3 border-b pb-2 text-[1.5rem] font-bold text-gray-700">개인정보 동의</h3>
|
||||
<div className="mb-3 rounded border bg-gray-50 p-3 text-[1.25rem] leading-relaxed text-gray-600">
|
||||
<p className="mb-1 font-semibold">[개인정보 수집·이용 목적]</p>
|
||||
<ul className="ml-4 list-disc space-y-1">
|
||||
<li>수집항목: 소속기관, 성명, 전화번호, 이메일, IP Address, 접속 기기 정보</li>
|
||||
<li>수집목적: 하수도 시설물 설치인가 신청 및 처리 목적</li>
|
||||
<li>보유기간: 관련 법령에 따른 의무 보유 기간 준수</li>
|
||||
</ul>
|
||||
<p className="mt-2 text-[1.2rem] text-gray-500">
|
||||
※ 개인정보 제공에 동의하지 않을 수 있으나, 미동의 시 서비스 이용이 제한될 수 있습니다.
|
||||
</p>
|
||||
<div className="mb-3 max-h-80 overflow-auto whitespace-pre-wrap rounded border bg-gray-50 p-3 pr-2 text-[1.25rem] leading-relaxed text-gray-600">
|
||||
<p className="mb-1 font-semibold">[ 개인정보 수집항목 ]</p>
|
||||
<div>
|
||||
* 필수항목 : 소속기관, 소속부서, 담당자, 직급, 사무실 번호, FAX 번호
|
||||
<br />
|
||||
․ 선택항목 : 휴대폰 번호, 이메일 주소
|
||||
<br />
|
||||
․ 기타항목 : IP Address, 쿠키, 시스템 접속 및 이용 기록
|
||||
<br />※ 시스템 이용과정에서 기타 항목의 정보들이 자동으로 생성되어 수집될 수 있습니다.
|
||||
</div>
|
||||
|
||||
<p className="mt-4 font-semibold">[ 개인정보 이용목적 ]</p>
|
||||
<div>
|
||||
․ 국가하수도정보시스템 웹서비스 이용에 따른 본인 확인 절차에 이용
|
||||
<br />
|
||||
․ 국가하수도정보시스템 사용에 필요한 권한 부여
|
||||
<br />․ 사용자별 맞춤 컨텐츠 (처리시설의 운영 데이터 조회, 수질현황 데이터 조회, 예산
|
||||
편성 / 예산편성 등) 제공에 이용
|
||||
</div>
|
||||
|
||||
<div className="tit mt-4">● 개인정보의 보유 및 이용기간</div>
|
||||
<div>
|
||||
․ 수집된 고객의 개인정보는 2년 동안 보유하며 그 이후에는 문서를 파쇄합니다.
|
||||
<br />․ 정보제공자가 개인정보 파쇄를 요청할 경우 즉시 파쇄합니다.
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<div className="tit">● 개인정보 제공 거부에 따른 제한사항</div>
|
||||
<div>
|
||||
․ 귀하는 개인정보 제공 동의를 거부할 권리가 있으나, 동의 거부 시 국가하수도정보시스템
|
||||
이용 서비스에 제한이 있을 수 있습니다.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-6 text-[1.3rem]">
|
||||
<label className="flex cursor-pointer items-center gap-2 font-semibold text-blue-600">
|
||||
<label className="flex cursor-pointer items-center gap-2 font-semibold">
|
||||
<input
|
||||
type="radio"
|
||||
name="privacyAgree"
|
||||
@@ -1356,16 +1426,7 @@ function CnfmRegistPage() {
|
||||
<button
|
||||
type="button"
|
||||
className="text-[1.2rem] text-red-500 hover:text-red-700"
|
||||
onClick={() =>
|
||||
setEtcFiles((prev) => {
|
||||
const next = prev.filter((x) => x.id !== f.id);
|
||||
if (next.length === 0) {
|
||||
setEtcFileGroupId("");
|
||||
etcFileGroupIdRef.current = "";
|
||||
}
|
||||
return next;
|
||||
})
|
||||
}
|
||||
onClick={() => void handleDeleteEtcFile(f.id, f.atflId)}
|
||||
>
|
||||
✕
|
||||
</button>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { getCookie } from "@/shared/lib";
|
||||
import { CLAIM_NAME, AUTH_USER_ID } from "@/shared/config/env";
|
||||
import axios from "axios";
|
||||
import { PROXY_HOST, ENDPOINT } from "@/shared/config";
|
||||
|
||||
/**
|
||||
* Common helper to delete attachment using cookies for auth headers.
|
||||
*/
|
||||
export async function deleteAttachment(atflId: string): Promise<void> {
|
||||
if (!atflId) return;
|
||||
const headers: Record<string, string> = {
|
||||
[CLAIM_NAME]: getCookie(CLAIM_NAME) ?? "",
|
||||
[AUTH_USER_ID]: getCookie(AUTH_USER_ID) ?? "",
|
||||
};
|
||||
const url = `${PROXY_HOST}${ENDPOINT.ATTACH_SERVICE.ATTACHMENTS}/${atflId}`;
|
||||
await axios.delete(url, { headers });
|
||||
}
|
||||
@@ -33,6 +33,16 @@ export interface IUserInfo {
|
||||
naverId: string;
|
||||
isSocialUser: boolean;
|
||||
hasPassword: boolean;
|
||||
aprvYmd: string;
|
||||
enoCd: string;
|
||||
instSeCd: string;
|
||||
dtlInstCd: string;
|
||||
laeSeNm: string;
|
||||
ogdpSeNm: string;
|
||||
instSeNm: string;
|
||||
userStateNm: string;
|
||||
enoNm: string;
|
||||
dtlInstNm: string;
|
||||
}
|
||||
|
||||
export type UserState = {
|
||||
|
||||
Reference in New Issue
Block a user