초기 셋팅
parent
ed04c2ae65
commit
b10769679a
@ -1,63 +0,0 @@
|
|||||||
package go.kr.project.carInspectionPenalty.search.controller;
|
|
||||||
|
|
||||||
import egovframework.constant.TilesConstants;
|
|
||||||
import egovframework.util.ApiResponseUtil;
|
|
||||||
import go.kr.project.api.service.VehicleInfoService;
|
|
||||||
import go.kr.project.api.model.VehicleApiResponseVO;
|
|
||||||
import go.kr.project.common.service.CommonCodeService;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/carInspectionPenalty/search")
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@Slf4j
|
|
||||||
@Tag(name = "자동차 검사 과태료 조회", description = "자동차 검사 과태료 조회 API")
|
|
||||||
public class CarInspectionPenaltyController {
|
|
||||||
|
|
||||||
private final CommonCodeService commonCodeService;
|
|
||||||
private final VehicleInfoService vehicleInfoService;
|
|
||||||
|
|
||||||
@GetMapping("/list.do")
|
|
||||||
public String list( Model model ) {
|
|
||||||
|
|
||||||
return "carInspectionPenalty/search/list" + TilesConstants.BASE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 차량 정보 조회 API
|
|
||||||
* 여러 차량번호를 받아서 차량 정보를 조회합니다.
|
|
||||||
* 설정(vmis.integration.mode)에 따라 내부 모듈 또는 외부 API를 호출합니다.
|
|
||||||
*
|
|
||||||
* @param vehicleNumbers 차량번호 리스트
|
|
||||||
* @return 차량 정보 조회 결과
|
|
||||||
*/
|
|
||||||
@PostMapping("/getVehiclesInfo.do")
|
|
||||||
@ResponseBody
|
|
||||||
@Operation(summary = "차량 정보 조회", description = "차량번호 리스트를 받아서 차량 기본정보와 등록원부 정보를 조회합니다.")
|
|
||||||
public ResponseEntity<?> getVehiclesInfo(@RequestBody List<String> vehicleNumbers) {
|
|
||||||
log.info("차량 정보 조회 요청 - 차량 수: {}", vehicleNumbers.size());
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 차량 정보 조회 (설정에 따라 internal/external 자동 선택)
|
|
||||||
List<VehicleApiResponseVO> vehicles = vehicleInfoService.getVehiclesInfo(vehicleNumbers);
|
|
||||||
|
|
||||||
log.info("차량 정보 조회 완료 - 총 {}건", vehicles.size());
|
|
||||||
|
|
||||||
return ApiResponseUtil.success(vehicles, "차량 정보 조회가 완료되었습니다.");
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("차량 정보 조회 중 오류 발생", e);
|
|
||||||
return ApiResponseUtil.error("조회 중 오류가 발생했습니다: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,295 +1,212 @@
|
|||||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
<!-- 팝업 전용 CSS -->
|
||||||
<head>
|
<link rel="stylesheet" type="text/css" href="<c:url value='/resources/xit/xit-popup.css'/>" />
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<!-- TXT 파일 업로드 팝업 -->
|
||||||
<title>TXT 파일 업로드</title>
|
<div class="popup_wrap">
|
||||||
<link rel="stylesheet" href="<c:url value='/resources/css/common.css'/>">
|
<div class="popup_inner">
|
||||||
<link rel="stylesheet" href="<c:url value='/resources/xit/xit-popup.css'/>">
|
<div class="popup_tit">
|
||||||
<script src="<c:url value='/resources/js/jquery-3.6.0.min.js'/>"></script>
|
<h2 class="tit">과태료 대상 TXT 파일 업로드</h2>
|
||||||
<script src="<c:url value='/resources/js/common.js'/>"></script>
|
<a href="#" class="pop-x-btn modalclose" id="btnCloseTop"></a>
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 20px;
|
|
||||||
font-family: 'Malgun Gothic', sans-serif;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
}
|
|
||||||
.popup-container {
|
|
||||||
background: white;
|
|
||||||
padding: 20px;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
.popup-title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
border-bottom: 2px solid #4CAF50;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
.upload-section {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
.upload-label {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #555;
|
|
||||||
}
|
|
||||||
.file-input-wrapper {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.file-input-wrapper input[type="file"] {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
border: 2px dashed #ddd;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.file-input-wrapper input[type="file"]:hover {
|
|
||||||
border-color: #4CAF50;
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
}
|
|
||||||
.file-info {
|
|
||||||
margin-top: 10px;
|
|
||||||
padding: 10px;
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 13px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
.file-format-info {
|
|
||||||
margin-top: 15px;
|
|
||||||
padding: 15px;
|
|
||||||
background-color: #fff3cd;
|
|
||||||
border: 1px solid #ffc107;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
.file-format-info h4 {
|
|
||||||
margin: 0 0 10px 0;
|
|
||||||
color: #856404;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.file-format-info ul {
|
|
||||||
margin: 0;
|
|
||||||
padding-left: 20px;
|
|
||||||
color: #856404;
|
|
||||||
}
|
|
||||||
.file-format-info li {
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
.button-area {
|
|
||||||
margin-top: 20px;
|
|
||||||
text-align: center;
|
|
||||||
padding-top: 20px;
|
|
||||||
border-top: 1px solid #eee;
|
|
||||||
}
|
|
||||||
.btn {
|
|
||||||
padding: 10px 30px;
|
|
||||||
margin: 0 5px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold;
|
|
||||||
transition: all 0.3s;
|
|
||||||
}
|
|
||||||
.btn-upload {
|
|
||||||
background-color: #4CAF50;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.btn-upload:hover {
|
|
||||||
background-color: #45a049;
|
|
||||||
}
|
|
||||||
.btn-upload:disabled {
|
|
||||||
background-color: #cccccc;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
.btn-close {
|
|
||||||
background-color: #f44336;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.btn-close:hover {
|
|
||||||
background-color: #da190b;
|
|
||||||
}
|
|
||||||
.loading {
|
|
||||||
display: none;
|
|
||||||
text-align: center;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
.loading.active {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.spinner {
|
|
||||||
border: 4px solid #f3f3f3;
|
|
||||||
border-top: 4px solid #4CAF50;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
animation: spin 1s linear infinite;
|
|
||||||
margin: 0 auto 10px;
|
|
||||||
}
|
|
||||||
@keyframes spin {
|
|
||||||
0% { transform: rotate(0deg); }
|
|
||||||
100% { transform: rotate(360deg); }
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="popup-container">
|
|
||||||
<div class="popup-title">과태료 대상 TXT 파일 업로드</div>
|
|
||||||
|
|
||||||
<div class="upload-section">
|
|
||||||
<label class="upload-label">TXT 파일 선택</label>
|
|
||||||
<div class="file-input-wrapper">
|
|
||||||
<input type="file" id="txtFile" name="txtFile" accept=".txt" />
|
|
||||||
</div>
|
|
||||||
<div class="file-info">
|
|
||||||
※ TXT 파일만 업로드 가능합니다. (최대 50MB)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="file-format-info">
|
|
||||||
<h4>📋 파일 형식 안내</h4>
|
|
||||||
<ul>
|
|
||||||
<li>첫 번째 줄은 헤더로 간주되어 스킵됩니다.</li>
|
|
||||||
<li>데이터는 탭(Tab)으로 구분되어야 합니다.</li>
|
|
||||||
<li>컬럼 순서: 접수일자, 구분, 검사소코드, 검사일자, 차량번호, 소유자명, 주민등록번호, 자동차명, 자동차종류, 자동차용도, 검사종료일자, 일수, 과태료금액, 최종등록일자, 주소, 유효기간만료일자, 매매상품</li>
|
|
||||||
<li>필수 항목: 접수일자, 검사일자, 차량번호, 소유자명, 과태료금액</li>
|
|
||||||
<li>날짜 형식: YYYYMMDD (예: 20231113)</li>
|
|
||||||
<li>차량번호 형식: 12가3456 또는 123가4567</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="loading" id="loading">
|
<div class="popup_con">
|
||||||
<div class="spinner"></div>
|
<form id="uploadForm" name="uploadForm">
|
||||||
<div>파일 업로드 중입니다. 잠시만 기다려주세요...</div>
|
<div class="forms_table_non">
|
||||||
|
<table>
|
||||||
|
<colgroup>
|
||||||
|
<col style="width: 20%;" />
|
||||||
|
<col style="width: 80%;" />
|
||||||
|
</colgroup>
|
||||||
|
<tr>
|
||||||
|
<th class="th"><span class="required">*</span> TXT 파일</th>
|
||||||
|
<td>
|
||||||
|
<div class="file-input-wrapper">
|
||||||
|
<input type="file" id="txtFile" name="txtFile" accept=".txt" class="input" style="width: 100%;" />
|
||||||
|
</div>
|
||||||
|
<div class="file-info" style="margin-top: 10px; color: #666; font-size: 13px;">
|
||||||
|
※ TXT 파일만 업로드 가능합니다. (최대 50MB)
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="file-format-info" style="padding: 15px; background-color: #fff3cd; border: 1px solid #ffc107; border-radius: 4px;">
|
||||||
|
<ul style="margin: 0; padding-left: 20px; color: #856404; font-size: 13px;">
|
||||||
|
<li>7~10 번째 줄은 헤더 및 라인구분 기호로 간주되어 스킵됩니다.</li>
|
||||||
|
<li>데이터는 ECU-KR 한글 2Byte으로 구분됩니다.</li>
|
||||||
|
<li>컬럼 순서: 접수일자, 구분, 검사소코드, 검사일자, 차량번호, 소유자명, 주민등록번호, 자동차명, 자동차종류, 자동차용도, 검사종료일자, 일수, 과태료금액, 최종등록일자, 주소, 유효기간만료일자, 매매상품</li>
|
||||||
|
<li>필수 항목: 접수일자, 검사일자, 차량번호, 소유자명, 과태료금액</li>
|
||||||
|
<li>날짜 형식: YYYY-MM-DD (예: 2023-11-13)</li>
|
||||||
|
<li>차량번호 형식: 12가3456 또는 123가4567</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- 중요로직: 로딩 표시 영역 -->
|
||||||
|
<div class="loading" id="loading" style="display: none; text-align: center; padding: 20px;">
|
||||||
|
<div class="spinner" style="border: 4px solid #f3f3f3; border-top: 4px solid #4CAF50; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 0 auto 10px;"></div>
|
||||||
|
<div>파일 업로드 중입니다. 잠시만 기다려주세요...</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="button-area">
|
<div class="popup_foot">
|
||||||
<button type="button" class="btn btn-upload" id="uploadBtn">파일 업로드</button>
|
<button type="button" id="btnUpload" class="newbtns bg1">파일 업로드</button>
|
||||||
<button type="button" class="btn btn-close" id="closeBtn">닫기</button>
|
<button type="button" id="btnClose" class="newbtns bg2 modalclose">닫기</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
.loading.active {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
/**
|
||||||
|
* TXT 파일 업로드 팝업 JavaScript
|
||||||
|
* 중요로직: 과태료 대상 TXT 파일을 업로드하고 검증한다.
|
||||||
|
*/
|
||||||
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 파일 업로드 버튼 클릭 이벤트
|
||||||
|
* 중요로직: 파일 선택 후 검증을 거쳐 서버로 업로드한다.
|
||||||
|
*/
|
||||||
|
$("#btnUpload").on('click', function() {
|
||||||
|
uploadFile();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 닫기 버튼 클릭 이벤트
|
||||||
|
*/
|
||||||
|
$("#btnClose, #btnCloseTop").on('click', function() {
|
||||||
|
closePopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 파일 선택 시 파일 정보 표시
|
||||||
|
*/
|
||||||
|
$("#txtFile").on('change', function() {
|
||||||
|
displayFileInfo(this.files[0]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
<script type="text/javascript">
|
/**
|
||||||
$(document).ready(function() {
|
* 파일 업로드 함수
|
||||||
|
* 중요로직: 파일 검증 후 FormData를 사용하여 파일을 서버로 전송한다.
|
||||||
|
*/
|
||||||
|
function uploadFile() {
|
||||||
|
var fileInput = document.getElementById('txtFile');
|
||||||
|
var file = fileInput.files[0];
|
||||||
|
|
||||||
|
// 중요로직: 파일 선택 여부 검증
|
||||||
|
if (!file) {
|
||||||
|
alert("파일을 선택해주세요.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 중요로직: 파일 확장자 검증
|
||||||
|
var fileName = file.name;
|
||||||
|
var fileExt = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
|
||||||
|
if (fileExt !== 'txt') {
|
||||||
|
alert("TXT 파일만 업로드 가능합니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 중요로직: 파일 크기 검증 (50MB)
|
||||||
|
if (file.size > 50 * 1024 * 1024) {
|
||||||
|
alert("파일 크기는 50MB를 초과할 수 없습니다.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 확인 메시지
|
||||||
|
if (!confirm("선택한 파일을 업로드하시겠습니까?")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 중요로직: FormData를 사용하여 파일 데이터 구성
|
||||||
|
var formData = new FormData();
|
||||||
|
formData.append('file', file);
|
||||||
|
|
||||||
|
// 로딩 표시
|
||||||
|
$("#loading").addClass('active');
|
||||||
|
$("#btnUpload").prop('disabled', true);
|
||||||
|
|
||||||
|
// 중요로직: AJAX로 파일 업로드
|
||||||
|
$.ajax({
|
||||||
|
url: '<c:url value="/carInspectionPenalty/registration/upload.ajax"/>',
|
||||||
|
type: 'POST',
|
||||||
|
data: formData,
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
success: function(response) {
|
||||||
|
// 로딩 숨김
|
||||||
|
$("#loading").removeClass('active');
|
||||||
|
$("#btnUpload").prop('disabled', false);
|
||||||
|
|
||||||
/**
|
if (response.success) {
|
||||||
* 파일 업로드 버튼 클릭
|
alert(response.message);
|
||||||
*/
|
|
||||||
$("#uploadBtn").on('click', function() {
|
|
||||||
var fileInput = document.getElementById('txtFile');
|
|
||||||
var file = fileInput.files[0];
|
|
||||||
|
|
||||||
// 파일 선택 검증
|
// 중요로직: 부모 창의 목록 새로고침
|
||||||
if (!file) {
|
if (window.opener && window.opener.CarFfnlgTrgt && typeof window.opener.CarFfnlgTrgt.search === 'function') {
|
||||||
alert("파일을 선택해주세요.");
|
window.opener.CarFfnlgTrgt.search();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 파일 확장자 검증
|
closePopup();
|
||||||
var fileName = file.name;
|
} else {
|
||||||
var fileExt = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
|
alert(response.message || '파일 업로드에 실패했습니다.');
|
||||||
if (fileExt !== 'txt') {
|
}
|
||||||
alert("TXT 파일만 업로드 가능합니다.");
|
},
|
||||||
return;
|
error: function(xhr, status, error) {
|
||||||
}
|
// 로딩 숨김
|
||||||
|
$("#loading").removeClass('active');
|
||||||
// 파일 크기 검증 (50MB)
|
$("#btnUpload").prop('disabled', false);
|
||||||
if (file.size > 50 * 1024 * 1024) {
|
|
||||||
alert("파일 크기는 50MB를 초과할 수 없습니다.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 확인 메시지
|
|
||||||
if (!confirm("선택한 파일을 업로드하시겠습니까?")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FormData 생성
|
|
||||||
var formData = new FormData();
|
|
||||||
formData.append('file', file);
|
|
||||||
|
|
||||||
// 로딩 표시
|
|
||||||
$("#loading").addClass('active');
|
|
||||||
$("#uploadBtn").prop('disabled', true);
|
|
||||||
|
|
||||||
// AJAX 업로드
|
|
||||||
$.ajax({
|
|
||||||
url: '<c:url value="/carInspectionPenalty/registration/upload.ajax"/>',
|
|
||||||
type: 'POST',
|
|
||||||
data: formData,
|
|
||||||
processData: false,
|
|
||||||
contentType: false,
|
|
||||||
success: function(response) {
|
|
||||||
// 로딩 숨김
|
|
||||||
$("#loading").removeClass('active');
|
|
||||||
$("#uploadBtn").prop('disabled', false);
|
|
||||||
|
|
||||||
if (response.success) {
|
|
||||||
alert(response.message);
|
|
||||||
|
|
||||||
// 성공 시 파일 입력 초기화
|
|
||||||
fileInput.value = '';
|
|
||||||
|
|
||||||
// 부모 창 새로고침을 위해 잠시 대기 후 닫기
|
|
||||||
setTimeout(function() {
|
|
||||||
window.close();
|
|
||||||
}, 500);
|
|
||||||
} else {
|
|
||||||
alert(response.message);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function(xhr, status, error) {
|
|
||||||
// 로딩 숨김
|
|
||||||
$("#loading").removeClass('active');
|
|
||||||
$("#uploadBtn").prop('disabled', false);
|
|
||||||
|
|
||||||
console.error("업로드 오류:", error);
|
|
||||||
|
|
||||||
var errorMessage = "파일 업로드 중 오류가 발생했습니다.";
|
|
||||||
if (xhr.responseJSON && xhr.responseJSON.message) {
|
|
||||||
errorMessage += "\n\n" + xhr.responseJSON.message;
|
|
||||||
}
|
|
||||||
alert(errorMessage);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
console.error("업로드 오류:", error);
|
||||||
* 닫기 버튼 클릭
|
|
||||||
*/
|
|
||||||
$("#closeBtn").on('click', function() {
|
|
||||||
window.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
var errorMessage = "파일 업로드 중 오류가 발생했습니다.";
|
||||||
* 파일 선택 시 파일 정보 표시
|
if (xhr.responseJSON && xhr.responseJSON.message) {
|
||||||
*/
|
errorMessage += "\n\n" + xhr.responseJSON.message;
|
||||||
$("#txtFile").on('change', function() {
|
}
|
||||||
var file = this.files[0];
|
alert(errorMessage);
|
||||||
if (file) {
|
}
|
||||||
var fileSize = (file.size / 1024).toFixed(2); // KB 단위
|
});
|
||||||
var fileSizeText = fileSize < 1024
|
}
|
||||||
? fileSize + ' KB'
|
|
||||||
: (fileSize / 1024).toFixed(2) + ' MB';
|
/**
|
||||||
|
* 파일 정보 표시 함수
|
||||||
$('.file-info').html(
|
* 중요로직: 선택한 파일의 이름과 크기를 화면에 표시한다.
|
||||||
'선택된 파일: <strong>' + file.name + '</strong><br>' +
|
*/
|
||||||
'파일 크기: ' + fileSizeText
|
function displayFileInfo(file) {
|
||||||
);
|
if (file) {
|
||||||
}
|
var fileSize = (file.size / 1024).toFixed(2); // KB 단위
|
||||||
});
|
var fileSizeText = fileSize < 1024
|
||||||
});
|
? fileSize + ' KB'
|
||||||
</script>
|
: (fileSize / 1024).toFixed(2) + ' MB';
|
||||||
</body>
|
|
||||||
</html>
|
$('.file-info').html(
|
||||||
|
'선택된 파일: <strong>' + file.name + '</strong><br>' +
|
||||||
|
'파일 크기: ' + fileSizeText
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 팝업 닫기 함수
|
||||||
|
*/
|
||||||
|
function closePopup() {
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|||||||
@ -1,211 +0,0 @@
|
|||||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
|
||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
|
||||||
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
|
|
||||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
|
|
||||||
<%@ taglib prefix="dateUtil" uri="http://egovframework.go.kr/functions/date-util" %>
|
|
||||||
|
|
||||||
<!-- Main body -->
|
|
||||||
<div class="main_body">
|
|
||||||
<section id="section8" class="main_bars">
|
|
||||||
<div class="bgs-main">
|
|
||||||
<section id="section5">
|
|
||||||
<div class="sub_title"></div>
|
|
||||||
<button type="button" id="registerBtn" class="newbtn bg1">등록</button>
|
|
||||||
<button type="button" id="updaterBtn" class="newbtn bg4">수정</button>
|
|
||||||
<button type="button" id="excelDownBtn" class="newbtn bg5 iconz">
|
|
||||||
<span class="mdi mdi-microsoft-excel"></span>엑셀 다운로드
|
|
||||||
</button>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<div class="contants_body">
|
|
||||||
<div class="gs_b_top">
|
|
||||||
<ul class="lef">
|
|
||||||
<li class="th">단속 년도</li>
|
|
||||||
<li>
|
|
||||||
<input type="text" id="schCrdnYr" name="schCrdnYr" maxlength="4" class="input calender yearpicker" style="width: 80px;" autocomplete="off" value="${empty param.schCrdnYr ? dateUtil:getCurrentDateTime('yyyy') : param.schCrdnYr}"/>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="rig2">
|
|
||||||
<li><button type="button" id="search_btn" class="newbtnss bg1">검색</button></li>
|
|
||||||
<li><button type="button" id="reset_btn" class="newbtnss bg5" style="margin-left: 5px;">초기화</button></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="gs_booking">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="box_column">
|
|
||||||
<ul class="box_title" style="display: flex; justify-content: space-between; align-items: center;">
|
|
||||||
<li class="tit">단속 목록</li>
|
|
||||||
<li class="rig">
|
|
||||||
<button type="button" id="btnCarExternalApiCall" class="newbtn bg2-1">차량조회</button>
|
|
||||||
|
|
||||||
<span id="totalCount" class="total-count" style="padding-left: 25px;padding-right: 25px;">총 0건</span>
|
|
||||||
<select id="perPageSelect" class="input" style="width: 112px; ">
|
|
||||||
<option value="15">페이지당 15</option>
|
|
||||||
<option value="50">페이지당 50</option>
|
|
||||||
<option value="100">페이지당 100</option>
|
|
||||||
</select>
|
|
||||||
<span class="page_number"><span id="currentPage"></span><span class="bar">/</span><span id="totalPages"></span> Pages</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="containers">
|
|
||||||
<div id="grid"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- /Main body -->
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 단속 등록/조회 목록 관리 모듈
|
|
||||||
* 단속 목록을 조회하고 관리하는 기능을 제공합니다.
|
|
||||||
*/
|
|
||||||
(function(window, $) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var SEARCH_COND = {};
|
|
||||||
|
|
||||||
// 페이징 정보를 저장할 전역 변수
|
|
||||||
var GRID_PAGINATION_INFO = {
|
|
||||||
totalCount: 0,
|
|
||||||
page: 0,
|
|
||||||
perPage: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
// 검색정보 설정
|
|
||||||
var setSearchCond = function() {
|
|
||||||
var schCrdnYr = $.trim(nvl($("#schCrdnYr").val(), ""));
|
|
||||||
|
|
||||||
SEARCH_COND.schCrdnYr = schCrdnYr;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 단속 목록 관리 네임스페이스
|
|
||||||
*/
|
|
||||||
var CrdnRegistAndViewList = {
|
|
||||||
/**
|
|
||||||
* 선택된 행 정보
|
|
||||||
*/
|
|
||||||
selectedRow: null,
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 이벤트 핸들러 설정
|
|
||||||
*/
|
|
||||||
eventBindEvents: function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
// 검색 버튼 클릭 이벤트
|
|
||||||
$("#search_btn").on('click', function() {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// 초기화 버튼 클릭 이벤트
|
|
||||||
$("#reset_btn").on('click', function() {
|
|
||||||
// 모든 검색 조건 초기화
|
|
||||||
$("#schCrdnYr").val("${dateUtil:getCurrentDateTime('yyyy')}"); // 현재 년도로 초기화
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// 등록 버튼 클릭 이벤트
|
|
||||||
$("#registerBtn").on('click', function() {
|
|
||||||
self.openRegisterPopup();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 차량조회 버튼 클릭 이벤트
|
|
||||||
$("#btnCarExternalApiCall").on('click', function() {
|
|
||||||
self.callVehicleApi();
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 차량 정보 조회 API 호출
|
|
||||||
*/
|
|
||||||
callVehicleApi: function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
// 임시 테스트용 차량번호 (실제로는 그리드에서 선택된 차량번호를 가져와야 함)
|
|
||||||
var vehicleNumbers = ["12가3456", "34나5678", "56다7890", "78라1234", "90마5678",
|
|
||||||
"12바9012", "34사3456", "56아7890", "78자1234", "90차5678",
|
|
||||||
"12카9012", "34타3456", "56파7890", "78하1234", "90거5678"];
|
|
||||||
|
|
||||||
// 확인 메시지
|
|
||||||
if (!confirm("총 " + vehicleNumbers.length + "건의 차량 정보를 조회하시겠습니까?")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// API 호출
|
|
||||||
$.ajax({
|
|
||||||
url: '/carInspectionPenalty/search/getVehiclesInfo.do',
|
|
||||||
type: 'POST',
|
|
||||||
contentType: 'application/json',
|
|
||||||
data: JSON.stringify(vehicleNumbers),
|
|
||||||
success: function(response) {
|
|
||||||
|
|
||||||
if (response.success) {
|
|
||||||
console.log("차량 정보 조회 성공:", response.data);
|
|
||||||
|
|
||||||
// 성공/실패 건수 계산
|
|
||||||
var successCount = 0;
|
|
||||||
var failCount = 0;
|
|
||||||
|
|
||||||
response.data.forEach(function(vehicle) {
|
|
||||||
if (vehicle.success) {
|
|
||||||
successCount++;
|
|
||||||
console.log("차량번호: " + vehicle.vhrno + " 조회 성공");
|
|
||||||
console.log("- 기본정보:", vehicle.basicInfo);
|
|
||||||
console.log("- 등록원부:", vehicle.ledgerInfo);
|
|
||||||
} else {
|
|
||||||
failCount++;
|
|
||||||
console.log("차량번호: " + vehicle.vhrno + " 조회 실패 - " + vehicle.message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 결과 메시지 표시
|
|
||||||
alert("차량 정보 조회가 완료되었습니다.\n\n" +
|
|
||||||
"성공: " + successCount + "건\n" +
|
|
||||||
"실패: " + failCount + "건\n\n" +
|
|
||||||
"자세한 내용은 콘솔을 확인하세요.");
|
|
||||||
|
|
||||||
// TODO: 조회된 정보를 그리드에 표시하거나 DB에 저장하는 로직 추가
|
|
||||||
|
|
||||||
} else {
|
|
||||||
alert("차량 정보 조회에 실패했습니다.\n\n" + response.message);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function(xhr, status, error) {
|
|
||||||
console.error("API 호출 오류:", error);
|
|
||||||
alert("차량 정보 조회 중 오류가 발생했습니다.\n\n" + error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 모듈 초기화
|
|
||||||
*/
|
|
||||||
init: function() {
|
|
||||||
|
|
||||||
|
|
||||||
// 이벤트 핸들러 설정
|
|
||||||
this.eventBindEvents();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// DOM 준비 완료 시 초기화
|
|
||||||
$(document).ready(function() {
|
|
||||||
CrdnRegistAndViewList.init();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 전역 네임스페이스에 모듈 노출
|
|
||||||
window.CrdnRegistAndViewList = CrdnRegistAndViewList;
|
|
||||||
|
|
||||||
})(window, jQuery);
|
|
||||||
</script>
|
|
||||||
Loading…
Reference in New Issue