자동차 검사 과태료 시스템(web)
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
Go to file
박성영 a6b96a8f45 검색조건이 달라졌을 경우, 감지 및 메시지 표출 함수 추가
README.md 배포 커멘드 추가
4 weeks ago
DB 자동차 과태료 대상 테이블 컬럼 추가 1 month ago
docs 상품용, 이첩 TEST CASE 작성, 테스트 진행 4 weeks ago
lib jni lib 추가 1 month ago
src 검색조건이 달라졌을 경우, 감지 및 메시지 표출 함수 추가 4 weeks ago
.gitignore 용인시 수지구청 자동차 검사 과태료 시스템 1 month ago
README.md 검색조건이 달라졌을 경우, 감지 및 메시지 표출 함수 추가 4 weeks ago
build.gradle feat: VMIS-interface 통합 (Spring Boot 2.7 호환) 1 month ago
gradle.properties 용인시 수지구청 자동차 검사 과태료 시스템 1 month ago

README.md

VIPS - Vehicle Information Processing System

프로젝트 개요

VIPS는 자동차 정보 조회 시스템으로, 정부 VMIS(Vehicle Management Information System)와 연계하여 차량 기본정보 및 등록원부 정보를 조회하는 Spring Boot 기반 웹 애플리케이션입니다.

주요 기능

  • 차량 기본정보 조회: 차량번호로 기본사항 조회 (차대번호, 소유자 정보, 차종 등)
  • 차량 등록원부 조회: 자동차등록원부(갑) 정보 조회
  • 통합 조회: 기본정보 + 등록원부 정보를 한 번에 조회
  • GPKI 인증: 정부 시스템과의 안전한 통신을 위한 GPKI 암호화 지원
  • 이력 관리: 모든 조회 요청/응답 이력을 데이터베이스에 저장

아키텍처

동작 모드

VIPS는 두 가지 모드로 동작하며, 설정을 통해 전환할 수 있습니다:

1. Internal Mode (내부 모듈 직접 호출)

  • VMIS 모듈을 애플리케이션 내부에 직접 통합하여 정부 API 호출
  • 네트워크 오버헤드 없이 직접 호출로 성능 향상
  • 단일 서버 환경에 적합
Client → VehicleInterfaceController
       → InternalVehicleInfoServiceImpl
       → VmisCarBassMatterInqireService / VmisCarLedgerFrmbkService
       → GovernmentApiClient
       → 정부 VMIS API

2. External Mode (외부 REST API 호출)

  • 별도로 실행 중인 VIPS 서버의 REST API를 호출
  • 서비스 분리를 통한 확장성 및 유지보수성 향상
  • MSA(Microservices Architecture) 환경에 적합
Client → VehicleInterfaceController
       → ExternalVehicleInfoServiceImpl
       → ExternalVehicleApiServiceImpl (RestTemplate)
       → VIPS 서버 (별도 실행)
       → 정부 VMIS API

모드 설정 방법

application.yml 또는 환경별 설정 파일에서 설정:

vmis:
  integration:
    mode: internal  # 또는 external

모드 분기 메커니즘

VIPS는 Spring Boot의 @ConditionalOnProperty 어노테이션을 활용하여 설정값에 따라 자동으로 적절한 구현체를 선택합니다.

핵심 컴포넌트

1. VehicleInfoService (인터페이스)

public interface VehicleInfoService {
    VehicleApiResponseVO getVehicleInfo(String vehicleNumber);
    VehicleApiResponseVO getVehicleInfo(BasicRequest basicRequest);
    BasicResponse getBasicInfo(BasicRequest request);
    LedgerResponse getLedgerInfo(LedgerRequest request);
    // ...
}

2. InternalVehicleInfoServiceImpl (Internal 모드 구현체)

@Service
@ConditionalOnProperty(name = "vmis.integration.mode", havingValue = "internal")
public class InternalVehicleInfoServiceImpl implements VehicleInfoService {
    // 내부 VMIS 모듈 직접 호출 로직
}
  • vmis.integration.mode=internal 일 때만 Bean으로 등록
  • 내부 VMIS 서비스를 직접 호출
  • GPKI 암호화 처리
  • 데이터베이스에 이력 저장

3. ExternalVehicleInfoServiceImpl (External 모드 구현체)

