[as] feat: 행정지원 메뉴(설치인가, 재원협의, 설계자문, 하수도기본계획) 수정
This commit is contained in:
@@ -51,7 +51,6 @@ export interface ElaprPrgrsSttsMyDocSearchParams extends ElaprPrgrsSttsSearchDto
|
||||
export interface ElaprProcessRequestDto {
|
||||
atrzPrgrsSttsComCd: string;
|
||||
rjctRsn?: string;
|
||||
finalApprovalYn?: boolean;
|
||||
}
|
||||
|
||||
/** 백엔드 ElaprApproverChangeRequestDto */
|
||||
|
||||
@@ -5,6 +5,8 @@ import { ENDPOINT } from "@/shared/config";
|
||||
import type {
|
||||
SewerBscPlanApplySaveRequestDto,
|
||||
SewerBscPlanSaveRequestDto,
|
||||
} from "../model/sewer-bsc-plan-apply-payload-schema";
|
||||
import type {
|
||||
SewerBscPlanSearchRequestDto,
|
||||
SewerBscPlanUpdateRequestDto,
|
||||
} from "../model/sewer-bsc-plan-interface";
|
||||
|
||||
@@ -4,10 +4,12 @@ import type { PageResponse } from "@/shared/model";
|
||||
|
||||
import type {
|
||||
SewerBscPlanApplySaveRequestDto,
|
||||
SewerBscPlanSaveRequestDto,
|
||||
} from "../model/sewer-bsc-plan-apply-payload-schema";
|
||||
import type {
|
||||
SewerBscPlanApplySaveResponseDto,
|
||||
SewerBscPlanDetResponseDto,
|
||||
SewerBscPlanResponseDto,
|
||||
SewerBscPlanSaveRequestDto,
|
||||
SewerBscPlanSearchRequestDto,
|
||||
SewerBscPlanService,
|
||||
SewerBscPlanUpdateRequestDto,
|
||||
|
||||
@@ -13,35 +13,52 @@ export {
|
||||
} from "./api/queries";
|
||||
export { sewerBscPlanService } from "./api/sewer-bsc-plan-service";
|
||||
export type {
|
||||
AtflMngClientResponseDto,
|
||||
CklstResultItem,
|
||||
CklstRvwRsltTreeDto,
|
||||
EsntlAtchFileItem,
|
||||
EsntlAtchFileMngTreeResponseDto,
|
||||
SewerBscPlanApplySaveRequestDto,
|
||||
SewerBscPlanApplySaveResponseDto,
|
||||
SewerBscPlanBizCstItem,
|
||||
SewerBscPlanDtlSaveRequestDto,
|
||||
SewerBscPlanFnrsCstItem,
|
||||
SewerBscPlanOtlnItem,
|
||||
SewerBscPlanRvwOpnnItem,
|
||||
SewerBscPlanSaveRequestDto,
|
||||
SewerBscPlanSplmntDmndItem,
|
||||
SewerBscPlanTmplntDtlItem,
|
||||
SewerBscPlanTmplntItem,
|
||||
SewerBscPlanTmplntTmprStrgItem,
|
||||
} from "./model/sewer-bsc-plan-apply-payload-schema";
|
||||
export {
|
||||
sewerBscPlanApplySaveSchema,
|
||||
sewerBscPlanBizCstItemSchema,
|
||||
sewerBscPlanCklstResultItemSchema,
|
||||
sewerBscPlanDtlSaveSchema,
|
||||
sewerBscPlanEsntlAtchFileItemSchema,
|
||||
sewerBscPlanFnrsCstItemSchema,
|
||||
sewerBscPlanOtlnItemSchema,
|
||||
sewerBscPlanRvwOpnnItemSchema,
|
||||
sewerBscPlanSaveSchema,
|
||||
sewerBscPlanSplmntDmndItemSchema,
|
||||
sewerBscPlanTmplntDtlItemSchema,
|
||||
sewerBscPlanTmplntItemSchema,
|
||||
sewerBscPlanTmplntTmprStrgItemSchema,
|
||||
} from "./model/sewer-bsc-plan-apply-payload-schema";
|
||||
export type {
|
||||
AtflMngClientResponseDto,
|
||||
CklstRvwRsltTreeDto,
|
||||
EsntlAtchFileMngTreeResponseDto,
|
||||
SewerBscPlanApplySaveResponseDto,
|
||||
SewerBscPlanBizCstResponseDto,
|
||||
SewerBscPlanDetResponseDto,
|
||||
SewerBscPlanDtlResponseDto,
|
||||
SewerBscPlanDtlSaveRequestDto,
|
||||
SewerBscPlanFnrsCstItem,
|
||||
SewerBscPlanFnrsCstResponseDto,
|
||||
SewerBscPlanOtlnItem,
|
||||
SewerBscPlanOtlnResponseDto,
|
||||
SewerBscPlanResponseDto,
|
||||
SewerBscPlanRvwOpnnItem,
|
||||
SewerBscPlanRvwOpnnResponseDto,
|
||||
SewerBscPlanSaveRequestDto,
|
||||
SewerBscPlanSearchRequestDto,
|
||||
SewerBscPlanService,
|
||||
SewerBscPlanSplmntDmndItem,
|
||||
SewerBscPlanSplmntDmndResponseDto,
|
||||
SewerBscPlanTmplntDtlItem,
|
||||
SewerBscPlanTmplntDtlResponseDto,
|
||||
SewerBscPlanTmplntItem,
|
||||
SewerBscPlanTmplntResponseDto,
|
||||
SewerBscPlanTmplntTmprStrgItem,
|
||||
SewerBscPlanTmplntTmprStrgResponseDto,
|
||||
SewerBscPlanUpdateRequestDto,
|
||||
} from "./model/sewer-bsc-plan-interface";
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
import { z } from "zod";
|
||||
|
||||
/** 백엔드 SewerBscPlanSaveRequestDto */
|
||||
export const sewerBscPlanSaveSchema = z.object({
|
||||
sewerBscPlanDocNo: z.string().optional(),
|
||||
admdstCd: z.string().optional(),
|
||||
envoSeComCd: z.string().optional(),
|
||||
sewerBscPlanSeComCd: z.string().optional(),
|
||||
sewerBscPlanNm: z.string().optional(),
|
||||
taskSeComCd: z.string().optional(),
|
||||
prgrsSttsComCd: z.string().optional(),
|
||||
});
|
||||
|
||||
/** 백엔드 SewerBscPlanDtlSaveRequestDto */
|
||||
export const sewerBscPlanDtlSaveSchema = z.object({
|
||||
sewerBscPlanDocNo: z.string().optional(),
|
||||
chgCycl: z.number().optional(),
|
||||
aplcntNm: z.string().optional(),
|
||||
aplcntMblTelno: z.string().optional(),
|
||||
aplcntOgdpNm: z.string().optional(),
|
||||
aplcntEmlAddr: z.string().optional(),
|
||||
dsgnrNm: z.string().optional(),
|
||||
dsgnrTelno: z.string().optional(),
|
||||
dsgnrOgdpNm: z.string().optional(),
|
||||
dsgnrEmlAddr: z.string().optional(),
|
||||
planYr: z.string().optional(),
|
||||
crtrYr: z.string().optional(),
|
||||
bizOtlnCn: z.string().optional(),
|
||||
frlvlGoalYr: z.string().optional(),
|
||||
sclvlGoalYr: z.string().optional(),
|
||||
thlvlGoalYr: z.string().optional(),
|
||||
folvlGoalYr: z.string().optional(),
|
||||
atchFileGroupId: z.string().optional(),
|
||||
});
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanOtlnItem */
|
||||
export const sewerBscPlanOtlnItemSchema = z.object({
|
||||
planStpNo: z.number().optional(),
|
||||
sewerPlanPpltnCnt: z.number().optional(),
|
||||
sewerPrcsPpltnCnt: z.number().optional(),
|
||||
sewerPsplyRt: z.number().optional(),
|
||||
});
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.CklstResultItem */
|
||||
export const sewerBscPlanCklstResultItemSchema = z.object({
|
||||
cklstRvwSn: z.number().optional(),
|
||||
cklstArtclSn: z.number().optional(),
|
||||
cklstSn: z.number().optional(),
|
||||
rvwStpComCd: z.string(),
|
||||
selected: z.string().optional(),
|
||||
picRvwCn: z.string().nullish(),
|
||||
});
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanFnrsCstItem */
|
||||
export const sewerBscPlanFnrsCstItemSchema = z.object({
|
||||
planStpNo: z.number().optional(),
|
||||
gvexpAmt: z.number().optional(),
|
||||
lcexpAmt: z.number().optional(),
|
||||
orgprBdchgAmt: z.number().optional(),
|
||||
etcAmt: z.number().optional(),
|
||||
sumAmt: z.number().optional(),
|
||||
});
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanSplmntDmndItem */
|
||||
export const sewerBscPlanSplmntDmndItemSchema = z.object({
|
||||
splmntDmndSn: z.number().nullish(),
|
||||
splmntArtclComCd: z.string().optional(),
|
||||
splmntDmndCn: z.string().optional(),
|
||||
splmntDmndDt: z.string().optional(),
|
||||
splmntDmndAtchFileGroupId: z.string().optional(),
|
||||
splmntCn: z.string().optional(),
|
||||
splmntPicNm: z.string().optional(),
|
||||
splmntCmptnDt: z.string().optional(),
|
||||
splmntAtchFileGroupId: z.string().optional(),
|
||||
cmptnYn: z.string().optional(),
|
||||
});
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanRvwOpnnItem */
|
||||
export const sewerBscPlanRvwOpnnItemSchema = z.object({
|
||||
rvwOpnnSn: z.number().optional(),
|
||||
opnrSeComCd: z.string().optional(),
|
||||
opnrNm: z.string().optional(),
|
||||
rvwRsltCn: z.string().optional(),
|
||||
rvwRsltAnmlyYn: z.string().optional(),
|
||||
atchFileGroupId: z.string().optional(),
|
||||
});
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.EsntlAtchFileItem */
|
||||
export const sewerBscPlanEsntlAtchFileItemSchema = z.object({
|
||||
esntlAtchFileId: z.string().optional(),
|
||||
atchFileGroupId: z.string().optional(),
|
||||
});
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanBizCstItem */
|
||||
export const sewerBscPlanBizCstItemSchema = z.object({
|
||||
planStpNo: z.number().optional(),
|
||||
acntgSeCd: z.string().optional(),
|
||||
cstrnAmt: z.number().optional(),
|
||||
});
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanTmplntDtlItem */
|
||||
export const sewerBscPlanTmplntDtlItemSchema = z.object({
|
||||
planStpNo: z.number().optional(),
|
||||
swtrmtFcltCd: z.string().optional(),
|
||||
prcsZoneArea: z.number().optional(),
|
||||
swtrmtPpltnCnt: z.number().optional(),
|
||||
planSwqty: z.number().optional(),
|
||||
fcltCpct: z.number().optional(),
|
||||
sprsysDrtwPplLen: z.number().optional(),
|
||||
sprsysExlnPplLen: z.number().optional(),
|
||||
cbsysPplLen: z.number().optional(),
|
||||
icptgPplLen: z.number().optional(),
|
||||
drgCnt: z.number().optional(),
|
||||
drtwRlyPumpCnt: z.number().optional(),
|
||||
drtwPumpCnt: z.number().optional(),
|
||||
exlnPumpCnt: z.number().optional(),
|
||||
});
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanTmplntItem */
|
||||
export const sewerBscPlanTmplntItemSchema = z.object({
|
||||
swtrmtFcltCd: z.string().optional(),
|
||||
atchFileGroupId: z.string().optional(),
|
||||
sewerBscPlanTmplntDtlList: z.array(sewerBscPlanTmplntDtlItemSchema).optional(),
|
||||
});
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanTmplntTmprStrgItem */
|
||||
export const sewerBscPlanTmplntTmprStrgItemSchema = z.object({
|
||||
dtStrgDt: z.string().optional(),
|
||||
swtrmtFcltCd: z.string().optional(),
|
||||
prcsZoneArea: z.number().optional(),
|
||||
swtrmtPpltnCnt: z.number().optional(),
|
||||
planSwqty: z.number().optional(),
|
||||
fcltCpct: z.number().optional(),
|
||||
sprsysDrtwPplLen: z.number().optional(),
|
||||
sprsysExlnPplLen: z.number().optional(),
|
||||
cbsysPplLen: z.number().optional(),
|
||||
icptgPplLen: z.number().optional(),
|
||||
drgCnt: z.number().optional(),
|
||||
drtwRlyPumpCnt: z.number().optional(),
|
||||
drtwPumpCnt: z.number().optional(),
|
||||
exlnPumpCnt: z.number().optional(),
|
||||
});
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto */
|
||||
export const sewerBscPlanApplySaveSchema = z.object({
|
||||
techReViewSaveCd: z.string().optional(),
|
||||
rvwStpCd: z.string().optional(),
|
||||
sewerBscPlan: sewerBscPlanSaveSchema,
|
||||
sewerBscPlanDtl: sewerBscPlanDtlSaveSchema,
|
||||
sewerBscPlanOtlnList: z.array(sewerBscPlanOtlnItemSchema).optional(),
|
||||
cklstResultList: z.array(sewerBscPlanCklstResultItemSchema).optional(),
|
||||
fnrsCstList: z.array(sewerBscPlanFnrsCstItemSchema).optional(),
|
||||
splmntDmndList: z.array(sewerBscPlanSplmntDmndItemSchema).optional(),
|
||||
rvwOpnnList: z.array(sewerBscPlanRvwOpnnItemSchema).optional(),
|
||||
esntlAtchFileList: z.array(sewerBscPlanEsntlAtchFileItemSchema).optional(),
|
||||
bizCstList: z.array(sewerBscPlanBizCstItemSchema).optional(),
|
||||
sewerBscPlanTmplntList: z.array(sewerBscPlanTmplntItemSchema).optional(),
|
||||
tmplntTmprStrgList: z.array(sewerBscPlanTmplntTmprStrgItemSchema).optional(),
|
||||
});
|
||||
|
||||
export type SewerBscPlanSaveRequestDto = z.infer<typeof sewerBscPlanSaveSchema>;
|
||||
export type SewerBscPlanDtlSaveRequestDto = z.infer<typeof sewerBscPlanDtlSaveSchema>;
|
||||
export type SewerBscPlanOtlnItem = z.infer<typeof sewerBscPlanOtlnItemSchema>;
|
||||
export type CklstResultItem = z.infer<typeof sewerBscPlanCklstResultItemSchema>;
|
||||
export type SewerBscPlanFnrsCstItem = z.infer<typeof sewerBscPlanFnrsCstItemSchema>;
|
||||
export type SewerBscPlanSplmntDmndItem = z.infer<typeof sewerBscPlanSplmntDmndItemSchema>;
|
||||
export type SewerBscPlanRvwOpnnItem = z.infer<typeof sewerBscPlanRvwOpnnItemSchema>;
|
||||
export type EsntlAtchFileItem = z.infer<typeof sewerBscPlanEsntlAtchFileItemSchema>;
|
||||
export type SewerBscPlanBizCstItem = z.infer<typeof sewerBscPlanBizCstItemSchema>;
|
||||
export type SewerBscPlanTmplntDtlItem = z.infer<typeof sewerBscPlanTmplntDtlItemSchema>;
|
||||
export type SewerBscPlanTmplntItem = z.infer<typeof sewerBscPlanTmplntItemSchema>;
|
||||
export type SewerBscPlanTmplntTmprStrgItem = z.infer<typeof sewerBscPlanTmplntTmprStrgItemSchema>;
|
||||
export type SewerBscPlanApplySaveRequestDto = z.infer<typeof sewerBscPlanApplySaveSchema>;
|
||||
@@ -1,35 +1,26 @@
|
||||
import type {
|
||||
AtflMngClientResponseDto,
|
||||
CklstResultSaveBase,
|
||||
CklstRvwRsltTreeDto,
|
||||
EsntlAtchFileMngTreeResponseDto,
|
||||
EsntlAtchFileSaveBase,
|
||||
PageableParams,
|
||||
PageResponse,
|
||||
PbadmsApplySaveHeader,
|
||||
RvwOpnnResponseExtension,
|
||||
RvwOpnnSaveBase,
|
||||
SplmntDmndResponseExtension,
|
||||
SplmntDmndSaveBase,
|
||||
} from "@/shared/model";
|
||||
|
||||
import type {
|
||||
SewerBscPlanApplySaveRequestDto,
|
||||
SewerBscPlanSaveRequestDto,
|
||||
} from "./sewer-bsc-plan-apply-payload-schema";
|
||||
|
||||
export type {
|
||||
AtflMngClientResponseDto,
|
||||
CklstRvwRsltTreeDto,
|
||||
EsntlAtchFileMngTreeResponseDto,
|
||||
} from "@/shared/model";
|
||||
|
||||
/** 백엔드 SewerBscPlanSaveRequestDto */
|
||||
export interface SewerBscPlanSaveRequestDto {
|
||||
sewerBscPlanDocNo?: string;
|
||||
admdstCd?: string;
|
||||
envoSeComCd?: string;
|
||||
sewerBscPlanSeComCd?: string;
|
||||
sewerBscPlanNm?: string;
|
||||
taskSeComCd?: string;
|
||||
prgrsSttsComCd?: string;
|
||||
}
|
||||
|
||||
/** 백엔드 SewerBscPlanUpdateRequestDto */
|
||||
export interface SewerBscPlanUpdateRequestDto {
|
||||
admdstCd?: string;
|
||||
@@ -72,28 +63,6 @@ export interface SewerBscPlanResponseDto {
|
||||
mdfcnDt?: string;
|
||||
}
|
||||
|
||||
/** 백엔드 SewerBscPlanDtlSaveRequestDto */
|
||||
export interface SewerBscPlanDtlSaveRequestDto {
|
||||
sewerBscPlanDocNo?: string;
|
||||
chgCycl?: number;
|
||||
aplcntNm?: string;
|
||||
aplcntMblTelno?: string;
|
||||
aplcntOgdpNm?: string;
|
||||
aplcntEmlAddr?: string;
|
||||
dsgnrNm?: string;
|
||||
dsgnrTelno?: string;
|
||||
dsgnrOgdpNm?: string;
|
||||
dsgnrEmlAddr?: string;
|
||||
planYr?: string;
|
||||
crtrYr?: string;
|
||||
bizOtlnCn?: string;
|
||||
frlvlGoalYr?: string;
|
||||
sclvlGoalYr?: string;
|
||||
thlvlGoalYr?: string;
|
||||
folvlGoalYr?: string;
|
||||
atchFileGroupId?: string;
|
||||
}
|
||||
|
||||
/** 백엔드 SewerBscPlanDtlResponseDto */
|
||||
export interface SewerBscPlanDtlResponseDto {
|
||||
sewerBscPlanDocNo?: string;
|
||||
@@ -210,103 +179,6 @@ export interface SewerBscPlanTmplntTmprStrgResponseDto {
|
||||
exlnPumpCnt?: number;
|
||||
}
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanOtlnItem */
|
||||
export interface SewerBscPlanOtlnItem {
|
||||
planStpNo?: number;
|
||||
sewerPlanPpltnCnt?: number;
|
||||
sewerPrcsPpltnCnt?: number;
|
||||
sewerPsplyRt?: number;
|
||||
}
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.CklstResultItem */
|
||||
export interface CklstResultItem extends CklstResultSaveBase {
|
||||
selected?: string;
|
||||
}
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanFnrsCstItem */
|
||||
export interface SewerBscPlanFnrsCstItem {
|
||||
planStpNo?: number;
|
||||
gvexpAmt?: number;
|
||||
lcexpAmt?: number;
|
||||
orgprBdchgAmt?: number;
|
||||
etcAmt?: number;
|
||||
sumAmt?: number;
|
||||
}
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanSplmntDmndItem */
|
||||
export type SewerBscPlanSplmntDmndItem = SplmntDmndSaveBase;
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanRvwOpnnItem */
|
||||
export type SewerBscPlanRvwOpnnItem = RvwOpnnSaveBase;
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.EsntlAtchFileItem */
|
||||
export type EsntlAtchFileItem = EsntlAtchFileSaveBase;
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanBizCstItem */
|
||||
export interface SewerBscPlanBizCstItem {
|
||||
planStpNo?: number;
|
||||
acntgSeCd?: string;
|
||||
cstrnAmt?: number;
|
||||
}
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanTmplntDtlItem */
|
||||
export interface SewerBscPlanTmplntDtlItem {
|
||||
planStpNo?: number;
|
||||
swtrmtFcltCd?: string;
|
||||
prcsZoneArea?: number;
|
||||
swtrmtPpltnCnt?: number;
|
||||
planSwqty?: number;
|
||||
fcltCpct?: number;
|
||||
sprsysDrtwPplLen?: number;
|
||||
sprsysExlnPplLen?: number;
|
||||
cbsysPplLen?: number;
|
||||
icptgPplLen?: number;
|
||||
drgCnt?: number;
|
||||
drtwRlyPumpCnt?: number;
|
||||
drtwPumpCnt?: number;
|
||||
exlnPumpCnt?: number;
|
||||
}
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanTmplntItem */
|
||||
export interface SewerBscPlanTmplntItem {
|
||||
swtrmtFcltCd?: string;
|
||||
atchFileGroupId?: string;
|
||||
sewerBscPlanTmplntDtlList?: SewerBscPlanTmplntDtlItem[];
|
||||
}
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto.SewerBscPlanTmplntTmprStrgItem */
|
||||
export interface SewerBscPlanTmplntTmprStrgItem {
|
||||
dtStrgDt?: string;
|
||||
swtrmtFcltCd?: string;
|
||||
prcsZoneArea?: number;
|
||||
swtrmtPpltnCnt?: number;
|
||||
planSwqty?: number;
|
||||
fcltCpct?: number;
|
||||
sprsysDrtwPplLen?: number;
|
||||
sprsysExlnPplLen?: number;
|
||||
cbsysPplLen?: number;
|
||||
icptgPplLen?: number;
|
||||
drgCnt?: number;
|
||||
drtwRlyPumpCnt?: number;
|
||||
drtwPumpCnt?: number;
|
||||
exlnPumpCnt?: number;
|
||||
}
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveRequestDto */
|
||||
export interface SewerBscPlanApplySaveRequestDto extends PbadmsApplySaveHeader {
|
||||
sewerBscPlan: SewerBscPlanSaveRequestDto;
|
||||
sewerBscPlanDtl: SewerBscPlanDtlSaveRequestDto;
|
||||
sewerBscPlanOtlnList?: SewerBscPlanOtlnItem[];
|
||||
cklstResultList?: CklstResultItem[];
|
||||
fnrsCstList?: SewerBscPlanFnrsCstItem[];
|
||||
splmntDmndList?: SewerBscPlanSplmntDmndItem[];
|
||||
rvwOpnnList?: SewerBscPlanRvwOpnnItem[];
|
||||
esntlAtchFileList?: EsntlAtchFileItem[];
|
||||
bizCstList?: SewerBscPlanBizCstItem[];
|
||||
sewerBscPlanTmplntList?: SewerBscPlanTmplntItem[];
|
||||
tmplntTmprStrgList?: SewerBscPlanTmplntTmprStrgItem[];
|
||||
}
|
||||
|
||||
/** 백엔드 SewerBscPlanApplySaveResponseDto */
|
||||
export interface SewerBscPlanApplySaveResponseDto {
|
||||
sewerBscPlanDocNo: string;
|
||||
|
||||
@@ -15,10 +15,12 @@ import {
|
||||
type DesignCnstnMngDetResponseDto,
|
||||
designCnstnMngService,
|
||||
} from "@/entities/design-cnstn";
|
||||
import { useEsntlAtchFileMngTree } from "@/entities/esntl";
|
||||
import {
|
||||
AttachmentsFormSection,
|
||||
BusinessScaleFormSection,
|
||||
ContactInfoFormSection,
|
||||
isFormEsntlAtchComplete,
|
||||
PrivacyConsentSection,
|
||||
} from "@/widgets/pbadms-sprt";
|
||||
import { Button } from "@common/components";
|
||||
@@ -53,6 +55,8 @@ function DesignFormPage({ id, mode, initialData, createDefaults }: DesignFormPag
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const isEditMode = mode === "edit";
|
||||
|
||||
const { data: essentialFiles = [] } = useEsntlAtchFileMngTree({ docSeComCd: "CNFM" });
|
||||
|
||||
const form = useForm<DesignCnstnRegistFormData>({
|
||||
resolver: zodResolver(designCnstnRegistSchema),
|
||||
mode: "onChange",
|
||||
@@ -113,6 +117,11 @@ function DesignFormPage({ id, mode, initialData, createDefaults }: DesignFormPag
|
||||
async function onApply(data: DesignCnstnRegistFormData) {
|
||||
if (isSubmitting) return;
|
||||
|
||||
if (!isFormEsntlAtchComplete(essentialFiles, data.esntlAtchFileList)) {
|
||||
alert("필수 첨부파일을 모두 등록해야 신청이 가능합니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
const designCnstnDocNo = await submitForm(data, "CT");
|
||||
|
||||
@@ -62,6 +62,7 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr
|
||||
</SectionCollapsible>
|
||||
)}
|
||||
|
||||
{etcFileList.length > 0 && (
|
||||
<SectionCollapsible title="기타 첨부파일">
|
||||
<div className="overflow-x-auto">
|
||||
<Table variant="secondary">
|
||||
@@ -105,6 +106,7 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr
|
||||
</Table>
|
||||
</div>
|
||||
</SectionCollapsible>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
|
||||
|
||||
import { Paperclip } from "lucide-react";
|
||||
|
||||
import { PROXY_HOST } from "@/shared/config";
|
||||
import { dayjs, getDefaultFileKey, useTus } from "@/shared/lib";
|
||||
import { Field, FieldLabel, FieldSet } from "@/shared/ui/field";
|
||||
@@ -71,12 +73,10 @@ function hasFormContent(formData: ReviewOpinionFormData) {
|
||||
const TechReviewOpinionSection = forwardRef<
|
||||
TechReviewOpinionSectionHandle,
|
||||
TechReviewOpinionSectionProps
|
||||
>(function TechReviewOpinionSection({
|
||||
rvwList,
|
||||
editableReviewStep,
|
||||
atrzSeComCdList = [],
|
||||
isAtrzLoading = false,
|
||||
}, ref) {
|
||||
>(function TechReviewOpinionSection(
|
||||
{ rvwList, editableReviewStep, atrzSeComCdList = [], isAtrzLoading = false },
|
||||
ref,
|
||||
) {
|
||||
const canWriteOpinion = !isAtrzLoading && atrzSeComCdList.includes("ATRZ02");
|
||||
const [formData, setFormData] = useState<ReviewOpinionFormData>({
|
||||
...EMPTY_FORM_DATA,
|
||||
@@ -317,11 +317,12 @@ function TechReviewOpinionTable({ items }: TechReviewOpinionTableProps) {
|
||||
<TableCell align="center">
|
||||
{item.atchFileInfo?.atflCd ? (
|
||||
<a
|
||||
className="text-blue-600 hover:underline"
|
||||
className="inline-flex cursor-pointer items-start gap-1 text-left text-blue-600 hover:underline"
|
||||
href={`${PROXY_HOST}/attach-service/api/v1/atflcd/download/${item.atchFileInfo.atflCd}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Paperclip className="my-1 size-5 shrink-0" />
|
||||
{item.atchFileInfo.orgnlFileNm || "다운로드"}
|
||||
</a>
|
||||
) : (
|
||||
|
||||
@@ -85,7 +85,7 @@ export const fnrsCnsltnRegistSchema = z.object({
|
||||
),
|
||||
splmntDmndList: z.array(
|
||||
z.object({
|
||||
splmntDmndSn: z.number().optional(),
|
||||
splmntDmndSn: z.number().nullish(),
|
||||
splmntArtclComCd: z.string().optional(),
|
||||
splmntArtclCdNm: z.string().nullish(),
|
||||
splmntDmndCn: z.string().optional(),
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { useAlertStore, useUserStore } from "@/shared/lib";
|
||||
import { useAcntgSeMngTree } from "@/entities/acntg";
|
||||
import { useEsntlAtchFileMngTree } from "@/entities/esntl";
|
||||
import {
|
||||
type FnrsCnsltnApplySaveRequestDto,
|
||||
fnrsCnsltnMngBaseKey,
|
||||
@@ -27,6 +28,7 @@ import {
|
||||
ContactInfoFormSection,
|
||||
FnrsSharFormSection,
|
||||
isFormChecklistComplete,
|
||||
isFormEsntlAtchComplete,
|
||||
PrivacyConsentSection,
|
||||
recalculateFnrsSharTotals,
|
||||
SplmntDmndFormSection,
|
||||
@@ -67,6 +69,7 @@ function FnrsFormPage({ id, mode, initialData, createDefaults }: FnrsFormPagePro
|
||||
|
||||
const { data: masterSharTree = [] } = useFnrsSharSeMngTree();
|
||||
const { data: acntgTree = [] } = useAcntgSeMngTree();
|
||||
const { data: essentialFiles = [] } = useEsntlAtchFileMngTree({ docSeComCd: "FNRS" });
|
||||
const sharTree =
|
||||
isEditMode && initialData?.fnrsSharList?.length ? initialData.fnrsSharList : masterSharTree;
|
||||
const sharItems = useMemo(() => buildFnrsSharItems(sharTree), [sharTree]);
|
||||
@@ -210,6 +213,11 @@ function FnrsFormPage({ id, mode, initialData, createDefaults }: FnrsFormPagePro
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isFormEsntlAtchComplete(essentialFiles, data.esntlAtchFileList)) {
|
||||
alert("필수 첨부파일을 모두 등록해야 신청이 가능합니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
const fnrsCnsltnDocNo = await submitForm(data, "ST");
|
||||
|
||||
@@ -19,6 +19,7 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr
|
||||
|
||||
return (
|
||||
<>
|
||||
{esntlFileList.length > 0 && (
|
||||
<SectionCollapsible title="필수 첨부파일">
|
||||
<div className="overflow-x-auto">
|
||||
<Table variant="secondary">
|
||||
@@ -59,7 +60,9 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr
|
||||
<span className="text-gray-500">첨부없음</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className="text-right">{formatFileSize(file.atflFlieSz)}</TableCell>
|
||||
<TableCell className="text-right">
|
||||
{formatFileSize(file.atflFlieSz)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
)}
|
||||
@@ -67,7 +70,9 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr
|
||||
</Table>
|
||||
</div>
|
||||
</SectionCollapsible>
|
||||
)}
|
||||
|
||||
{etcFileList.length > 0 && (
|
||||
<SectionCollapsible title="기타 첨부파일">
|
||||
<div className="overflow-x-auto">
|
||||
<Table variant="secondary">
|
||||
@@ -111,6 +116,7 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr
|
||||
</Table>
|
||||
</div>
|
||||
</SectionCollapsible>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -71,6 +71,10 @@ function ChecklistSection({
|
||||
|
||||
const { total, completed, percent } = progress;
|
||||
|
||||
if (cklstResultList.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<SectionCollapsible title="체크리스트">
|
||||
<div className="flex flex-col gap-4 p-2">
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
|
||||
|
||||
import { Paperclip } from "lucide-react";
|
||||
|
||||
import { PROXY_HOST } from "@/shared/config";
|
||||
import { dayjs, getDefaultFileKey, useTus } from "@/shared/lib";
|
||||
import { Field, FieldLabel, FieldSet } from "@/shared/ui/field";
|
||||
@@ -71,12 +73,10 @@ function hasFormContent(formData: ReviewOpinionFormData) {
|
||||
const TechReviewOpinionSection = forwardRef<
|
||||
TechReviewOpinionSectionHandle,
|
||||
TechReviewOpinionSectionProps
|
||||
>(function TechReviewOpinionSection({
|
||||
rvwList,
|
||||
editableReviewStep,
|
||||
atrzSeComCdList = [],
|
||||
isAtrzLoading = false,
|
||||
}, ref) {
|
||||
>(function TechReviewOpinionSection(
|
||||
{ rvwList, editableReviewStep, atrzSeComCdList = [], isAtrzLoading = false },
|
||||
ref,
|
||||
) {
|
||||
const canWriteKecoOpinion = !isAtrzLoading && atrzSeComCdList.includes("ATRZ02");
|
||||
const [formData, setFormData] = useState<ReviewOpinionFormData>({
|
||||
...EMPTY_FORM_DATA,
|
||||
@@ -336,11 +336,12 @@ function TechReviewOpinionTable({ items }: TechReviewOpinionTableProps) {
|
||||
<TableCell align="center">
|
||||
{item.atchFileInfo?.atflCd ? (
|
||||
<a
|
||||
className="text-blue-600 hover:underline"
|
||||
className="inline-flex cursor-pointer items-start gap-1 text-left text-blue-600 hover:underline"
|
||||
href={`${PROXY_HOST}/attach-service/api/v1/atflcd/download/${item.atchFileInfo.atflCd}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Paperclip className="my-1 size-5 shrink-0" />
|
||||
{item.atchFileInfo.orgnlFileNm || "다운로드"}
|
||||
</a>
|
||||
) : (
|
||||
|
||||
@@ -77,7 +77,7 @@ export const instlSncnRegistSchema = z.object({
|
||||
),
|
||||
splmntDmndList: z.array(
|
||||
z.object({
|
||||
splmntDmndSn: z.number().optional(),
|
||||
splmntDmndSn: z.number().nullish(),
|
||||
splmntArtclComCd: z.string().optional(),
|
||||
splmntArtclCdNm: z.string().nullish(),
|
||||
splmntDmndCn: z.string().optional(),
|
||||
|
||||
@@ -9,6 +9,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { useAlertStore, useUserStore } from "@/shared/lib";
|
||||
import { useEsntlAtchFileMngTree } from "@/entities/esntl";
|
||||
import {
|
||||
type InstlSncnApplySaveRequestDto,
|
||||
instlSncnKeys,
|
||||
@@ -22,6 +23,7 @@ import {
|
||||
ChecklistFormSection,
|
||||
ContactInfoFormSection,
|
||||
isFormChecklistComplete,
|
||||
isFormEsntlAtchComplete,
|
||||
PrivacyConsentSection,
|
||||
SplmntDmndFormSection,
|
||||
} from "@/widgets/pbadms-sprt";
|
||||
@@ -57,6 +59,8 @@ function InstlFormPage({ id, mode, initialData, createDefaults }: InstlFormPageP
|
||||
const isEditMode = mode === "edit";
|
||||
const isSplmntPrgrsStts = initialData?.detDto.prgrsSttsComCd === "SL";
|
||||
|
||||
const { data: essentialFiles = [] } = useEsntlAtchFileMngTree({ docSeComCd: "INSTL" });
|
||||
|
||||
const form = useForm<InstlSncnRegistFormData>({
|
||||
resolver: zodResolver(instlSncnRegistSchema),
|
||||
mode: "onChange",
|
||||
@@ -172,6 +176,11 @@ function InstlFormPage({ id, mode, initialData, createDefaults }: InstlFormPageP
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isFormEsntlAtchComplete(essentialFiles, data.esntlAtchFileList)) {
|
||||
alert("필수 첨부파일을 모두 등록해야 신청이 가능합니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
const instlSncnDocNo = await submitForm(data, "ST");
|
||||
|
||||
@@ -19,6 +19,7 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr
|
||||
|
||||
return (
|
||||
<>
|
||||
{esntlFileList.length > 0 && (
|
||||
<SectionCollapsible title="필수 첨부파일">
|
||||
<div className="overflow-x-auto">
|
||||
<Table variant="secondary">
|
||||
@@ -59,7 +60,9 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr
|
||||
<span className="text-gray-500">첨부없음</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className="text-right">{formatFileSize(file.atflFlieSz)}</TableCell>
|
||||
<TableCell className="text-right">
|
||||
{formatFileSize(file.atflFlieSz)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
)}
|
||||
@@ -67,7 +70,9 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr
|
||||
</Table>
|
||||
</div>
|
||||
</SectionCollapsible>
|
||||
)}
|
||||
|
||||
{etcFileList.length > 0 && (
|
||||
<SectionCollapsible title="기타 첨부파일">
|
||||
<div className="overflow-x-auto">
|
||||
<Table variant="secondary">
|
||||
@@ -111,6 +116,7 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr
|
||||
</Table>
|
||||
</div>
|
||||
</SectionCollapsible>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -70,6 +70,10 @@ function ChecklistSection({
|
||||
|
||||
const { total, completed, percent } = progress;
|
||||
|
||||
if (cklstResultList.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<SectionCollapsible title="체크리스트">
|
||||
<div className="flex flex-col gap-4 p-2">
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
|
||||
|
||||
import { Paperclip } from "lucide-react";
|
||||
|
||||
import { PROXY_HOST } from "@/shared/config";
|
||||
import { dayjs, getDefaultFileKey, useTus } from "@/shared/lib";
|
||||
import { Field, FieldLabel, FieldSet } from "@/shared/ui/field";
|
||||
@@ -67,12 +69,10 @@ function hasFormContent(formData: ReviewOpinionFormData) {
|
||||
const TechReviewOpinionSection = forwardRef<
|
||||
TechReviewOpinionSectionHandle,
|
||||
TechReviewOpinionSectionProps
|
||||
>(function TechReviewOpinionSection({
|
||||
rvwList,
|
||||
editableReviewStep,
|
||||
atrzSeComCdList = [],
|
||||
isAtrzLoading = false,
|
||||
}, ref) {
|
||||
>(function TechReviewOpinionSection(
|
||||
{ rvwList, editableReviewStep, atrzSeComCdList = [], isAtrzLoading = false },
|
||||
ref,
|
||||
) {
|
||||
const canWriteKecoOpinion = !isAtrzLoading && atrzSeComCdList.includes("ATRZ02");
|
||||
const [formData, setFormData] = useState<ReviewOpinionFormData>({
|
||||
...EMPTY_FORM_DATA,
|
||||
@@ -329,11 +329,12 @@ function TechReviewOpinionTable({ items }: TechReviewOpinionTableProps) {
|
||||
<TableCell align="center">
|
||||
{item.atchFileInfo?.atflCd ? (
|
||||
<a
|
||||
className="text-blue-600 hover:underline"
|
||||
className="inline-flex cursor-pointer items-start gap-1 text-left text-blue-600 hover:underline"
|
||||
href={`${PROXY_HOST}/attach-service/api/v1/atflcd/download/${item.atchFileInfo.atflCd}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Paperclip className="my-1 size-5 shrink-0" />
|
||||
{item.atchFileInfo.orgnlFileNm || "다운로드"}
|
||||
</a>
|
||||
) : (
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import type { IUserInfo } from "@/shared/store";
|
||||
import type {
|
||||
SewerBscPlanApplySaveRequestDto,
|
||||
SewerBscPlanDetResponseDto,
|
||||
} from "@/entities/sewer-bsc-plan";
|
||||
import { sewerBscPlanApplySaveSchema } from "@/entities/sewer-bsc-plan";
|
||||
|
||||
import type { BizCstMatrixItem } from "./biz-cst-matrix-utils";
|
||||
import { recalcFnrsCstSumAmt } from "./fnrs-cst-form-utils";
|
||||
@@ -245,47 +245,33 @@ export function buildApplyPayload(
|
||||
prgrsSttsComCd: "SV" | "LE" | "TE",
|
||||
options?: { isEditMode?: boolean; docNo?: string },
|
||||
): SewerBscPlanApplySaveRequestDto {
|
||||
const { taskSeComCd, ...sewerBscPlanRest } = data.sewerBscPlan;
|
||||
const docNo = options?.isEditMode ? options.docNo : undefined;
|
||||
|
||||
return {
|
||||
return sewerBscPlanApplySaveSchema.parse({
|
||||
sewerBscPlan: {
|
||||
...sewerBscPlanRest,
|
||||
taskSeComCd: taskSeComCd ?? "",
|
||||
sewerBscPlanDocNo: options?.isEditMode ? options.docNo : undefined,
|
||||
...data.sewerBscPlan,
|
||||
sewerBscPlanDocNo: docNo,
|
||||
taskSeComCd: data.sewerBscPlan.taskSeComCd ?? "",
|
||||
prgrsSttsComCd,
|
||||
},
|
||||
sewerBscPlanDtl: {
|
||||
...data.sewerBscPlanDtl,
|
||||
sewerBscPlanDocNo: options?.isEditMode ? options.docNo : undefined,
|
||||
sewerBscPlanDocNo: docNo,
|
||||
},
|
||||
sewerBscPlanOtlnList: data.sewerBscPlanOtlnList,
|
||||
bizCstList: data.bizCstList,
|
||||
fnrsCstList: data.fnrsCstList.map((item) => recalcFnrsCstSumAmt(item)),
|
||||
sewerBscPlanTmplntList: data.sewerBscPlanTmplntList.map(
|
||||
({ atchFileNm, swtrmtFcltNm, ...item }) => ({
|
||||
swtrmtFcltCd: item.swtrmtFcltCd,
|
||||
atchFileGroupId: item.atchFileGroupId,
|
||||
sewerBscPlanTmplntDtlList: item.sewerBscPlanTmplntDtlList,
|
||||
}),
|
||||
),
|
||||
sewerBscPlanTmplntList: data.sewerBscPlanTmplntList,
|
||||
cklstResultList: data.cklstResultList.map((item) => ({
|
||||
...item,
|
||||
selected: item.selected ?? undefined,
|
||||
})),
|
||||
esntlAtchFileList: data.esntlAtchFileList,
|
||||
splmntDmndList: data.splmntDmndList.map(
|
||||
({
|
||||
splmntArtclCdNm,
|
||||
splmntAtchFileNm,
|
||||
splmntAtchFileAtflId,
|
||||
splmntDmndAtchFileNm,
|
||||
...item
|
||||
}) => ({
|
||||
splmntDmndList: data.splmntDmndList.map((item) => ({
|
||||
...item,
|
||||
...(prgrsSttsComCd === "TE" ? { cmptnYn: "Y" } : null),
|
||||
}),
|
||||
),
|
||||
};
|
||||
cmptnYn: prgrsSttsComCd === "TE" ? "Y" : item.cmptnYn,
|
||||
})),
|
||||
});
|
||||
}
|
||||
|
||||
export { createEmptyTmplntDtlList };
|
||||
|
||||
+2
-4
@@ -146,10 +146,8 @@ export function buildSupplementReqPayload(
|
||||
toSplmntDmndSaveItem(item),
|
||||
);
|
||||
|
||||
const nextSn = existingItems.reduce((max, item) => Math.max(max, item.splmntDmndSn ?? 0), 0) + 1;
|
||||
|
||||
const newItems: SewerBscPlanSplmntDmndItem[] = payload.items.map((item, index) => ({
|
||||
splmntDmndSn: nextSn + index,
|
||||
const newItems: SewerBscPlanSplmntDmndItem[] = payload.items.map((item) => ({
|
||||
splmntDmndSn: null,
|
||||
splmntArtclComCd: item.splmntArtclComCd,
|
||||
splmntDmndCn: item.splmntDmndCn,
|
||||
splmntDmndAtchFileGroupId: item.splmntDmndAtchFileGroupId,
|
||||
@@ -1,38 +1,27 @@
|
||||
import { z } from "zod";
|
||||
|
||||
const tmplntDtlSchema = z.object({
|
||||
planStpNo: z.number(),
|
||||
swtrmtFcltCd: z.string(),
|
||||
prcsZoneArea: z.number().optional(),
|
||||
swtrmtPpltnCnt: z.number().optional(),
|
||||
planSwqty: z.number().optional(),
|
||||
fcltCpct: z.number().optional(),
|
||||
sprsysDrtwPplLen: z.number().optional(),
|
||||
sprsysExlnPplLen: z.number().optional(),
|
||||
cbsysPplLen: z.number().optional(),
|
||||
icptgPplLen: z.number().optional(),
|
||||
drgCnt: z.number().optional(),
|
||||
drtwRlyPumpCnt: z.number().optional(),
|
||||
drtwPumpCnt: z.number().optional(),
|
||||
exlnPumpCnt: z.number().optional(),
|
||||
});
|
||||
import {
|
||||
sewerBscPlanBizCstItemSchema,
|
||||
sewerBscPlanCklstResultItemSchema,
|
||||
sewerBscPlanDtlSaveSchema,
|
||||
sewerBscPlanEsntlAtchFileItemSchema,
|
||||
sewerBscPlanFnrsCstItemSchema,
|
||||
sewerBscPlanOtlnItemSchema,
|
||||
sewerBscPlanSaveSchema,
|
||||
sewerBscPlanSplmntDmndItemSchema,
|
||||
sewerBscPlanTmplntDtlItemSchema,
|
||||
sewerBscPlanTmplntItemSchema,
|
||||
} from "@/entities/sewer-bsc-plan";
|
||||
|
||||
export const sewerBscPlanRegistSchema = z.object({
|
||||
sewerBscPlan: z.object({
|
||||
sewerBscPlanDocNo: z.string().optional(),
|
||||
sewerBscPlan: sewerBscPlanSaveSchema.extend({
|
||||
sewerBscPlanNm: z.string().min(1, "기본계획명은 필수입니다"),
|
||||
sewerBscPlanSeComCd: z.string().optional(),
|
||||
sewerBscPlanSeCdNm: z.string().optional(),
|
||||
taskSeComCd: z.string().optional(),
|
||||
taskSeCdNm: z.string().optional(),
|
||||
admdstCd: z.string().optional(),
|
||||
envoSeComCd: z.string().optional(),
|
||||
prgrsSttsComCd: z.string().optional(),
|
||||
sido: z.string().optional(),
|
||||
gugun: z.string().optional(),
|
||||
gugun: z.string().nullish(),
|
||||
}),
|
||||
sewerBscPlanDtl: z.object({
|
||||
chgCycl: z.number().optional(),
|
||||
sewerBscPlanDtl: sewerBscPlanDtlSaveSchema.extend({
|
||||
planYr: z.string().min(1, "계획년도는 필수입니다"),
|
||||
crtrYr: z.string().min(1, "기준년도는 필수입니다"),
|
||||
frlvlGoalYr: z.string().min(1, "1단계 목표연도는 필수입니다"),
|
||||
@@ -40,10 +29,6 @@ export const sewerBscPlanRegistSchema = z.object({
|
||||
thlvlGoalYr: z.string().min(1, "3단계 목표연도는 필수입니다"),
|
||||
folvlGoalYr: z.string().min(1, "4단계 목표연도는 필수입니다"),
|
||||
bizOtlnCn: z.string().min(1, "계획개요는 필수입니다"),
|
||||
aplcntNm: z.string().optional(),
|
||||
aplcntMblTelno: z.string().optional(),
|
||||
aplcntOgdpNm: z.string().optional(),
|
||||
aplcntEmlAddr: z.string().optional(),
|
||||
dsgnrNm: z.string().min(1, "설계자 이름은 필수입니다"),
|
||||
dsgnrTelno: z
|
||||
.string()
|
||||
@@ -54,74 +39,60 @@ export const sewerBscPlanRegistSchema = z.object({
|
||||
.string()
|
||||
.min(1, "설계자 이메일은 필수입니다")
|
||||
.email("올바른 이메일 형식이 아닙니다"),
|
||||
atchFileGroupId: z.string().optional(),
|
||||
}),
|
||||
sewerBscPlanOtlnList: z.array(
|
||||
z.object({
|
||||
sewerBscPlanOtlnItemSchema.extend({
|
||||
planStpNo: z.number(),
|
||||
sewerPlanPpltnCnt: z.number().optional(),
|
||||
sewerPrcsPpltnCnt: z.number().optional(),
|
||||
sewerPsplyRt: z.number().optional(),
|
||||
}),
|
||||
),
|
||||
bizCstList: z.array(
|
||||
z.object({
|
||||
sewerBscPlanBizCstItemSchema.extend({
|
||||
planStpNo: z.number(),
|
||||
acntgSeCd: z.string(),
|
||||
cstrnAmt: z.number(),
|
||||
}),
|
||||
),
|
||||
fnrsCstList: z.array(
|
||||
z.object({
|
||||
sewerBscPlanFnrsCstItemSchema.extend({
|
||||
planStpNo: z.number(),
|
||||
gvexpAmt: z.number().optional(),
|
||||
lcexpAmt: z.number().optional(),
|
||||
orgprBdchgAmt: z.number().optional(),
|
||||
etcAmt: z.number().optional(),
|
||||
sumAmt: z.number().optional(),
|
||||
}),
|
||||
),
|
||||
sewerBscPlanTmplntList: z.array(
|
||||
z.object({
|
||||
sewerBscPlanTmplntItemSchema.extend({
|
||||
swtrmtFcltCd: z.string(),
|
||||
swtrmtFcltNm: z.string().nullish(),
|
||||
atchFileGroupId: z.string().optional(),
|
||||
atchFileNm: z.string().optional(),
|
||||
sewerBscPlanTmplntDtlList: z.array(tmplntDtlSchema).optional(),
|
||||
sewerBscPlanTmplntDtlList: z
|
||||
.array(
|
||||
sewerBscPlanTmplntDtlItemSchema.extend({
|
||||
planStpNo: z.number(),
|
||||
swtrmtFcltCd: z.string(),
|
||||
}),
|
||||
)
|
||||
.optional(),
|
||||
}),
|
||||
),
|
||||
cklstResultList: z.array(
|
||||
z.object({
|
||||
sewerBscPlanCklstResultItemSchema.extend({
|
||||
cklstSn: z.number(),
|
||||
cklstArtclSn: z.number(),
|
||||
cklstRvwSn: z.number(),
|
||||
rvwStpComCd: z.string(),
|
||||
selected: z.enum(["Y", "N"]).nullable(),
|
||||
picRvwCn: z.string().nullable().optional(),
|
||||
}),
|
||||
),
|
||||
esntlAtchFileList: z.array(
|
||||
z.object({
|
||||
sewerBscPlanEsntlAtchFileItemSchema.extend({
|
||||
esntlAtchFileId: z.string(),
|
||||
atchFileGroupId: z.string(),
|
||||
}),
|
||||
),
|
||||
splmntDmndList: z.array(
|
||||
z.object({
|
||||
splmntDmndSn: z.number().optional(),
|
||||
splmntArtclComCd: z.string().optional(),
|
||||
sewerBscPlanSplmntDmndItemSchema.extend({
|
||||
splmntArtclCdNm: z.string().nullish(),
|
||||
splmntDmndCn: z.string().optional(),
|
||||
splmntDmndDt: z.string().optional(),
|
||||
splmntDmndAtchFileGroupId: z.string().optional(),
|
||||
splmntDmndAtchFileNm: z.string().optional(),
|
||||
splmntCn: z.string().optional(),
|
||||
splmntPicNm: z.string().optional(),
|
||||
splmntCmptnDt: z.string().optional(),
|
||||
splmntAtchFileGroupId: z.string().optional(),
|
||||
splmntAtchFileNm: z.string().optional(),
|
||||
splmntAtchFileAtflId: z.string().optional(),
|
||||
cmptnYn: z.string().optional(),
|
||||
}),
|
||||
),
|
||||
privacyConsent: z.enum(["Y", "N"], {
|
||||
@@ -130,6 +101,3 @@ export const sewerBscPlanRegistSchema = z.object({
|
||||
});
|
||||
|
||||
export type SewerBscPlanRegistFormData = z.infer<typeof sewerBscPlanRegistSchema>;
|
||||
|
||||
/** 체크리스트·필수첨부 docSeComCd — CMS 합의 전 임시값 */
|
||||
export const SEWER_BSC_PLAN_DOC_SE_COM_CD = "SEWER";
|
||||
|
||||
@@ -46,8 +46,9 @@ function buildProgressBadges(prgrsSttsComCd: string, prgrsSttsCdNm: string): Pro
|
||||
return [
|
||||
{ label: MAIN_STEP_LABELS.save, state: "completed" },
|
||||
{ label: MAIN_STEP_LABELS.apply, state: "completed" },
|
||||
{ label: MAIN_STEP_LABELS.envoReview, state: "completed" },
|
||||
{ label: MAIN_STEP_LABELS.reply, state: "action" },
|
||||
{ label: MAIN_STEP_LABELS.envoReview, state: "action" },
|
||||
{ label: MAIN_STEP_LABELS.techReview, state: "pending" },
|
||||
{ label: MAIN_STEP_LABELS.reply, state: "pending" },
|
||||
];
|
||||
}
|
||||
|
||||
@@ -56,8 +57,8 @@ function buildProgressBadges(prgrsSttsComCd: string, prgrsSttsCdNm: string): Pro
|
||||
{ label: MAIN_STEP_LABELS.save, state: "completed" },
|
||||
{ label: MAIN_STEP_LABELS.apply, state: "completed" },
|
||||
{ label: MAIN_STEP_LABELS.envoReview, state: "completed" },
|
||||
{ label: MAIN_STEP_LABELS.techReview, state: "pending" },
|
||||
{ label: MAIN_STEP_LABELS.supplement, state: "action" },
|
||||
{ label: MAIN_STEP_LABELS.reply, state: "pending" },
|
||||
];
|
||||
}
|
||||
|
||||
@@ -71,16 +72,6 @@ function buildProgressBadges(prgrsSttsComCd: string, prgrsSttsCdNm: string): Pro
|
||||
];
|
||||
}
|
||||
|
||||
if (prgrsSttsComCd === "EP") {
|
||||
return [
|
||||
{ label: MAIN_STEP_LABELS.save, state: "completed" },
|
||||
{ label: MAIN_STEP_LABELS.apply, state: "completed" },
|
||||
{ label: MAIN_STEP_LABELS.envoReview, state: "completed" },
|
||||
{ label: MAIN_STEP_LABELS.techReview, state: "completed" },
|
||||
{ label: replyLabel, state: "action" },
|
||||
];
|
||||
}
|
||||
|
||||
if (prgrsSttsComCd === "TA") {
|
||||
return [
|
||||
{ label: MAIN_STEP_LABELS.save, state: "completed" },
|
||||
@@ -91,6 +82,16 @@ function buildProgressBadges(prgrsSttsComCd: string, prgrsSttsCdNm: string): Pro
|
||||
];
|
||||
}
|
||||
|
||||
if (prgrsSttsComCd === "EP") {
|
||||
return [
|
||||
{ label: MAIN_STEP_LABELS.save, state: "completed" },
|
||||
{ label: MAIN_STEP_LABELS.apply, state: "completed" },
|
||||
{ label: MAIN_STEP_LABELS.envoReview, state: "completed" },
|
||||
{ label: MAIN_STEP_LABELS.techReview, state: "completed" },
|
||||
{ label: replyLabel, state: "completed" },
|
||||
];
|
||||
}
|
||||
|
||||
return [{ label: prgrsSttsCdNm || prgrsSttsComCd || "-", state: "current" }];
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ import {
|
||||
buildSupplementReqPayload,
|
||||
buildTechReviewReplyPayload,
|
||||
toSplmntDmndSaveItem,
|
||||
} from "../../lib/save-payload-utils";
|
||||
} from "../../lib/payload-utils";
|
||||
import { type ChecklistFormState } from "../../model/view-types";
|
||||
import type { TechReviewOpinionSectionHandle } from "../sections/tech-review-opinion-section";
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { Paperclip } from "lucide-react";
|
||||
|
||||
import { formatFileSize } from "@/shared/lib/file-utils";
|
||||
import { useDownloadAttachmentByAtflCd } from "@/entities/attach";
|
||||
import type {
|
||||
@@ -19,6 +21,7 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr
|
||||
|
||||
return (
|
||||
<>
|
||||
{esntlFileList.length > 0 && (
|
||||
<SectionCollapsible title="필수 첨부파일">
|
||||
<div className="overflow-x-auto">
|
||||
<Table variant="secondary">
|
||||
@@ -48,18 +51,21 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr
|
||||
<TableCell className="text-left">
|
||||
{file.atflCd ? (
|
||||
<a
|
||||
className="cursor-pointer text-blue-600 hover:underline"
|
||||
className="inline-flex cursor-pointer items-center gap-1 text-blue-600 hover:underline"
|
||||
onClick={() => downloadAttachment(file.atflCd ?? "")}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Paperclip className="size-5 shrink-0" />
|
||||
{file.orgnlFileNm || "다운로드"}
|
||||
</a>
|
||||
) : (
|
||||
<span className="text-gray-500">첨부없음</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className="text-right">{formatFileSize(file.atflFlieSz)}</TableCell>
|
||||
<TableCell className="text-right">
|
||||
{formatFileSize(file.atflFlieSz)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
)}
|
||||
@@ -67,7 +73,9 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr
|
||||
</Table>
|
||||
</div>
|
||||
</SectionCollapsible>
|
||||
)}
|
||||
|
||||
{etcFileList.length > 0 && (
|
||||
<SectionCollapsible title="기타 첨부파일">
|
||||
<div className="overflow-x-auto">
|
||||
<Table variant="secondary">
|
||||
@@ -111,6 +119,7 @@ function AttachmentsSection({ esntlFileList, etcFileList }: AttachmentsSectionPr
|
||||
</Table>
|
||||
</div>
|
||||
</SectionCollapsible>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
|
||||
import { useUserStore } from "@/shared/lib";
|
||||
import { Field, FieldError } from "@/shared/ui/field";
|
||||
import { SectionCollapsible } from "@/widgets/pbadms-sprt";
|
||||
import {
|
||||
@@ -23,6 +24,7 @@ import type { SewerBscPlanRegistFormData } from "../../lib/sewer-bsc-plan-regist
|
||||
import { getGoalYearOptions, getLinkedGoalYears, getPlanYearOptions } from "../../lib/year-options";
|
||||
|
||||
function BasicInfoFormSection() {
|
||||
const userInfo = useUserStore((state) => state.userInfo);
|
||||
const { control, setValue, watch } = useFormContext<SewerBscPlanRegistFormData>();
|
||||
const planYearOptions = getPlanYearOptions();
|
||||
const goalYearOptions = getGoalYearOptions();
|
||||
@@ -265,7 +267,7 @@ function BasicInfoFormSection() {
|
||||
<TableHead>구분</TableHead>
|
||||
<TableCell>{sewerBscPlanSeLabel}</TableCell>
|
||||
<TableHead>신청 지자체</TableHead>
|
||||
<TableCell>{localGovLabel}</TableCell>
|
||||
<TableCell>{localGovLabel || userInfo?.laeSeNm}</TableCell>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
</Table>
|
||||
|
||||
@@ -71,6 +71,10 @@ function ChecklistSection({
|
||||
|
||||
const { total, completed, percent } = progress;
|
||||
|
||||
if (cklstResultList.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<SectionCollapsible title="체크리스트">
|
||||
<div className="flex flex-col gap-4 p-2">
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
|
||||
|
||||
import { Paperclip } from "lucide-react";
|
||||
|
||||
import { PROXY_HOST } from "@/shared/config";
|
||||
import { dayjs, getDefaultFileKey, useTus } from "@/shared/lib";
|
||||
import { Field, FieldLabel, FieldSet } from "@/shared/ui/field";
|
||||
@@ -334,11 +336,12 @@ function TechReviewOpinionTable({ items }: TechReviewOpinionTableProps) {
|
||||
<TableCell align="center">
|
||||
{item.atchFileInfo?.atflCd ? (
|
||||
<a
|
||||
className="text-blue-600 hover:underline"
|
||||
className="inline-flex cursor-pointer items-start gap-1 text-left text-blue-600 hover:underline"
|
||||
href={`${PROXY_HOST}/attach-service/api/v1/atflcd/download/${item.atchFileInfo.atflCd}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Paperclip className="my-1 size-5 shrink-0" />
|
||||
{item.atchFileInfo.orgnlFileNm || "다운로드"}
|
||||
</a>
|
||||
) : (
|
||||
|
||||
@@ -4,11 +4,10 @@ import { useId, useMemo, useState } from "react";
|
||||
import { Controller, useFieldArray, useFormContext, useWatch } from "react-hook-form";
|
||||
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { Paperclip } from "lucide-react";
|
||||
|
||||
import { getDefaultFileKey, useTus } from "@/shared/lib";
|
||||
import { Field } from "@/shared/ui/field";
|
||||
import { attachService, useDownloadAttachmentByAtflCd } from "@/entities/attach";
|
||||
import { attachService } from "@/entities/attach";
|
||||
import { useFacilityList } from "@/entities/bns-if";
|
||||
import { useNowDmgMtncGnsvy } from "@/entities/dc";
|
||||
import { SectionCollapsible } from "@/widgets/pbadms-sprt";
|
||||
@@ -226,7 +225,6 @@ function TmplntFacilityAttachments({
|
||||
}: TmplntFacilityAttachmentsProps) {
|
||||
const formId = useId();
|
||||
const { setValue } = useFormContext<SewerBscPlanRegistFormData>();
|
||||
const { mutate: downloadAttachment } = useDownloadAttachmentByAtflCd();
|
||||
const [uploadedFile, setUploadedFile] = useState<UploadedTmplntFile | null>(() =>
|
||||
atchFileGroupId && atchFileNm
|
||||
? {
|
||||
@@ -254,7 +252,6 @@ function TmplntFacilityAttachments({
|
||||
const fileInputId = `${formId}-tmplnt-atch-${facilityIndex}`;
|
||||
const uploading = uploadedFile ? (isUploading[uploadedFile.fileKey] ?? false) : false;
|
||||
const displayFileName = uploadedFile?.fileName ?? atchFileNm ?? "";
|
||||
const downloadAtflCd = uploadedFile?.atflCd || atchFileGroupId;
|
||||
const hasFile = Boolean(uploadedFile || atchFileNm);
|
||||
|
||||
async function handleFileUpload(files: FileList | null) {
|
||||
@@ -315,22 +312,14 @@ function TmplntFacilityAttachments({
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell>{facilityName} 계획평면도</TableCell>
|
||||
<TableHead data-required align="left">
|
||||
{facilityName} 계획평면도
|
||||
</TableHead>
|
||||
<TableCell className="text-center">{TMPLNT_ATCH_FORMAT_LABEL}</TableCell>
|
||||
<TableCell>
|
||||
{hasFile ? (
|
||||
<div className="flex items-center gap-2">
|
||||
{downloadAtflCd ? (
|
||||
<a
|
||||
className="inline-flex cursor-pointer items-center gap-1 text-blue-600 hover:underline"
|
||||
onClick={() => downloadAttachment(downloadAtflCd)}
|
||||
>
|
||||
<Paperclip className="size-5 shrink-0" />
|
||||
{displayFileName}
|
||||
</a>
|
||||
) : (
|
||||
<span className="text-xl">{displayFileName}</span>
|
||||
)}
|
||||
<Button
|
||||
type="button"
|
||||
size="icon"
|
||||
|
||||
@@ -245,6 +245,10 @@ function TmplntSection({ tmplntList, det, dtl }: TmplntSectionProps) {
|
||||
<div className="mt-6 space-y-2">
|
||||
<h3 className="mb-4 text-xl font-semibold">처리구역 필수 첨부파일</h3>
|
||||
<Table variant="secondary">
|
||||
<colgroup>
|
||||
<col width="35%" />
|
||||
<col width="65%" />
|
||||
</colgroup>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead align="left">파일명</TableHead>
|
||||
|
||||
@@ -79,7 +79,9 @@ function SewerBscPlanApplyDialog({ open, onOpenChange, onConfirm }: SewerBscPlan
|
||||
setTaskSeComCd("");
|
||||
}, [open]);
|
||||
|
||||
const canConfirm = Boolean(sidoComCd && sewerBscPlanSeComCd && taskSeComCd);
|
||||
const canSidoGugunSelectable = userInfo?.dtlInstCd !== "ROLE_USER05";
|
||||
const canConfirm =
|
||||
!!sewerBscPlanSeComCd && !!taskSeComCd && (!canSidoGugunSelectable || !!sidoComCd);
|
||||
|
||||
function handleConfirm() {
|
||||
if (!canConfirm) return;
|
||||
@@ -118,6 +120,7 @@ function SewerBscPlanApplyDialog({ open, onOpenChange, onConfirm }: SewerBscPlan
|
||||
<col width="35%" />
|
||||
</colgroup>
|
||||
<TableHeader>
|
||||
{canSidoGugunSelectable && (
|
||||
<TableRow>
|
||||
<TableHead data-required>시도</TableHead>
|
||||
<TableCell>
|
||||
@@ -160,6 +163,7 @@ function SewerBscPlanApplyDialog({ open, onOpenChange, onConfirm }: SewerBscPlan
|
||||
</Select>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
<TableRow>
|
||||
<TableHead data-required>계획구분</TableHead>
|
||||
<TableCell colSpan={3}>
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { useAlertStore, useUserStore } from "@/shared/lib";
|
||||
import { useAcntgSeMngTree } from "@/entities/acntg";
|
||||
import { useEsntlAtchFileMngTree } from "@/entities/esntl";
|
||||
import {
|
||||
SewerBscPlanApplySaveResponseDto,
|
||||
sewerBscPlanBaseKey,
|
||||
@@ -22,6 +23,7 @@ import {
|
||||
ChecklistFormSection,
|
||||
ContactInfoFormSection,
|
||||
isFormChecklistComplete,
|
||||
isFormEsntlAtchComplete,
|
||||
PrivacyConsentSection,
|
||||
SplmntDmndFormSection,
|
||||
} from "@/widgets/pbadms-sprt";
|
||||
@@ -34,7 +36,6 @@ import {
|
||||
mapDetailToFormData,
|
||||
} from "../lib/form-data-mapper";
|
||||
import {
|
||||
SEWER_BSC_PLAN_DOC_SE_COM_CD,
|
||||
type SewerBscPlanRegistFormData,
|
||||
sewerBscPlanRegistSchema,
|
||||
} from "../lib/sewer-bsc-plan-regist-schema";
|
||||
@@ -76,6 +77,7 @@ function SewerBscPlanFormPage({
|
||||
const isSplmntPrgrsStts = initialData?.detDto?.prgrsSttsComCd === "SL";
|
||||
|
||||
const { data: acntgTree = [] } = useAcntgSeMngTree();
|
||||
const { data: essentialFiles = [] } = useEsntlAtchFileMngTree({ docSeComCd: "SEWER" });
|
||||
const costItems = useMemo(() => buildAcntgCostItems(acntgTree), [acntgTree]);
|
||||
|
||||
const form = useForm<SewerBscPlanRegistFormData>({
|
||||
@@ -140,11 +142,21 @@ function SewerBscPlanFormPage({
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.sewerBscPlanTmplntList.some((item) => !item.atchFileGroupId?.trim())) {
|
||||
alert("처리구역 필수 첨부파일을 모두 등록해야 신청이 가능합니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isFormChecklistComplete(data.cklstResultList)) {
|
||||
alert("모든 체크리스트 항목을 체크해야 신청이 가능합니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isFormEsntlAtchComplete(essentialFiles, data.esntlAtchFileList)) {
|
||||
alert("필수 첨부파일을 모두 등록해야 신청이 가능합니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
const result = await submitForm(data, "LE");
|
||||
@@ -237,12 +249,9 @@ function SewerBscPlanFormPage({
|
||||
<BizCstMatrixFormSection />
|
||||
<FnrsCstFormSection />
|
||||
<TmplntFormSection />
|
||||
<ChecklistFormSection
|
||||
docSeComCd={SEWER_BSC_PLAN_DOC_SE_COM_CD}
|
||||
fieldPrefix="sewerBscPlan"
|
||||
/>
|
||||
<ChecklistFormSection docSeComCd="SEWER" fieldPrefix="sewerBscPlan" />
|
||||
<AttachmentsFormSection
|
||||
docSeComCd={SEWER_BSC_PLAN_DOC_SE_COM_CD}
|
||||
docSeComCd="SEWER"
|
||||
fieldPrefix="sewerBscPlanDtl"
|
||||
initialEsntlFiles={isEditMode ? initialData?.esntlFileList : undefined}
|
||||
initialEtcFiles={isEditMode ? initialData?.etcFileList : undefined}
|
||||
|
||||
@@ -11,7 +11,6 @@ import { Skeleton } from "@common/components";
|
||||
|
||||
import { needsRoleUser01AtrzResolve } from "../lib/button-config";
|
||||
import { getEditableReviewStep } from "../lib/review-step-utils";
|
||||
import { SEWER_BSC_PLAN_DOC_SE_COM_CD } from "../lib/sewer-bsc-plan-regist-schema";
|
||||
import { EMPTY_CKLST_RESULT_LIST, useChecklistFormState } from "../lib/use-checklist-form-state";
|
||||
|
||||
import { FloatingActionButtons } from "./components/floating-action-buttons";
|
||||
@@ -121,7 +120,7 @@ function SewerBscPlanViewPage({ id, propChgCycl }: SewerBscPlanViewPageProps) {
|
||||
/>
|
||||
<FloatingActionButtons
|
||||
data={data}
|
||||
docSeComCd={SEWER_BSC_PLAN_DOC_SE_COM_CD}
|
||||
docSeComCd="SEWER"
|
||||
sewerBscPlanDocNo={detDto.sewerBscPlanDocNo}
|
||||
chgCycl={chgCycl}
|
||||
prgrsSttsComCd={detDto.prgrsSttsComCd || ""}
|
||||
|
||||
@@ -188,7 +188,7 @@ export interface EsntlAtchFileSaveBase {
|
||||
|
||||
/** 보완요구 저장 공통 필드 */
|
||||
export interface SplmntDmndSaveBase {
|
||||
splmntDmndSn?: number;
|
||||
splmntDmndSn?: number | null;
|
||||
splmntArtclComCd?: string;
|
||||
splmntDmndCn?: string;
|
||||
splmntDmndDt?: string;
|
||||
|
||||
@@ -3,6 +3,7 @@ export {
|
||||
createEtcUploadKey,
|
||||
createUploadKey,
|
||||
isEtcFileKey,
|
||||
isFormEsntlAtchComplete,
|
||||
} from "./lib/attachments-form-utils";
|
||||
export {
|
||||
buildAcntgCostItems,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { getDefaultFileKey } from "@/shared/lib";
|
||||
import type { EsntlAtchFileMngTreeResponseDto } from "@/shared/model";
|
||||
|
||||
export type FieldPrefix =
|
||||
| "fnrsCnsltnMng"
|
||||
@@ -9,6 +10,11 @@ export type FieldPrefix =
|
||||
|
||||
export const ETC_FILE_KEY_PREFIX = "etc::";
|
||||
|
||||
interface EsntlAtchFileListItem {
|
||||
esntlAtchFileId: string;
|
||||
atchFileGroupId: string;
|
||||
}
|
||||
|
||||
export function atchFileGroupIdPath(fieldPrefix: FieldPrefix): string {
|
||||
return `${fieldPrefix}.atchFileGroupId`;
|
||||
}
|
||||
@@ -35,3 +41,21 @@ export function toFileAccept(rmrk: string | null | undefined): string {
|
||||
.map((ext) => (ext.startsWith(".") ? ext : `.${ext}`))
|
||||
.join(",");
|
||||
}
|
||||
|
||||
export function isFormEsntlAtchComplete(
|
||||
essentialFiles: EsntlAtchFileMngTreeResponseDto[],
|
||||
esntlAtchFileList: EsntlAtchFileListItem[],
|
||||
): boolean {
|
||||
if (essentialFiles.length === 0) return true;
|
||||
|
||||
const requiredFiles = essentialFiles.filter((file) => file.esntlAtchYn === "Y");
|
||||
if (requiredFiles.length === 0) return true;
|
||||
|
||||
const attachedIds = new Set(
|
||||
esntlAtchFileList
|
||||
.filter((item) => Boolean(item.atchFileGroupId))
|
||||
.map((item) => item.esntlAtchFileId),
|
||||
);
|
||||
|
||||
return requiredFiles.every((file) => attachedIds.has(file.esntlAtchFileId));
|
||||
}
|
||||
|
||||
@@ -72,7 +72,8 @@ function PbadmsTaskApplyDialog({
|
||||
const sidoOptions = sidoData ?? EMPTY_ADST_LIST;
|
||||
const gugunOptions = gugunData ?? EMPTY_ADST_LIST;
|
||||
const isPending = isSidoPending || isTaskSePending;
|
||||
const canConfirm = Boolean(sidoComCd && selectedCodes.length > 0);
|
||||
const canSidoGugunSelectable = userInfo?.dtlInstCd !== "ROLE_USER05";
|
||||
const canConfirm = selectedCodes.length > 0 && (!canSidoGugunSelectable || !!sidoComCd);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
@@ -121,6 +122,7 @@ function PbadmsTaskApplyDialog({
|
||||
<col width="35%" />
|
||||
</colgroup>
|
||||
<TableHeader>
|
||||
{canSidoGugunSelectable && (
|
||||
<TableRow>
|
||||
<TableHead data-required>시도</TableHead>
|
||||
<TableCell>
|
||||
@@ -163,6 +165,7 @@ function PbadmsTaskApplyDialog({
|
||||
</Select>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
<TableRow>
|
||||
<TableHead data-required>업무구분</TableHead>
|
||||
<TableCell colSpan={3}>
|
||||
|
||||
@@ -26,6 +26,10 @@ interface SupplementDemandSectionProps {
|
||||
function SupplementDemandSection({ splmntDmndList }: SupplementDemandSectionProps) {
|
||||
const { mutate: downloadAttachment } = useDownloadAttachmentByAtflCd();
|
||||
|
||||
if (splmntDmndList.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<SectionCollapsible title="보완요청 및 완료 현황">
|
||||
<div className="overflow-x-auto">
|
||||
|
||||
Reference in New Issue
Block a user