st: fix: db 표준화 작업에 맞게 interface 및 type 수정, middleware 수정

This commit is contained in:
2026-03-05 10:10:56 +09:00
parent ff5b43e1d2
commit 63afdfc726
19 changed files with 197 additions and 175 deletions
+19 -14
View File
@@ -12,10 +12,10 @@ import {
const serverApiUrl =
process.env.NEXT_PUBLIC_SERVER_API_URL ?? "http://localhost:3000";
const linkBackendApiHost = process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST ?? "http://localhost:8080";
const stServiceUrl = ST_SERVICE_URL;
const linkBackendApiHost = process.env.NEXT_PUBLIC_LINK_BACKEND_API_HOST ?? "http://localhost:8080";
// CSP 헤더 설정 함수 (img-src만)
function addSecurityHeaders(response: NextResponse): NextResponse {
response.headers.set("Content-Security-Policy", "img-src 'self' data: https: blob:;");
@@ -28,41 +28,46 @@ export function middleware(req: NextRequest) {
const logMessages: string[] = [
`[Middleware Request] ${new Date().toISOString()}`,
`[Environment]\n Mode: ${process.env.NODE_ENV}\n Port: ${PORT}\n Proxy Host: ${PROXY_HOST}\n Server API URL: ${SERVER_API_URL}\n Site ID: ${SITE_ID}`,
`[Environment]\n Mode: ${process.env.NODE_ENV}\n Port: ${PORT}\n Proxy Host: ${PROXY_HOST}\n Server API URL: ${SERVER_API_URL}\n Site ID: ${SITE_ID}\n ST Service URL: ${stServiceUrl}`,
`[Request]\n Original Pathname: ${pathname}`,
];
if (pathname.startsWith("/st-management-service") || pathname.startsWith("/st-input-service")) {
// ST Service 처리 (dc의 /server/dc-service 패턴과 동일)
if (pathname.startsWith("/server/st-management-service") || pathname.startsWith("/server/st-input-service")) {
const requestHeaders = new Headers(req.headers);
const token = req.cookies.get(CLAIM_NAME)?.value;
const userId = req.cookies.get(AUTH_USER_ID)?.value;
const queryParams = searchParams.toString();
const newUrl = `${stServiceUrl}${pathname}${
const newUrl = `${stServiceUrl}${pathname.replace("/server", "")}${
queryParams ? `?${queryParams}` : ""
}`;
if (token) requestHeaders.set(CLAIM_NAME, token);
if (userId) requestHeaders.set(AUTH_USER_ID, userId);
// 디버깅을 위한 토큰 정보 로그
logMessages.push(` Token Debug: ${token ? 'EXISTS' : 'MISSING'}`);
logMessages.push(` UserId Debug: ${userId ? 'EXISTS' : 'MISSING'}`);
logMessages.push(` Token Debug: ${token ? "EXISTS" : "MISSING"}`);
logMessages.push(` UserId Debug: ${userId ? "EXISTS" : "MISSING"}`);
logMessages.push(` ST Service Rewritten URL: ${newUrl}`);
logMessages.push("\n--------------------------------\n");
console.log(logMessages.join("\n"));
const response = NextResponse.rewrite(new URL(newUrl), {
headers: requestHeaders,
});
return addSecurityHeaders(response);
}
if (pathname.startsWith("/server")) {
// 일반 Server API 처리 (ST 서비스 제외)
if (
pathname.startsWith("/server") &&
!pathname.startsWith("/server/st-management-service") &&
!pathname.startsWith("/server/st-input-service")
) {
const requestHeaders = new Headers(req.headers);
const token = req.cookies.get(CLAIM_NAME)?.value;
const userId = req.cookies.get(AUTH_USER_ID)?.value;
const queryParams = searchParams.toString();
const newUrl = `${serverApiUrl}${pathname.replace("/server", "")}${
queryParams ? `?${queryParams}` : ""
@@ -138,5 +143,5 @@ export function middleware(req: NextRequest) {
}
export const config = {
matcher: ["/server/:path*", "/attach-service/:path*", "/api/link/:path*", "/st-management-service/:path*", "/st-input-service/:path*", "/"],
matcher: ["/server/:path*", "/attach-service/:path*", "/api/link/:path*", "/"],
};
@@ -0,0 +1,16 @@
import { Button } from "@common/components";
interface CancelSubmitButtonProps {
cnacelSubmitFunc: () => void;
}
const CancelSubmitButton = ({ cnacelSubmitFunc }: CancelSubmitButtonProps) => {
return (
<Button className="h-[3.2rem] w-[96px]" color="red" onClick={cnacelSubmitFunc}>
<i className="ri-arrow-reset"></i>
<span>제출 취소</span>
</Button>
);
};
export default CancelSubmitButton;
+9 -9
View File
@@ -1039,21 +1039,21 @@ const DataGrid = ({
{statusInfo &&
<div className="data-grid-status-bubble flex flex-wrap items-center gap-x-4 gap-y-1">
<span>진행상황: {
statusInfo.locgStatus === null || statusInfo.locgStatus === '0' ?
statusInfo.laeSbmsnSttsCd === null || statusInfo.laeSbmsnSttsCd === '0' ?
'미작성'
:
statusInfo.locgStatus === '1' ? '작성중' : statusInfo.locgStatus === '2' ? '제출'
statusInfo.laeSbmsnSttsCd === '1' ? '작성중' : statusInfo.laeSbmsnSttsCd === '2' ? '제출'
:
statusInfo.locgStatus === '3' ? '승인' : '반려'
statusInfo.laeSbmsnSttsCd === '3' ? '승인' : '반려'
}
</span>
<span>제출일: {statusInfo.locgDt
? (statusInfo.locgDt.length === 8 && /^\d{8}$/.test(statusInfo.locgDt)
? `${statusInfo.locgDt.slice(0, 4)}-${statusInfo.locgDt.slice(4, 6)}-${statusInfo.locgDt.slice(6, 8)}`
: statusInfo.locgDt)
<span>제출일: {statusInfo.laeSbmsnYmd
? (statusInfo.laeSbmsnYmd.length === 8 && /^\d{8}$/.test(statusInfo.laeSbmsnYmd)
? `${statusInfo.laeSbmsnYmd.slice(0, 4)}-${statusInfo.laeSbmsnYmd.slice(4, 6)}-${statusInfo.laeSbmsnYmd.slice(6, 8)}`
: statusInfo.laeSbmsnYmd)
: '미제출'}</span>
<span>담당자: {statusInfo.locgCharger ? statusInfo.locgCharger : '-'}</span>
<span>연락처: {statusInfo.locgCttpc ? statusInfo.locgCttpc : '-'}</span>
<span>담당자: {statusInfo.laePicNm ? statusInfo.laePicNm : '-'}</span>
<span>연락처: {statusInfo.laePicTelNo ? statusInfo.laePicTelNo : '-'}</span>
</div>
}
{isExcelImport && (
+2 -2
View File
@@ -67,9 +67,9 @@ const SearchForm = (props: SearchFormProps = {}) => {
bsnmCd: props.defaultValues?.bsnmCd || '',
});
// isStatusMenu면 bsnmCd가 doList에 있을 때만 시군구 조회. 선택 후 옵션 유지를 위해 마지막 목록 ref 사용
const sggKey: [string, string] | null =
values.sido && values.sido !== "ALL" && (!mergedProps.isStatusMenu || doList.includes(values.bsnmCd ?? ""))
// values.sido && values.sido !== "ALL" && doList.includes(values.bsnmCd ?? "")
values.sido && values.sido !== "ALL"
? ["sgg-list", values.sido]
: null;
const { data: sggList } = useSWR<ApiResponse<Sgg[]>>(
@@ -7,6 +7,7 @@ import SubmitButton from "@/components/button/SumitButton";
import SaveButton from "@/components/button/SaveButton";
import LastYearDataButton from "@/components/button/LastYearDataButton";
import SubmitExceptionButton from "@/components/button/SubmitExceptionButton";
import CancelSubmitButton from "@/components/button/CancelSubmitButton";
import { LoadingWithAnimation } from "@common/components";
import { ConfirmDialog } from "@/shared/ui/confirm-dialog";
import SubmitDailog from "./SubmitDailog";
@@ -123,16 +124,16 @@ const SeweragePenetrationRateInp = () => {
setFooterFromApi(
commonInfo
? {
totalPopl: commonInfo.sewerBzmnTotalPopl,
poplSm: commonInfo.sewerBzmnPoplSm,
frgnrPoplSm: commonInfo.sewerBzmnFrgnrPoplSm,
totalPopl: commonInfo.sewerBzmnWholPpltnCnt,
poplSm: commonInfo.sewerBzmnDomplWholPpltnCnt,
frgnrPoplSm: commonInfo.sewerBzmnFrgnrWholPpltnCnt,
refArea: commonInfo.sewerBzmnArea,
}
: null
);
if (statusInfo && statusInfo.locgStatus) {
if (['2', '3'].includes(statusInfo.locgStatus)) {
if (statusInfo && statusInfo.laeSbmsnSttsCd) {
if (['2', '3'].includes(statusInfo.laeSbmsnSttsCd)) {
setIsEnterable(false);
} else {
setIsEnterable(isEnterable);
@@ -267,15 +268,15 @@ const SeweragePenetrationRateInp = () => {
statsYr: searchValues?.year ?? '',
userId: userInfo.userUnqId,
submitList: convertedData,
sewerBzmnFrgnrPoplSm: footerFromApi?.frgnrPoplSm,
locgCharger: submitInfo.locgCharger,
locgJob: submitInfo.locgJob,
locgDept: submitInfo.locgDept,
locgCttpc: submitInfo.locgCttpc,
locgCnfirmNm: submitInfo.locgCnfirmNm,
locgCnfirmJob: submitInfo.locgCnfirmJob,
locgCnfirmDept: submitInfo.locgCnfirmDept,
locgCnfirmPh: submitInfo.locgCnfirmPh,
sewerBzmnFrgnrWholPpltnCnt: footerFromApi?.frgnrPoplSm,
laePicNm: submitInfo.laePicNm,
laeKbrdrJbgdNm: submitInfo.laeKbrdrJbgdNm,
laeKbrdrDeptNm: submitInfo.laeKbrdrDeptNm,
laePicTelNo: submitInfo.laePicTelNo,
laeIdfrNm: submitInfo.laeIdfrNm,
laeIdfrJbgdNm: submitInfo.laeIdfrJbgdNm,
laeIdfrDeptNm: submitInfo.laeIdfrDeptNm,
laeIdfrTelNo: submitInfo.laeIdfrTelNo,
};
const response = await StatisticsInputSewSupplyRateApi.submitSewerageSupplyRate(requestData);
@@ -369,7 +370,7 @@ const SeweragePenetrationRateInp = () => {
statsYr: searchValues?.year ?? '', // 통계 연도
userId: userInfo.userUnqId, // 사용자
saveList: convertedData, // 저장 데이터
sewerBzmnFrgnrPoplSm: footerFromApi?.frgnrPoplSm // 행정참고자료 외국인 합계
sewerBzmnFrgnrWholPpltnCnt: footerFromApi?.frgnrPoplSm // 행정참고자료 외국인 합계
};
if (isAdminInfo) {
@@ -406,8 +407,10 @@ const SeweragePenetrationRateInp = () => {
<SubmitExceptionButton SubmitExceptionFunc={SubmitExceptionFunc} />
<LastYearDataButton getLastYearDataFunc={() => getLastYearDataFunc(searchValues ?? {})} />
<SubmitButton submitFunc={submitFunc} />
</>
)}
{statusInfo?.laeSbmsnSttsCd === '2' && <CancelSubmitButton cnacelSubmitFunc={() => console.log('test')} />}
{(isEnterable && (doList.includes(lastSearchedValues?.bsnmCd || '') ? Boolean(lastSearchedValues?.gugun && lastSearchedValues.gugun !== 'ALL') : true) || isAdminInfo) && <SaveButton saveFunc={saveFunc} />}
</div>
</div>
@@ -66,7 +66,7 @@ const StatsInputStatusInp = () => {
return (
<>
<div className="relative">
<SearchForm onSubmit={handleSearch} onReset={handleReset} isStatusMenu={true} />
<SearchForm onSubmit={handleSearch} onReset={handleReset} />
<div className="card !py-0">
<div className="flex justify-end items-center gap-[0.6rem] m-[0.6rem]">
<RejectButton rejectFunc={rejectFunc} />
@@ -37,7 +37,7 @@ function formatPhoneWithHyphen(value: string): string {
return `${digits.slice(0, 3)}-${digits.slice(3, 6)}-${digits.slice(6, 10)}`;
}
const PHONE_FIELDS: (keyof StatisticsInputSubmitInfoFormData)[] = ["locgCttpc", "locgCnfirmPh"];
const PHONE_FIELDS: (keyof StatisticsInputSubmitInfoFormData)[] = ["laePicTelNo", "laeIdfrTelNo"];
interface SubmitDialogProps {
open: boolean;
@@ -48,26 +48,26 @@ interface SubmitDialogProps {
}
const defaultValues: StatisticsInputSubmitInfoFormData = {
locgCharger: "",
locgJob: "",
locgDept: "",
locgCttpc: "",
locgCnfirmNm: "",
locgCnfirmJob: "",
locgCnfirmDept: "",
locgCnfirmPh: "",
laePicNm: "",
laeKbrdrJbgdNm: "",
laeKbrdrDeptNm: "",
laePicTelNo: "",
laeIdfrNm: "",
laeIdfrJbgdNm: "",
laeIdfrDeptNm: "",
laeIdfrTelNo: "",
};
function statusInfoToFormData(info: SewerageSupplyRateStatusInfo): StatisticsInputSubmitInfoFormData {
return {
locgCharger: info.locgCharger ?? "",
locgJob: info.locgJob ?? "",
locgDept: info.locgDept ?? "",
locgCttpc: info.locgCttpc ?? "",
locgCnfirmNm: info.locgCnfirmNm ?? "",
locgCnfirmJob: info.locgCnfirmJob ?? "",
locgCnfirmDept: info.locgCnfirmDept ?? "",
locgCnfirmPh: info.locgCnfirmPh ?? "",
laePicNm: info.laePicNm ?? "",
laeKbrdrJbgdNm: info.laeKbrdrJbgdNm ?? "",
laeKbrdrDeptNm: info.laeKbrdrDeptNm ?? "",
laePicTelNo: info.laePicTelNo ?? "",
laeIdfrNm: info.laeIdfrNm ?? "",
laeIdfrJbgdNm: info.laeIdfrJbgdNm ?? "",
laeIdfrDeptNm: info.laeIdfrDeptNm ?? "",
laeIdfrTelNo: info.laeIdfrTelNo ?? "",
};
}
@@ -95,14 +95,14 @@ const SubmitDailog = ({ open, onOpenChange, statusInfo, onConfirm }: SubmitDialo
}
const rows: { name: keyof StatisticsInputSubmitInfoFormData; label: string; placeholder: string }[] = [
{ name: "locgCharger", label: "작성자 명", placeholder: "작성자 명 입력" },
{ name: "locgJob", label: "작성자 직제", placeholder: "작성자 직제 입력" },
{ name: "locgDept", label: "작성자 부서", placeholder: "작성자 부서 입력" },
{ name: "locgCttpc", label: "작성자 연락처", placeholder: "작성자 연락처 입력" },
{ name: "locgCnfirmNm", label: "승인자명", placeholder: "승인자명 입력" },
{ name: "locgCnfirmJob", label: "승인자 직제", placeholder: "승인자 직제 입력" },
{ name: "locgCnfirmDept", label: "승인자 부서", placeholder: "승인자 부서 입력" },
{ name: "locgCnfirmPh", label: "승인자 연락처", placeholder: "승인자 연락처" },
{ name: "laePicNm", label: "작성자 명", placeholder: "작성자 명 입력" },
{ name: "laeKbrdrJbgdNm", label: "작성자 직제", placeholder: "작성자 직제 입력" },
{ name: "laeKbrdrDeptNm", label: "작성자 부서", placeholder: "작성자 부서 입력" },
{ name: "laePicTelNo", label: "작성자 연락처", placeholder: "작성자 연락처 입력" },
{ name: "laeIdfrNm", label: "승인자명", placeholder: "승인자명 입력" },
{ name: "laeIdfrJbgdNm", label: "승인자 직제", placeholder: "승인자 직제 입력" },
{ name: "laeIdfrDeptNm", label: "승인자 부서", placeholder: "승인자 부서 입력" },
{ name: "laeIdfrTelNo", label: "승인자 연락처", placeholder: "승인자 연락처" },
];
return (
@@ -0,0 +1,7 @@
const LogHistory = () => {
return (
<></>
);
};
export default LogHistory;
@@ -18,7 +18,6 @@ export type SearchFormProps = {
onReset?: () => void;
onValuesChange?: (values: SearchFormValues) => void;
defaultValues?: SearchFormValues;
isStatusMenu?: boolean;
};
export const defaultSearchFormProps: Required<Omit<SearchFormProps, 'onSubmit' | 'onReset' | 'onValuesChange' | 'defaultValues'>> = {
@@ -28,5 +27,4 @@ export const defaultSearchFormProps: Required<Omit<SearchFormProps, 'onSubmit' |
order: false,
fctName: false,
userMenual: false,
isStatusMenu: false,
};
@@ -1,4 +1,4 @@
import { ValueType } from "realgrid";
// import { ValueType } from "realgrid";
/**
* 하수도 통계 관리 > 00. 통계 입력 현황
@@ -10,15 +10,15 @@ export const StatsInputStatusInpColumn = {
{ name: 'gugun', fieldName: 'gugun', header: { text: '시군구' }, editable: false },
{ name: 'menuCd', fieldName: 'menuCd', header: { text: '메뉴코드' }, visible: false, editable: false },
{ name: 'menuNm', fieldName: 'menuNm', header: { text: '구분' }, editable: false, width: 220 },
{ name: 'locgStatusNm', fieldName: 'locgStatusNm', header: { text: '진행상황' }, editable: false },
{ name: 'inputRate', fieldName: 'inputRate', header: { text: '작성률' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'locgCharger', fieldName: 'locgCharger', header: { text: '작성자' }, editable: false },
{ name: 'locgCttpc', fieldName: 'locgCttpc', header: { text: '작성자연락처' }, editable: false },
{ name: 'locgDept', fieldName: 'locgDept', header: { text: '부서' }, editable: false },
{ name: 'locgJob', fieldName: 'locgJob', header: { text: '직제' }, editable: false },
{ name: 'locgCnfirmNm', fieldName: 'locgCnfirmNm', header: { text: '승인자' }, editable: false },
{ name: 'locgCnfirmDept', fieldName: 'locgCnfirmDept', header: { text: '부서' }, editable: false },
{ name: 'locgCnfirmJob', fieldName: 'locgCnfirmJob', header: { text: '직제' }, editable: false },
{ name: 'laeSbmsnSttsCdNm', fieldName: 'laeSbmsnSttsCdNm', header: { text: '진행상황' }, editable: false },
// { name: 'inputRate', fieldName: 'inputRate', header: { text: '작성률' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
{ name: 'laePicNm', fieldName: 'laePicNm', header: { text: '작성자' }, editable: false },
{ name: 'laePicTelNo', fieldName: 'laePicTelNo', header: { text: '작성자연락처' }, editable: false },
{ name: 'laeKbrdrDeptNm', fieldName: 'laeKbrdrDeptNm', header: { text: '부서' }, editable: false },
{ name: 'laeKbrdrJbgdNm', fieldName: 'laeKbrdrJbgdNm', header: { text: '직제' }, editable: false },
{ name: 'laeIdfrNm', fieldName: 'laeIdfrNm', header: { text: '승인자' }, editable: false },
{ name: 'laeIdfrDeptNm', fieldName: 'laeIdfrDeptNm', header: { text: '부서' }, editable: false },
{ name: 'laeIdfrJbgdNm', fieldName: 'laeIdfrJbgdNm', header: { text: '직제' }, editable: false },
{ name: 'returnOpinionSm', fieldName: 'returnOpinionSm', header: { text: '반려사유' }, editable: false },
],
@@ -32,15 +32,15 @@ export const StatsInputStatusInpColumn = {
hideChildHeaders: false,
header: { text: '하수도사업자' },
items: [
'locgStatusNm',
'inputRate',
'locgCharger',
'locgCttpc',
'locgDept',
'locgJob',
'locgCnfirmNm',
'locgCnfirmDept',
'locgCnfirmJob',
'laeSbmsnSttsCdNm',
// 'inputRate',
'laePicNm',
'laePicTelNo',
'laeKbrdrDeptNm',
'laeKbrdrJbgdNm',
'laeIdfrNm',
'laeIdfrDeptNm',
'laeIdfrJbgdNm',
'returnOpinionSm'
],
},
@@ -1,7 +1,7 @@
import axios from "axios";
import { ENDPOINT } from "@/shared/config";
import { stClient } from "@/shared/api/client";
import {
import {
type StatisticsInputSewSupplyRateService,
type SewerageSupplyRateRequestParams,
type SewerageSupplyRateApiResponse,
@@ -12,39 +12,33 @@ import {
export class StatisticsInputSewSupplyRateApiService implements StatisticsInputSewSupplyRateService {
public async getSewerageSupplyRateList(params: SewerageSupplyRateRequestParams): Promise<SewerageSupplyRateApiResponse> {
const response = await axios.get<SewerageSupplyRateApiResponse> (
const response = await stClient.get<SewerageSupplyRateApiResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewerage-supply-rate`,
{
params: params
}
{ params }
);
return response.data;
}
public async checkInputPeriod(params: string): Promise<CheckInputPeriodResponse> {
const response = await axios.get<CheckInputPeriodResponse> (
const response = await stClient.get<CheckInputPeriodResponse>(
`${ENDPOINT.ST_SERVICE.INPUTCOMMON}/check-input-period?year=${params}`,
);
return response.data;
}
public async saveSewerageSupplyRate(params: SewerageSupplyRateSaveRequest): Promise<SewerageSupplyRateSaveApiResponse> {
const response = await axios.post<SewerageSupplyRateSaveApiResponse> (
const response = await stClient.post<SewerageSupplyRateSaveApiResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewerage-supply-rate`,
params
params,
);
return response.data;
}
public async submitSewerageSupplyRate(params: SewerageSupplyRateSaveRequest): Promise<SewerageSupplyRateSaveApiResponse> {
const response = await axios.post<SewerageSupplyRateSaveApiResponse> (
const response = await stClient.post<SewerageSupplyRateSaveApiResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/sewerage-supply-rate/submit`,
params
params,
);
return response.data;
}
}
@@ -1,7 +1,7 @@
import axios from "axios";
import { ENDPOINT } from "@/shared/config";
import { stClient } from "@/shared/api/client";
import type {
import type {
StatisticsInputStatusService,
StatsInputStatusListRequestParams,
StatsInputStatusListApiResponse,
@@ -9,15 +9,12 @@ import type {
export class StatisticsInputStatusApiService implements StatisticsInputStatusService {
public async getStatisticsInputStatusList(param: StatsInputStatusListRequestParams): Promise<StatsInputStatusListApiResponse> {
const response = await axios.get<StatsInputStatusListApiResponse> (
const response = await stClient.get<StatsInputStatusListApiResponse>(
`${ENDPOINT.ST_SERVICE.INPUT}/stats-input-status`,
{
params: param
}
{ params: param },
);
return response.data;
};
}
}
export const StatisticsInputStatusApi = new StatisticsInputStatusApiService();
@@ -1,5 +1,5 @@
import axios from "axios";
import { ENDPOINT } from "@/shared/config";
import { stClient } from "@/shared/api/client";
import {
@@ -38,7 +38,7 @@ export class StatisticsManagementApiService {
public async getStatsInputStatusList(
params: { yr?: string; bsnmCd?: string; sido?: string; gugun?: string }
): Promise<StatsInputStatusReviewApiResponse> {
const response = await axios.get<StatsInputStatusReviewApiResponse>(
const response = await stClient.get<StatsInputStatusReviewApiResponse>(
`${ENDPOINT.ST_SERVICE.REVIEW}/input-status`,
{ params }
);
@@ -52,7 +52,7 @@ export class StatisticsManagementApiService {
public async getSewerageSupplyRateReviewList(
params: SewerageSupplyRateReviewRequestParams
): Promise<SewerageSupplyRateReviewApiResponse> {
const response = await axios.get<SewerageSupplyRateReviewApiResponse>(
const response = await stClient.get<SewerageSupplyRateReviewApiResponse>(
`${ENDPOINT.ST_SERVICE.REVIEW}/supply-rate`,
{ params }
);
@@ -66,7 +66,7 @@ export class StatisticsManagementApiService {
public async getSewagePipeReviewRegionalList(
params: SewagePipeReviewRequestParams
): Promise<SewagePipeReviewRegionalApiResponse> {
const response = await axios.get<SewagePipeReviewRegionalApiResponse>(
const response = await stClient.get<SewagePipeReviewRegionalApiResponse>(
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-pipe/regional-status`,
{ params }
);
@@ -80,7 +80,7 @@ export class StatisticsManagementApiService {
public async getSewagePipeFacilityList(
params: SewagePipeReviewRequestParams
): Promise<SewagePipeFacilityApiResponse> {
const response = await axios.get<SewagePipeFacilityApiResponse>(
const response = await stClient.get<SewagePipeFacilityApiResponse>(
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-pipe/facility-status`,
{ params }
);
@@ -99,7 +99,7 @@ export class StatisticsManagementApiService {
gugun?: string;
}
): Promise<SewerPipeTypeApiResponse> {
const response = await axios.get<SewerPipeTypeApiResponse>(
const response = await stClient.get<SewerPipeTypeApiResponse>(
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-pipe/type-status`,
{ params }
);
@@ -118,7 +118,7 @@ export class StatisticsManagementApiService {
gugun?: string;
}
): Promise<SewerPipeDiamApiResponse> {
const response = await axios.get<SewerPipeDiamApiResponse>(
const response = await stClient.get<SewerPipeDiamApiResponse>(
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-pipe/diam-status`,
{ params }
);
@@ -132,7 +132,7 @@ export class StatisticsManagementApiService {
public async getSewerPipeMtcList(
params: SewerPipeMtcRequestParams
): Promise<SewerPipeMtcApiResponse> {
const response = await axios.get<SewerPipeMtcApiResponse>(
const response = await stClient.get<SewerPipeMtcApiResponse>(
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-pipe-mtc/repair`,
{ params }
);
@@ -151,7 +151,7 @@ export class StatisticsManagementApiService {
gugun?: string;
}
): Promise<SewerPipeDrdgApiResponse> {
const response = await axios.get<SewerPipeDrdgApiResponse>(
const response = await stClient.get<SewerPipeDrdgApiResponse>(
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-pipe-mtc/dredging`,
{ params }
);
@@ -170,7 +170,7 @@ export class StatisticsManagementApiService {
gugun?: string;
}
): Promise<SewerReservoirRegionalApiResponse> {
const response = await axios.get<SewerReservoirRegionalApiResponse>(
const response = await stClient.get<SewerReservoirRegionalApiResponse>(
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-reservoir/facilities`,
{ params }
);
@@ -189,7 +189,7 @@ export class StatisticsManagementApiService {
gugun?: string;
}
): Promise<PumpingStationRegionalApiResponse> {
const response = await axios.get<PumpingStationRegionalApiResponse>(
const response = await stClient.get<PumpingStationRegionalApiResponse>(
`${ENDPOINT.ST_SERVICE.REVIEW}/sewer-reservoir/pumping-stations`,
{ params }
);
@@ -209,7 +209,7 @@ export class StatisticsManagementApiService {
bscFctNm?: string; // 펌프장명 (시설명)
}
): Promise<MediationPumpStationApiResponse> {
const response = await axios.get<MediationPumpStationApiResponse>(
const response = await stClient.get<MediationPumpStationApiResponse>(
`${ENDPOINT.ST_SERVICE.REVIEW}/mediation-pump-stations`,
{ params }
);
@@ -1,33 +1,26 @@
import axios from "axios";
import { ENDPOINT } from "@/shared/config";
import { stClient } from "@/shared/api/client";
import {
type StatisticsService,
type SearchCondition,
type ApiResponse,
type Sgg
type Sgg,
} from "../model/statistics-interface";
export class StatisticsAPiService implements StatisticsService {
public async getSidoList(): Promise<ApiResponse<SearchCondition>> {
const response = await axios.get<ApiResponse<SearchCondition>>(
const response = await stClient.get<ApiResponse<SearchCondition>>(
`${ENDPOINT.ST_SERVICE.COMMON}/search-condition`,
);
return response.data;
};
}
public async getSggList(sidoName: string): Promise<ApiResponse<Sgg[]>> {
const response = await axios.get<ApiResponse<Sgg[]>>(
const response = await stClient.get<ApiResponse<Sgg[]>>(
`${ENDPOINT.ST_SERVICE.COMMON}/sgg`,
{
params: {
sidoName: sidoName,
},
}
{ params: { sidoName } },
);
return response.data;
}
}
@@ -13,15 +13,15 @@ export interface StatsInputStatusList {
gugun?: string;
menuCd?: string;
menuNm?: string;
locgStatusNm?: string;
laeSbmsnSttsCdNm?: string;
inputRate?: number;
locgCharger?: string;
locgCttpc?: string;
locgDept?: string;
locgJob?: string;
locgCnfirmNm?: string;
locgCnfirmDept?: string;
locgCnfirmJob?: string;
laePicNm?: string;
laePicTelNo?: string;
laeKbrdrDeptNm?: string;
laeKbrdrJbgdNm?: string;
laeIdfrNm?: string;
laeIdfrDeptNm?: string;
laeIdfrJbgdNm?: string;
returnOpinionSm?: string;
}
@@ -2,14 +2,14 @@ import { z } from "zod";
export const statisticsInputSubmitInfoSchema = z.object({
// 작성자 명, 작성자 직제, 작성자 부서, 작성자 연락처, 승인자명, 승인자 직제, 승인자 부서, 승인자 연락처 (전부 필수)
locgCharger: z.string().min(1, "작성자 명을 입력하세요"),
locgJob: z.string().min(1, "작성자 직제를 입력하세요"),
locgDept: z.string().min(1, "작성자 부서를 입력하세요"),
locgCttpc: z.string().min(1, "작성자 연락처를 입력하세요"),
locgCnfirmNm: z.string().min(1, "승인자명을 입력하세요"),
locgCnfirmJob: z.string().min(1, "승인자 직제를 입력하세요"),
locgCnfirmDept: z.string().min(1, "승인자 부서를 입력하세요"),
locgCnfirmPh: z.string().min(1, "승인자 연락처를 입력하세요"),
laePicNm: z.string().min(1, "작성자 명을 입력하세요"),
laeKbrdrJbgdNm: z.string().min(1, "작성자 직제를 입력하세요"),
laeKbrdrDeptNm: z.string().min(1, "작성자 부서를 입력하세요"),
laePicTelNo: z.string().min(1, "작성자 연락처를 입력하세요"),
laeIdfrNm: z.string().min(1, "승인자명을 입력하세요"),
laeIdfrJbgdNm: z.string().min(1, "승인자 직제를 입력하세요"),
laeIdfrDeptNm: z.string().min(1, "승인자 부서를 입력하세요"),
laeIdfrTelNo: z.string().min(1, "승인자 연락처를 입력하세요"),
});
export type StatisticsInputSubmitInfoFormData = z.infer<
@@ -2,29 +2,29 @@ import type { ApiResponse } from "./statistics-interface";
// 하수도 보급률 데이터 항목
export interface SewerageSupplyRateStatusInfo {
locgStatus: string | null;
locgDt: string | null;
locgCharger: string | null;
locgCttpc: string | null;
locgJob: string | null;
laeSbmsnSttsCd: string | null;
laeSbmsnYmd: string | null;
laePicNm: string | null;
laePicTelNo: string | null;
laeKbrdrJbgdNm: string | null;
prvnStatus: string | null;
dcsnStatus: string | null;
wrterOpinionSm: string | null;
chckerOpinionSm: string | null;
returnOpinionSm: string | null;
locgCnfirmDept: string | null;
locgCnfirmJob: string | null;
locgCnfirmNm: string | null;
locgCnfirmPh: string | null;
locgDept: string | null;
laeIdfrDeptNm: string | null;
laeIdfrJbgdNm: string | null;
laeIdfrNm: string | null;
laeIdfrTelNo: string | null;
laeKbrdrDeptNm: string | null;
}
export interface SewerageSupplyRateCommonInfo {
sewerBzmnArea: number;
sewerBzmnCd: string;
sewerBzmnFrgnrPoplSm: number;
sewerBzmnPoplSm: number;
sewerBzmnTotalPopl: number;
sewerBzmnFrgnrWholPpltnCnt: number;
sewerBzmnDomplWholPpltnCnt: number;
sewerBzmnWholPpltnCnt: number;
piplFcltyExtn: number;
piplPlanExtn: number;
swagePplPsplyRt: number;
@@ -135,17 +135,17 @@ export interface SewerageSupplyRateSaveRequest {
ctpvNm: string;
sewerBzmnCd: string;
userId: string;
sewerBzmnFrgnrPoplSm?: number;
sewerBzmnFrgnrWholPpltnCnt?: number;
saveList?: SewerageSupplyRateSaveItem[];
submitList?: SewerageSupplyRateSaveItem[];
locgCharger?: string;
locgJob?: string;
locgDept?: string;
locgCttpc?: string;
locgCnfirmNm?: string;
locgCnfirmJob?: string;
locgCnfirmDept?: string;
locgCnfirmPh?: string;
laePicNm?: string;
laeKbrdrJbgdNm?: string;
laeKbrdrDeptNm?: string;
laePicTelNo?: string;
laeIdfrNm?: string;
laeIdfrJbgdNm?: string;
laeIdfrDeptNm?: string;
laeIdfrTelNo?: string;
superAdmin?: string;
}
+9 -2
View File
@@ -1,11 +1,18 @@
import axios, { type AxiosInstance } from "axios";
import { Client } from "@common/network";
import { BASE_URL } from "../config/api";
import { SITE_ID } from "../config/env";
import { BASE_URL, ST_SERVICE_BASE_URL } from "../config/api";
import { AUTH_USER_ID, CLAIM_NAME, SITE_ID } from "../config/env";
import { setCookie } from "../lib";
import Cookies from "js-cookie";
setCookie("site-id-key", SITE_ID);
export const client = Client.getInstance({
baseURL: BASE_URL,
siteId: SITE_ID,
});
export const stClient = Client.getInstance({
baseURL: ST_SERVICE_BASE_URL,
siteId: SITE_ID,
});
+2
View File
@@ -2,6 +2,8 @@ import { PROXY_HOST } from "./env";
export const BASE_URL = `${PROXY_HOST}/server`;
export const ST_SERVICE_BASE_URL = `${PROXY_HOST}/server`;
export const ENDPOINT = {
ATTACH_SERVICE: {
TUS_UPLOAD: "/attach-service/api/v1/tus/upload",