@Service
@ConditionalOnProperty(name = "vmis.integration.mode", havingValue = "external", matchIfMissing = true)
public class ExternalVehicleInfoServiceImpl implements VehicleInfoService {
    // 외부 REST API 호출 로직
}
  • vmis.integration.mode=external 일 때만 Bean으로 등록
  • matchIfMissing = true: 설정값이 없으면 External 모드가 기본값
  • ExternalVehicleApiService를 통해 외부 서버 REST API 호출

4. VmisIntegrationConfig (통합 설정 및 모니터링)

@Configuration
public class VmisIntegrationConfig {

    @Bean
    public CommandLineRunner vmisIntegrationModeLogger(VehicleInfoService vehicleInfoService) {
        // 애플리케이션 시작 시 현재 모드 및 설정 정보 출력
    }
}

동작 원리

  1. 애플리케이션 시작 시

    • Spring Boot가 vmis.integration.mode 설정값 확인
    • 조건에 맞는 VehicleInfoService 구현체를 Bean으로 등록
    • 다른 구현체는 Bean으로 등록되지 않음
  2. 컨트롤러에서 서비스 호출 시

    @RestController
    public class VehicleInterfaceController {
    
        // Spring이 자동으로 적절한 구현체 주입
        private final VehicleInfoService vehicleInfoService;
    
        @PostMapping("/info.ajax")
        public ResponseEntity<Envelope<VehicleApiResponseVO>> info(...) {
            // 설정에 따라 Internal 또는 External 구현체가 실행됨
            VehicleApiResponseVO resp = vehicleInfoService.getVehicleInfo(request);
            return ResponseEntity.ok(new Envelope<>(resp));
        }
    }
    
  3. 모드 확인 로그

    애플리케이션 시작 시 콘솔에 다음과 같은 로그가 출력됩니다:

    Internal 모드:

    ========================================
    VMIS Integration Mode: internal
    Active Implementation: InternalVehicleInfoServiceImpl
    ========================================
    [Internal Mode] 내부 VMIS 모듈을 직접 사용합니다
      - 정부 API 호스트: https://gov-api-url
      - 기본사항 조회 경로: /api/basic
      - 등록원부 조회 경로: /api/ledger
      - GPKI 암호화: Y
      - 연결 타임아웃: 30000ms
      - 읽기 타임아웃: 60000ms
    

    External 모드:

    ========================================
    VMIS Integration Mode: external
    Active Implementation: ExternalVehicleInfoServiceImpl
    ========================================
    [External Mode] 외부 REST API를 사용합니다
      - 외부 API Base URL: http://localhost:8081/api/v1/vehicles
      - 연결 타임아웃: 10000ms
      - 읽기 타임아웃: 30000ms
    

모드 전환 시 주의사항

Internal → External 전환 시:

  1. 외부 VIPS 서버가 실행 중이어야 함
  2. vmis.external.api.url.base 설정 필요
  3. 네트워크 방화벽 설정 확인
  4. GPKI 암호화는 외부 서버에서 처리됨

External → Internal 전환 시:

  1. GPKI 인증서 설정 필요
  2. 정부 API 직접 호출을 위한 네트워크 설정
  3. vmis.gov.host, vmis.gov.services 설정 필요
  4. 데이터베이스 이력 저장용 테이블 필요

관련 소스 파일

모드 분기 관련 핵심 파일:

src/main/java/go/kr/project/api/
├── config/
│   └── VmisIntegrationConfig.java              # 통합 모드 설정 및 로깅
│
├── service/
│   └── VehicleInfoService.java                  # 공통 인터페이스
│
├── internal/service/impl/
│   └── InternalVehicleInfoServiceImpl.java      # Internal 모드 구현체
│                                                 # @ConditionalOnProperty(havingValue = "internal")
│
└── external/service/impl/
    └── ExternalVehicleInfoServiceImpl.java      # External 모드 구현체
                                                  # @ConditionalOnProperty(havingValue = "external")

설정 파일:

src/main/resources/
├── application.yml                               # 공통 설정
├── application-local.yml                         # 로컬 환경 (Internal 모드 권장)
├── application-dev.yml                           # 개발 환경
└── application-prd.yml                           # 운영 환경

프로젝트 구조

