Merge remote-tracking branch 'origin/iipbs/st/dev' into feature/review-skeleton-sein
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -18,9 +18,9 @@ from "@common/components";
|
|||||||
import { useAlertStore } from "@/shared/lib";
|
import { useAlertStore } from "@/shared/lib";
|
||||||
import { type SearchFormProps, type SearchFormValues, defaultSearchFormProps } from "../type/SearchForm.type";
|
import { type SearchFormProps, type SearchFormValues, defaultSearchFormProps } from "../type/SearchForm.type";
|
||||||
import { statisticsAPi } from "@/entities/statistics/api/statistics-service";
|
import { statisticsAPi } from "@/entities/statistics/api/statistics-service";
|
||||||
import type { ApiResponse, Sido, Sgg } from "@/entities/statistics/model/statistics-interface";
|
import type { ApiResponse, SearchCondition, Sgg } from "@/entities/statistics/model/statistics-interface";
|
||||||
|
|
||||||
const getSidoListFetcher = async (): Promise<ApiResponse<Sido[]>> => {
|
const getSidoListFetcher = async (): Promise<ApiResponse<SearchCondition>> => {
|
||||||
return statisticsAPi.getSidoList();
|
return statisticsAPi.getSidoList();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -34,20 +34,8 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
|||||||
|
|
||||||
const currentYear = new Date().getFullYear();
|
const currentYear = new Date().getFullYear();
|
||||||
const defaultYear = currentYear - 1;
|
const defaultYear = currentYear - 1;
|
||||||
const startYear = currentYear - 10;
|
|
||||||
|
|
||||||
const yearOptions = Array.from({ length: currentYear - startYear + 1 }, (_, i) => currentYear - i);
|
const { data: sidoList } = useSWR<ApiResponse<SearchCondition>>(
|
||||||
|
|
||||||
const [values, setValues] = useState<SearchFormValues>({
|
|
||||||
sido: props.defaultValues?.sido || "",
|
|
||||||
gugun: props.defaultValues?.gugun || '',
|
|
||||||
year: props.defaultValues?.year || String(defaultYear),
|
|
||||||
order: props.defaultValues?.order || '',
|
|
||||||
fctName: props.defaultValues?.fctName || '',
|
|
||||||
bsnmCd: props.defaultValues?.bsnmCd || '',
|
|
||||||
});
|
|
||||||
|
|
||||||
const { data: sidoList } = useSWR<ApiResponse<Sido[]>>(
|
|
||||||
"sido-list",
|
"sido-list",
|
||||||
getSidoListFetcher,
|
getSidoListFetcher,
|
||||||
{
|
{
|
||||||
@@ -69,6 +57,15 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [values, setValues] = useState<SearchFormValues>({
|
||||||
|
sido: props.defaultValues?.sido || '',
|
||||||
|
gugun: props.defaultValues?.gugun || '',
|
||||||
|
year: props.defaultValues?.year || defaultYear.toString(),
|
||||||
|
order: props.defaultValues?.order || '',
|
||||||
|
fctName: props.defaultValues?.fctName || '',
|
||||||
|
bsnmCd: props.defaultValues?.bsnmCd || '',
|
||||||
|
});
|
||||||
|
|
||||||
const { data: sggList } = useSWR<ApiResponse<Sgg[]>>(
|
const { data: sggList } = useSWR<ApiResponse<Sgg[]>>(
|
||||||
values.sido && values.sido !== "ALL" ? ["sgg-list", values.sido] : null,
|
values.sido && values.sido !== "ALL" ? ["sgg-list", values.sido] : null,
|
||||||
getSggListFetcher,
|
getSggListFetcher,
|
||||||
@@ -111,7 +108,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSidoChange = (value: string) => {
|
const handleSidoChange = (value: string) => {
|
||||||
const selectedBsnm = sidoList?.data.find((v) => v.sido === value)?.bsnmCd || '';
|
const selectedBsnm = sidoList?.data.sidoList.find((v) => v.sido === value)?.bsnmCd || '';
|
||||||
|
|
||||||
setValues((prev) => ({
|
setValues((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
@@ -121,6 +118,10 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
props.onValuesChange?.(values);
|
||||||
|
}, [values]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card card-border">
|
<div className="card card-border">
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
@@ -136,7 +137,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
|||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="ALL">선택</SelectItem>
|
<SelectItem value="ALL">선택</SelectItem>
|
||||||
{sidoList?.data?.map((sido) => (
|
{sidoList?.data?.sidoList?.map((sido) => (
|
||||||
<SelectItem key={sido.adstDstrCd} value={sido.sido}>
|
<SelectItem key={sido.adstDstrCd} value={sido.sido}>
|
||||||
{sido.sido}
|
{sido.sido}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
@@ -175,7 +176,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
|||||||
<SelectValue placeholder="선택"></SelectValue>
|
<SelectValue placeholder="선택"></SelectValue>
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{yearOptions.map((year) => (
|
{sidoList?.data?.yearList.map((year) => (
|
||||||
<SelectItem key={year} value={String(year)}>
|
<SelectItem key={year} value={String(year)}>
|
||||||
{year}년
|
{year}년
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState } from "react";
|
import { useState, useMemo } from "react";
|
||||||
|
|
||||||
import SearchForm from "@/components/module/SearchForm";
|
import SearchForm from "@/components/module/SearchForm";
|
||||||
// import { DataGrid } from "@rsone/components";
|
// import { DataGrid } from "@rsone/components";
|
||||||
@@ -12,47 +12,68 @@ import { LoadingWithAnimation } from "@common/components";
|
|||||||
import { useAlertStore } from "@/shared/lib";
|
import { useAlertStore } from "@/shared/lib";
|
||||||
import { statisticsInputAPi } from "@/entities/statistics/api/statistics-input-service";
|
import { statisticsInputAPi } from "@/entities/statistics/api/statistics-input-service";
|
||||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||||
import type { SewerageSupplyRateItem } from "@/entities/statistics/model/statistics-input-interface";
|
import type {
|
||||||
|
SewerageSupplyRateItem,
|
||||||
|
SewerageSupplyRateRequestParams,
|
||||||
|
} from "@/entities/statistics/model/statistics-input-interface";
|
||||||
import { SeweragePenetrationRateInpColumn } from "@/components/util/column/input/SeweragePenetrationRateInpColumn";
|
import { SeweragePenetrationRateInpColumn } from "@/components/util/column/input/SeweragePenetrationRateInpColumn";
|
||||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||||
|
|
||||||
|
function getSewerageSupplyRateParams(
|
||||||
|
values: SearchFormValues,
|
||||||
|
overrides?: { yr?: string; demoYr?: string; mode?: string }
|
||||||
|
): SewerageSupplyRateRequestParams {
|
||||||
|
return {
|
||||||
|
sido: values.sido,
|
||||||
|
gugun: values.gugun === 'ALL' ? '' : values.gugun,
|
||||||
|
bsnmCd: values.bsnmCd,
|
||||||
|
yr: overrides?.yr ?? values.year,
|
||||||
|
demoYr: overrides?.demoYr ?? values.year,
|
||||||
|
...(overrides?.mode && { mode: overrides.mode }),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// 하수도 통계 관리 > 01. 하수도 보급률
|
// 하수도 통계 관리 > 01. 하수도 보급률
|
||||||
const SeweragePenetrationRateInp = () => {
|
const SeweragePenetrationRateInp = () => {
|
||||||
const { setMessage: alert } = useAlertStore((state) => state);
|
const { setMessage: alert } = useAlertStore((state) => state);
|
||||||
const [rowData, setRowData] = useState<Record<string, string | number>[]>([]);
|
const [rowData, setRowData] = useState<Record<string, string | number>[]>([]);
|
||||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||||
|
const [searchValues, setSearchValues] = useState<SearchFormValues | null>(null);
|
||||||
|
const [isEnterable, setIsEnterable] = useState<boolean>(true);
|
||||||
|
const [lastSearchedYear, setLastSearchedYear] = useState<string | null>(null);
|
||||||
|
|
||||||
|
|
||||||
|
// 최상위 관리자일땐 모든 상황에서 edit 가능하게 수정 필요.
|
||||||
|
const columnInfo = useMemo(() => {
|
||||||
|
const { columns, columnLayout } = SeweragePenetrationRateInpColumn;
|
||||||
|
return {
|
||||||
|
columnLayout,
|
||||||
|
columns: isEnterable
|
||||||
|
? columns
|
||||||
|
: columns.map((col) => ({ ...col, editable: false as const })),
|
||||||
|
};
|
||||||
|
}, [isEnterable]);
|
||||||
|
|
||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
setRowData([]);
|
setRowData([]);
|
||||||
|
setLastSearchedYear(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSearch = async (values: SearchFormValues) => {
|
const fetchSewerageSupplyRate = async (params: SewerageSupplyRateRequestParams) => {
|
||||||
try {
|
try {
|
||||||
if (values.sido !== '' && values.sido !== 'ALL') {
|
setIsLoading(true);
|
||||||
setIsLoading(true);
|
const response = await statisticsInputAPi.getSewerageSupplyRateList(params);
|
||||||
|
if (response.status === 'success' && response.data) {
|
||||||
|
const convertedData: SewerageSupplyRateItem[] = response.data.sewerageSupplyRateList.map((d) => ({
|
||||||
|
...d,
|
||||||
|
speclCntrplnAr: d.speclCntrplnAr === '' || d.speclCntrplnAr === null ? '해당없음' : d.speclCntrplnAr,
|
||||||
|
}));
|
||||||
|
|
||||||
const response = await statisticsInputAPi.getSewerageSupplyRateList({
|
setRowData(toGridRows(convertedData));
|
||||||
sido: values.sido,
|
|
||||||
gugun: values.gugun === 'ALL' ? '' : values.gugun,
|
|
||||||
bsnmCd: values.bsnmCd,
|
|
||||||
yr: values.year,
|
|
||||||
demoYr: values.year,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.status === 'success' && response.data) {
|
|
||||||
const convertedData: SewerageSupplyRateItem[] = response.data.sewerageSupplyRateList.map((d) => ({
|
|
||||||
...d,
|
|
||||||
speclCntrplnAr: d.speclCntrplnAr === '' || d.speclCntrplnAr === null ? '해당없음' : d.speclCntrplnAr,
|
|
||||||
}));
|
|
||||||
|
|
||||||
setRowData(toGridRows(convertedData));
|
|
||||||
} else {
|
|
||||||
alert(response.message);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
alert('시도를 선택해주세요.');
|
alert(response.message);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch {
|
||||||
alert('데이터 조회 중 오류가 발생했습니다.');
|
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||||
setRowData([]);
|
setRowData([]);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -60,12 +81,45 @@ const SeweragePenetrationRateInp = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSearch = async (values: SearchFormValues) => {
|
||||||
|
if (values.sido === '' || values.sido === 'ALL') {
|
||||||
|
alert('시도를 선택해주세요.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await statisticsInputAPi.checkInputPeriod(values.year || '');
|
||||||
|
|
||||||
|
if (response.status === 'success') {
|
||||||
|
setIsEnterable(response.data);
|
||||||
|
setLastSearchedYear(values.year || null);
|
||||||
|
|
||||||
|
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(values));
|
||||||
|
} else {
|
||||||
|
alert(response.message);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
alert('데이터 조회 중 오류가 발생했습니다.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const SubmitExceptionFunc = () => {
|
const SubmitExceptionFunc = () => {
|
||||||
// 예외 제출 로직
|
// 예외 제출 로직
|
||||||
};
|
};
|
||||||
|
|
||||||
const getLastYearDataFunc = () => {
|
const getLastYearDataFunc = async (values: SearchFormValues) => {
|
||||||
// 지난연도 데이터 가져오기
|
if (values.sido === '' || values.sido === 'ALL') {
|
||||||
|
alert('시도를 선택해주세요.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 실제 조회된 연도가 없으면 실행 불가
|
||||||
|
if (!lastSearchedYear) {
|
||||||
|
alert('먼저 데이터를 조회해주세요.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(values, { mode: 'PRE' }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const submitFunc = () => {
|
const submitFunc = () => {
|
||||||
@@ -78,22 +132,29 @@ const SeweragePenetrationRateInp = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<SearchForm onSubmit={handleSearch} onReset={handleReset} />
|
<SearchForm onSubmit={handleSearch} onReset={handleReset} onValuesChange={setSearchValues} />
|
||||||
<div className="card !py-0">
|
{rowData.length > 0 &&
|
||||||
<div className="flex justify-end items-center gap-[0.6rem] mx-[0.6rem]">
|
<div className="card !py-0">
|
||||||
<SubmitExceptionButton SubmitExceptionFunc={SubmitExceptionFunc} />
|
<div className="flex justify-end items-center gap-[0.6rem] mx-[0.6rem]">
|
||||||
<LastYearDataButton getLastYearDataFunc={getLastYearDataFunc} />
|
{isEnterable && <SubmitExceptionButton SubmitExceptionFunc={SubmitExceptionFunc} />}
|
||||||
<SubmitButton submitFunc={submitFunc} />
|
{isEnterable && <LastYearDataButton getLastYearDataFunc={() => getLastYearDataFunc(searchValues ?? {})} />}
|
||||||
<SaveButton saveFunc={saveFunc} />
|
{isEnterable && <SubmitButton submitFunc={submitFunc} />}
|
||||||
|
{
|
||||||
|
// 최고 관리자일땐 저장 가능하게
|
||||||
|
<SaveButton saveFunc={saveFunc} />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
{isLoading && <div className="absolute inset-0 z-50 [data-theme='black']:bg-transparent rounded-lg p-10 flex justify-center items-center">
|
{isLoading && <div className="absolute inset-0 z-50 [data-theme='black']:bg-transparent rounded-lg p-10 flex justify-center items-center">
|
||||||
<div className="relative size-[5rem]">
|
<div className="relative size-[5rem]">
|
||||||
<LoadingWithAnimation color="primary" />
|
<LoadingWithAnimation color="primary" />
|
||||||
</div>
|
</div>
|
||||||
</div>}
|
</div>}
|
||||||
<DataGrid
|
<DataGrid
|
||||||
columnInfo={SeweragePenetrationRateInpColumn}
|
key={isEnterable ? 'enterable' : 'readonly'}
|
||||||
|
columnInfo={columnInfo}
|
||||||
|
isExcelImport={(rowData.length > 0) && isEnterable}
|
||||||
rowStartNum={3}
|
rowStartNum={3}
|
||||||
fixedColumns={1}
|
fixedColumns={1}
|
||||||
rowData={rowData}
|
rowData={rowData}
|
||||||
|
|||||||
@@ -16,10 +16,11 @@ export type SearchFormProps = {
|
|||||||
userMenual?: boolean;
|
userMenual?: boolean;
|
||||||
onSubmit?: (values: SearchFormValues) => void;
|
onSubmit?: (values: SearchFormValues) => void;
|
||||||
onReset?: () => void;
|
onReset?: () => void;
|
||||||
|
onValuesChange?: (values: SearchFormValues) => void;
|
||||||
defaultValues?: SearchFormValues;
|
defaultValues?: SearchFormValues;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultSearchFormProps: Required<Omit<SearchFormProps, 'onSubmit' | 'onReset' | 'defaultValues'>> = {
|
export const defaultSearchFormProps: Required<Omit<SearchFormProps, 'onSubmit' | 'onReset' | 'onValuesChange' | 'defaultValues'>> = {
|
||||||
sido: true,
|
sido: true,
|
||||||
gugun: true,
|
gugun: true,
|
||||||
year: true,
|
year: true,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
type StatisticsInputService,
|
type StatisticsInputService,
|
||||||
type SewerageSupplyRateRequestParams,
|
type SewerageSupplyRateRequestParams,
|
||||||
type SewerageSupplyRateApiResponse,
|
type SewerageSupplyRateApiResponse,
|
||||||
|
type CheckInputPeriodResponse,
|
||||||
} from "../model/statistics-input-interface";
|
} from "../model/statistics-input-interface";
|
||||||
|
|
||||||
export class StatisticsInputAPiService implements StatisticsInputService {
|
export class StatisticsInputAPiService implements StatisticsInputService {
|
||||||
@@ -18,6 +19,14 @@ export class StatisticsInputAPiService implements StatisticsInputService {
|
|||||||
|
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async checkInputPeriod(params: string): Promise<CheckInputPeriodResponse> {
|
||||||
|
const response = await axios.get<CheckInputPeriodResponse> (
|
||||||
|
`${ENDPOINT.ST_SERVICE.INPUTCOMMON}/check-input-period?year=${params}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const statisticsInputAPi = new StatisticsInputAPiService();
|
export const statisticsInputAPi = new StatisticsInputAPiService();
|
||||||
@@ -3,16 +3,16 @@ import { ENDPOINT } from "@/shared/config";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
type StatisticsService,
|
type StatisticsService,
|
||||||
type Sido,
|
type SearchCondition,
|
||||||
type ApiResponse,
|
type ApiResponse,
|
||||||
type Sgg
|
type Sgg
|
||||||
} from "../model/statistics-interface";
|
} from "../model/statistics-interface";
|
||||||
|
|
||||||
export class StatisticsAPiService implements StatisticsService {
|
export class StatisticsAPiService implements StatisticsService {
|
||||||
|
|
||||||
public async getSidoList(): Promise<ApiResponse<Sido[]>> {
|
public async getSidoList(): Promise<ApiResponse<SearchCondition>> {
|
||||||
const response = await axios.get<ApiResponse<Sido[]>>(
|
const response = await axios.get<ApiResponse<SearchCondition>>(
|
||||||
`${ENDPOINT.ST_SERVICE.COMMON}/sido`,
|
`${ENDPOINT.ST_SERVICE.COMMON}/search-condition`,
|
||||||
);
|
);
|
||||||
|
|
||||||
return response.data;
|
return response.data;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { ApiResponse } from "./statistics-interface";
|
import type { ApiResponse } from "./statistics-interface";
|
||||||
|
|
||||||
// 하수도 보급률 API 응답의 상태 정보
|
// 하수도 보급률 데이터 항목
|
||||||
export interface SewerageSupplyRateStatusInfo {
|
export interface SewerageSupplyRateStatusInfo {
|
||||||
locgStatus: string;
|
locgStatus: string;
|
||||||
locgDt: string;
|
locgDt: string;
|
||||||
@@ -13,7 +13,6 @@ export interface SewerageSupplyRateStatusInfo {
|
|||||||
returnOpinionSm: string | null;
|
returnOpinionSm: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 하수도 보급률 데이터 항목
|
|
||||||
export interface SewerageSupplyRateItem {
|
export interface SewerageSupplyRateItem {
|
||||||
sido: string;
|
sido: string;
|
||||||
gugun: string;
|
gugun: string;
|
||||||
@@ -103,7 +102,7 @@ export interface SewerageSupplyRateResponseData {
|
|||||||
|
|
||||||
export type SewerageSupplyRateApiResponse = ApiResponse<SewerageSupplyRateResponseData> & {
|
export type SewerageSupplyRateApiResponse = ApiResponse<SewerageSupplyRateResponseData> & {
|
||||||
message: string;
|
message: string;
|
||||||
};
|
}
|
||||||
|
|
||||||
export interface SewerageSupplyRateRequestParams {
|
export interface SewerageSupplyRateRequestParams {
|
||||||
sido?: string;
|
sido?: string;
|
||||||
@@ -111,6 +110,14 @@ export interface SewerageSupplyRateRequestParams {
|
|||||||
bsnmCd?: string;
|
bsnmCd?: string;
|
||||||
yr?: string;
|
yr?: string;
|
||||||
demoYr?: string;
|
demoYr?: string;
|
||||||
|
mode?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 하수도 통계 입력 기간 조회
|
||||||
|
export interface CheckInputPeriodResponse {
|
||||||
|
status: string;
|
||||||
|
message: string;
|
||||||
|
data: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StatisticsInputService {
|
export interface StatisticsInputService {
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ export const ENDPOINT = {
|
|||||||
COMMON: "/st-management-service/api/v1/common",
|
COMMON: "/st-management-service/api/v1/common",
|
||||||
INPUT: "/st-input-service/api/v1/input",
|
INPUT: "/st-input-service/api/v1/input",
|
||||||
REVIEW: "/st-management-service/api/v1/review",
|
REVIEW: "/st-management-service/api/v1/review",
|
||||||
|
INPUTCOMMON: "/st-input-service/api/v1/common",
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user