src/main/java/go/kr/project/api/
├── config/                          # 설정 클래스
│   ├── ApiConstant.java            # API 상수 정의 (결과 코드 등)
│   ├── VmisIntegrationConfig.java  # VMIS 통합 모드 설정
│   ├── RestTemplateConfig.java     # RestTemplate 빈 설정
│   └── properties/
│       └── VmisProperties.java     # VMIS 설정 프로퍼티
│
├── controller/                      # REST 컨트롤러
│   └── VehicleInterfaceController.java  # 차량 정보 조회 API 엔드포인트
│
├── service/                         # 서비스 인터페이스
│   └── VehicleInfoService.java     # 차량 정보 조회 서비스 인터페이스
│
├── internal/                        # Internal 모드 관련 클래스
│   ├── service/
│   │   ├── impl/
│   │   │   └── InternalVehicleInfoServiceImpl.java  # Internal 모드 구현체
│   │   ├── VmisCarBassMatterInqireService.java      # 기본정보 조회 서비스
│   │   ├── VmisCarLedgerFrmbkService.java           # 등록원부 조회 서비스
│   │   └── VmisRequestEnricher.java                 # 요청 데이터 자동 설정
│   ├── client/
│   │   ├── GovernmentApi.java      # 정부 API Feign 인터페이스
│   │   └── GovernmentApiClient.java # 정부 API 호출 클라이언트
│   ├── gpki/                        # GPKI 암호화 관련
│   │   ├── GpkiService.java
│   │   ├── RealGpkiService.java
│   │   └── NoopGpkiService.java
│   └── mapper/                      # MyBatis 매퍼
│       ├── VmisCarBassMatterInqireMapper.java
│       └── VmisCarLedgerFrmbkMapper.java
│
├── external/                        # External 모드 관련 클래스
│   └── service/
│       ├── ExternalVehicleApiService.java           # 외부 API 호출 인터페이스
│       └── impl/
│           ├── ExternalVehicleInfoServiceImpl.java  # External 모드 구현체
│           └── ExternalVehicleApiServiceImpl.java   # REST API 호출 구현체
│
└── model/                           # 데이터 모델
    ├── request/
    │   ├── BasicRequest.java        # 기본정보 조회 요청
    │   └── LedgerRequest.java       # 등록원부 조회 요청
    ├── response/
    │   ├── BasicResponse.java       # 기본정보 조회 응답
    │   └── LedgerResponse.java      # 등록원부 조회 응답
    ├── VehicleApiResponseVO.java    # 통합 조회 응답
    └── Envelope.java                # 공통 메시지 래퍼

기술 스택

  • Backend Framework: Spring Boot 2.7.x
  • Language: Java 1.8
  • Database: MariaDB
  • ORM: MyBatis 3.x
  • API Documentation: Springdoc OpenAPI (Swagger)
  • Build Tool: Gradle
  • Security: GPKI (Government Public Key Infrastructure)

환경 설정

필수 설정 파일

프로젝트는 환경별로 다음 설정 파일들을 사용합니다:

  • application.yml: 공통 설정
  • application-local.yml: 로컬 개발 환경
  • application-dev.yml: 개발 환경
  • application-prd.yml: 운영 환경

VMIS 통합 설정 예시

vmis:
  integration:
    mode: internal  # internal 또는 external

  # Internal 모드 설정
  gov:
    api:
      url: https://gov-api-url
    services:
      basic:
        cntcInfoCode: AC1_FD11_01
      ledger:
        cntcInfoCode: AC1_FD11_02

  # System 정보 (공통)
  system:
    infoSysId: "41-345"
    infoSysIp: "105.19.10.135"
    sigunguCode: "41460"
    chargerId: ""
    chargerIp: ""
    chargerNm: ""

  # External 모드 설정
  external:
    api:
      url:
        base: http://localhost:8081/api/v1/vehicles

API 엔드포인트

모든 API는 /api/v1/vehicles 경로 하위에 정의되어 있습니다.

1. 통합 조회 (기본정보 + 등록원부)

POST /api/v1/vehicles/info.ajax

요청 예시:

{
  "data": [{
    "VHRNO": "12가3456",
    "LEVY_STDDE": "20250101",
    "INQIRE_SE_CODE": "1",
    "VIN": "KMHAB812345678901"
  }]
}

응답 예시:

{
  "data": [{
    "vhrno": "12가3456",
    "success": true,
    "message": "조회 성공",
    "basicInfo": { /* 기본정보 */ },
    "ledgerInfo": { /* 등록원부 정보 */ }
  }]
}

2. 기본정보만 조회

POST /api/v1/vehicles/basic.ajax

요청 예시:

{
  "data": [{
    "VHRNO": "12가3456",
    "LEVY_STDDE": "20250101",
    "INQIRE_SE_CODE": "1",
    "VIN": "KMHAB812345678901"
  }]
}

3. 등록원부만 조회

POST /api/v1/vehicles/ledger.ajax

요청 예시:

{
  "data": [{
    "VHRNO": "12가3456",
    "ONES_INFORMATION_OPEN": "1",
    "CPTTR_NM": "홍길동",
    "CPTTR_IHIDNUM": "8801011234567",
    "ROUTE_SE_CODE": "3",
    "DETAIL_EXPRESSION": "1",
    "INQIRE_SE_CODE": "1"
  }]
}

주요 클래스 및 컴포넌트

1. VehicleInfoService (인터페이스)

차량 정보 조회의 핵심 인터페이스로, Internal/External 모드에 따라 다른 구현체가 자동으로 주입됩니다.

구현체:

  • InternalVehicleInfoServiceImpl: Internal 모드
  • ExternalVehicleInfoServiceImpl: External 모드

2. VmisRequestEnricher

요청 객체에 시스템 정보를 자동으로 채워주는 컴포넌트입니다.

자동 설정 항목:

  • INFO_SYS_ID, INFO_SYS_IP, SIGUNGU_CODE
  • CNTC_INFO_CODE (서비스별)
  • CHARGER_ID, CHARGER_IP, CHARGER_NM

고정값 설정 (LedgerRequest):

  • ONES_INFORMATION_OPEN: "1" (소유자 공개)
  • ROUTE_SE_CODE: "3"
  • DETAIL_EXPRESSION: "1" (전체내역)
  • INQIRE_SE_CODE: "1" (열람)

3. ApiConstant

API 응답 코드 및 시스템 상수를 관리합니다.

주요 상수:

  • CNTC_RESULT_CODE_SUCCESS: "MSG50000" (성공)
  • CNTC_RESULT_CODE_ERROR: "ERROR" (에러)
  • DEFAULT_REGISTRANT: "SYSTEM"

데이터베이스

주요 테이블

  • tb_car_bass_matter_inqire: 차량 기본정보 조회 이력
  • tb_car_ledger_frmbk: 차량 등록원부 조회 이력

MyBatis 매퍼 위치

src/main/resources/mybatis/mapper/api-internal/
├── CarBassMatterInqireMapper_maria.xml
└── CarLedgerFrmbkMapper_maria.xml

빌드 및 실행

빌드

# 클린 빌드
./gradlew clean build

# 컴파일만 (테스트 제외)
./gradlew clean compileJava

실행

# 기본 실행 (local 프로파일)
./gradlew bootRun

# 특정 프로파일로 실행
./gradlew bootRun --args='--spring.profiles.active=dev'

포트 설정

기본 포트: 8080

변경 방법:

server:
  port: 8080

방법 2: JAR 파일 실행 (배포 권장)

개발 환경

# Linux/Mac
java -Dspring.profiles.active=dev -jar build/libs/VIPS-BOOT.war

# Windows PowerShell
java -Dspring.profiles.active=dev -jar build/libs/VIPS-BOOT.war

# 또는 환경변수 사용 (Windows PowerShell)
$env:SPRING_PROFILES_ACTIVE = "dev"
java -jar build/libs/VIPS-BOOT.war

운영 환경 (환경변수 포함)

# Linux/Mac
export SPRING_PROFILES_ACTIVE=prd
export VMIS_SYSTEM_INFO_SYS_ID="41-345"
export VMIS_SYSTEM_SIGUNGU_CODE="41460"
java -jar build/libs/VIPS-BOOT.war

# Windows PowerShell
$env:SPRING_PROFILES_ACTIVE = "prd"
$env:VMIS_SYSTEM_INFO_SYS_ID = "41-345"
$env:VMIS_SYSTEM_SIGUNGU_CODE = "41460"
java -jar build/libs/VIPS-BOOT.war

백그라운드 실행 (Linux 서버)

# nohup 사용 (기본 java 경로, 콘솔 출력을 app.log에 저장)
nohup java -Dspring.profiles.active=prd -jar build/libs/VIPS-BOOT.war > app.log 2>&1 &

# Java 경로를 직접 지정하는 방법 (Java 17 이상)
nohup /usr/bin/java -Dspring.profiles.active=prd -jar build/libs/VIPS-BOOT.war > app.log 2>&1 &

# 또는 사용자 지정 Java 경로 사용
nohup /opt/jdk-17/bin/java -Dspring.profiles.active=prd -jar build/libs/VIPS-BOOT.war > app.log 2>&1 &

# 콘솔 출력을 남기지 않을 때 (애플리케이션 자체 로그는 logback-spring.xml 설정에 따라 별도 저장됨)
# 개발 환경
nohup /usr/bin/java -Dspring.profiles.active=dev -jar build/libs/VIPS-BOOT.war > /dev/null 2>&1 &

# 운영 환경 (애플리케이션 로그: d:/data/VIPS/logs/vips.log)
nohup /usr/bin/java -Dspring.profiles.active=prd -jar build/libs/VIPS-BOOT.war > /dev/null 2>&1 &

# Java 경로 확인 방법
which java
# 또는
readlink -f $(which java)

# 프로세스 확인
ps aux | grep VIPS

# 종료
kill -9 <PID>

참고: /dev/null 사용 시 콘솔 출력만 버려지며, 애플리케이션 자체 로그는 logging.file.path 설정에 따라 정상적으로 기록됩니다.

  • 개발: d:/data/VIPS/logs/vips.log
  • 운영: d:/data/VIPS/logs/vips.log

백그라운드 실행 (Windows 서버)

PowerShell - 백그라운드 프로세스로 실행

# 개발 환경 (콘솔 출력을 app.log에 저장)
Start-Process -NoNewWindow -FilePath "java" -ArgumentList "-Dspring.profiles.active=dev","-jar","build\libs\VIPS-BOOT.war" -RedirectStandardOutput "app.log" -RedirectStandardError "app.log"

# 운영 환경 (콘솔 출력을 app.log에 저장)
Start-Process -NoNewWindow -FilePath "java" -ArgumentList "-Dspring.profiles.active=prd","-jar","build\libs\VIPS-BOOT.war" -RedirectStandardOutput "app.log" -RedirectStandardError "app.log"

# Java 경로를 직접 지정하는 방법
Start-Process -NoNewWindow -FilePath "D:\DEV\.jdks\jdk1.8.0_271\bin\java.exe" -ArgumentList "-Dspring.profiles.active=prd","-jar","build\libs\VIPS-BOOT.war" -RedirectStandardOutput "app.log" -RedirectStandardError "app.log"

# 콘솔 출력을 남기지 않을 때 (NUL로 리다이렉트)
Start-Process -NoNewWindow -FilePath "java" -ArgumentList "-Dspring.profiles.active=prd","-jar","build\libs\VIPS-BOOT.war" -RedirectStandardOutput "NUL" -RedirectStandardError "NUL"

CMD - javaw 사용 (콘솔 창 없이 실행)

# 개발 환경
start /B javaw -Dspring.profiles.active=dev -jar build\libs\VIPS-BOOT.war

# 운영 환경
start /B javaw -Dspring.profiles.active=prd -jar build\libs\VIPS-BOOT.war

# Java 경로를 직접 지정 (경로에 공백이 있을 경우 빈 창제목 "" 필요)
start "" /B "D:\DEV\.jdks\jdk1.8.0_271\bin\javaw.exe" -Dspring.profiles.active=prd -jar build\libs\VIPS-BOOT.war

# 또는 절대 경로 사용
start "" /B "D:\DEV\.jdks\jdk1.8.0_271\bin\javaw.exe" -Dspring.profiles.active=prd -jar D:\workspace\git\VIPS\build\libs\VIPS-BOOT.war


cd /d d:
D:\VIPS\azul-17.0.14\bin

java -Dspring.profiles.active=prd -jar D:\VIPS\VIPS-BOOT.war

"D:\VIPS\azul-17.0.14\bin\javaw.exe" -Dspring.profiles.active=prd -jar D:\VIPS\VIPS-BOOT.war

start "" /B "D:\VIPS\azul-17.0.14\bin\javaw.exe" -Dspring.profiles.active=prd -jar D:\VIPS\VIPS-BOOT.war

참고: start 명령어는 첫 번째 따옴표 문자열을 창 제목으로 인식하므로, 경로를 따옴표로 묶을 때는 앞에 빈 창제목 ""을 추가해야 합니다.

프로세스 관리

# 프로세스 확인
Get-Process | Where-Object {$_.ProcessName -like "*java*"} | Select-Object Id, ProcessName, Path

# 또는 특정 포트로 확인
netstat -ano | findstr :18080

# 프로세스 종료 (PID로)
Stop-Process -Id <PID> -Force

# 또는 taskkill 사용
taskkill /F /PID <PID>

Java 경로 확인 (Windows)

# PowerShell
where.exe java

# 또는
(Get-Command java).Source

# Java 버전 확인
java -version

참고: Windows 환경에서도 콘솔 출력을 NUL로 리다이렉트하면, 애플리케이션 자체 로그는 d:/data/VIPS/logs/vips.log에 정상적으로 기록됩니다.

4) API 문서(Swagger UI)

  • 개발 환경: http://localhost:8080/swagger-ui/index.html
  • 운영 환경: http://localhost:18080/swagger-ui/index.html


Swagger API 문서

애플리케이션 실행 후 다음 URL에서 API 문서를 확인할 수 있습니다:

http://localhost:8080/swagger-ui/index.html

개발 가이드

새로운 API 추가 시

  1. Request/Response 모델 생성

    • model/request/ 또는 model/response/ 패키지에 DTO 클래스 생성
    • @JsonProperty 어노테이션으로 JSON 필드 매핑
  2. 서비스 인터페이스에 메서드 추가

    • VehicleInfoService 인터페이스에 메서드 정의
  3. 구현체에 로직 작성

    • InternalVehicleInfoServiceImpl: Internal 모드
    • ExternalVehicleApiServiceImpl: External 모드
  4. 컨트롤러에 엔드포인트 추가

    • VehicleInterfaceController@PostMapping 추가
    • Swagger 문서화를 위한 @Operation 어노테이션 추가

LedgerRequest 필수 설정 값

등록원부 조회 시 다음 값들이 자동으로 설정됩니다:

// BasicInfo에서 자동 매핑
ledgerRequest.setCpttrNm(basicInfo.getMberNm());         // 민원인성명
ledgerRequest.setCpttrIhidnum(basicInfo.getMberSeNo());  // 민원인주민번호

// 고정값
ledgerRequest.setOnesInformationOpen("1");  // 개인정보공개
ledgerRequest.setRouteSeCode("3");          // 경로구분코드
ledgerRequest.setDetailExpression("2");     // 내역표시
ledgerRequest.setInqireSeCode("1");         // 조회구분코드

성공 코드 체크

응답 검증 시 반드시 상수를 사용하세요:

// ❌ 하드코딩
if ("00".equals(response.getCntcResultCode())) { ... }

// ✅ 상수 사용
if (ApiConstant.CNTC_RESULT_CODE_SUCCESS.equals(response.getCntcResultCode())) { ... }

응답 코드

정부 API 응답 코드는 ApiConstant.java의 주석을 참고하세요.

주요 응답 코드:

코드 설명
MSG50000 EAI 연계 호출을 성공적으로 처리하였습니다.
MSG50001 요청하신 자료가 존재하지 않습니다.
MSG50002 기준치보다 많은 결과조회로 인해 열람이 불가합니다.
MSG50110 EAI 호출을 위한 Message(Header) 구성에 실패하였습니다.
MSG50250 EAI-HUB 구간 통신장애 오류

트러블슈팅

1. 모드가 전환되지 않을 때

@ConditionalOnProperty 어노테이션이 적용된 구현체가 제대로 로드되는지 확인:

vmis:
  integration:
    mode: internal  # 또는 external

2. GPKI 오류

  • GPKI 인증서 경로 확인
  • GpkiConfig 설정 확인
  • 로컬 개발 시 NoopGpkiService 사용 고려

3. 데이터베이스 연결 오류

  • HikariCP 설정 확인
  • 데이터베이스 URL, 사용자명, 비밀번호 확인
  • 방화벽/네트워크 설정 확인


라이선스

Copyright (c) 2025 XIT Co., Ltd.


연락처

프로젝트 관련 문의사항은 개발팀에 문의하시기 바랍니다.