235 lines
9.8 KiB
PHP
235 lines
9.8 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>배포 파일 관리 시스템</title>
|
|
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
|
</head>
|
|
<body class="bg-gray-100 p-6">
|
|
<div class="max-w-screen-xl mx-auto">
|
|
<div class="flex items-center mb-4">
|
|
<svg class="w-7 h-7 text-blue-600 mr-2" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2M7 10l5-5m0 0l5 5m-5-5v12" />
|
|
</svg>
|
|
<span class="text-xl font-bold mr-4">파일 업로드 관리자</span>
|
|
</div>
|
|
|
|
<!-- 헤드 구성 -->
|
|
<div class="bg-white p-4 rounded shadow mb-6 flex items-center justify-between">
|
|
<div class="flex items-center space-x-4">
|
|
<label for="product-select" class="font-bold">제품명(제품코드):</label>
|
|
<select id="product-select" class="p-2 border border-gray-300 rounded">
|
|
<option value="1">EG-BIM</option>
|
|
<option value="2">TOVA</option>
|
|
<option value="3">GAIA</option>
|
|
</select>
|
|
</div>
|
|
<div class="flex items-center space-x-4">
|
|
<div>
|
|
<span class="text-sm">내부 배포 버전(최신):</span>
|
|
<span class="text-blue-600 font-semibold">0.28.1</span>
|
|
</div>
|
|
<div class="flex items-center space-x-1">
|
|
<span class="text-sm">외부 배포 버전:</span>
|
|
<input type="number" id="ver1" class="w-14 p-1 border rounded" min="0" max="99">
|
|
<span class="text-sm">.</span>
|
|
<input type="number" id="ver2" class="w-14 p-1 border rounded" min="0" max="99">
|
|
<span class="text-sm">.</span>
|
|
<input type="number" id="ver3" class="w-14 p-1 border rounded" min="0" max="99">
|
|
</div>
|
|
<button id="save-version" class="bg-blue-500 text-white px-3 py-1 rounded hover:bg-blue-600">저장</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 버튼 영역 -->
|
|
<div class="flex justify-end space-x-2 mb-4">
|
|
<button id="btn-new" class="bg-green-500 text-white px-3 py-1 rounded hover:bg-green-600">+ 신규 버전</button>
|
|
<button class="bg-gray-500 text-white px-3 py-1 rounded hover:bg-gray-600">다운로드</button>
|
|
<button class="bg-red-500 text-white px-3 py-1 rounded hover:bg-red-600">파일삭제</button>
|
|
</div>
|
|
|
|
<!-- 테이블 -->
|
|
<div class="bg-white shadow rounded-lg overflow-x-auto">
|
|
<table class="min-w-full text-sm text-left">
|
|
<thead class="bg-gray-200">
|
|
<tr>
|
|
<th class="px-4 py-2"><input type="checkbox" id="select-all" /></th>
|
|
<th class="px-4 py-2">번호</th>
|
|
<th class="px-4 py-2">파일명</th>
|
|
<th class="px-4 py-2">파일타입</th>
|
|
<th class="px-4 py-2">버전</th>
|
|
<th class="px-4 py-2">크기</th>
|
|
<th class="px-4 py-2">업로드일</th>
|
|
<th class="px-4 py-2">업로드자</th>
|
|
<th class="px-4 py-2">테스트완료</th>
|
|
<th class="px-4 py-2">테스트자</th>
|
|
<th class="px-4 py-2">릴리즈일</th>
|
|
<th class="px-4 py-2">릴리즈자</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="file-list">
|
|
<!-- JavaScript로 동적 삽입 예정 -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 신규 버전 업로드 팝업(모달) -->
|
|
<div id="upload-modal" class="fixed inset-0 bg-black bg-opacity-40 flex items-center justify-center z-50 hidden">
|
|
<div class="bg-white p-8 rounded shadow-lg w-full max-w-lg relative">
|
|
<h2 class="text-xl font-bold mb-6 text-center">
|
|
신규 버전 업로드
|
|
<span class="text-base text-gray-500">(테스트 서버)</span>
|
|
</h2>
|
|
|
|
<div class="space-y-3">
|
|
<div class="flex items-center">
|
|
<label class="w-28">S/W 버전 :</label>
|
|
<input type="number" class="border w-14 p-1 mx-1 text-center" id="sw1" min="0">
|
|
<span>.</span>
|
|
<input type="number" class="border w-14 p-1 mx-1 text-center" id="sw2" min="0">
|
|
<span>.</span>
|
|
<input type="number" class="border w-14 p-1 mx-1 text-center" id="sw3" min="0">
|
|
<span class="ml-3 text-gray-500">MAJOR</span>
|
|
</div>
|
|
|
|
<!-- 설치파일 -->
|
|
<div class="flex items-center mb-2">
|
|
<label class="w-39 flex justify-between items-center">
|
|
<span>설치파일(EXE)</span>
|
|
<span>:</span>
|
|
</label>
|
|
<input type="file" class="hidden" id="setup-file" accept=".exe">
|
|
<input type="text" class="border flex-1 p-1 bg-gray-100 ml-2" id="setup-filename" readonly>
|
|
<button type="button" class="ml-2 px-3 py-1 bg-blue-500 text-white rounded" id="setup-add">추가</button>
|
|
</div>
|
|
|
|
<!-- 패치파일 -->
|
|
<div class="flex items-center mb-2">
|
|
<label class="w-39 flex justify-between items-center">
|
|
<span>패치파일(EXE)</span>
|
|
<span>:</span>
|
|
</label>
|
|
<input type="file" class="hidden" id="patch-file" accept=".exe">
|
|
<input type="text" class="border flex-1 p-1 bg-gray-100 ml-2" id="patch-filename" readonly>
|
|
<button type="button" class="ml-2 px-3 py-1 bg-blue-500 text-white rounded" id="patch-add">추가</button>
|
|
</div>
|
|
|
|
<!-- 정보파일 -->
|
|
<div class="flex items-center mb-2">
|
|
<label class="w-39 flex justify-between items-center">
|
|
<span class="flex items-center">
|
|
정보파일
|
|
<span class="relative group cursor-pointer ml-1">
|
|
<span class="w-5 h-5 flex items-center justify-center bg-blue-100 rounded-full text-blue-700 font-bold">i</span>
|
|
<span class="absolute left-1/2 -translate-x-1/2 top-7 z-50 hidden group-hover:block bg-gray-800 text-white text-xs rounded py-1 px-2 whitespace-nowrap shadow-lg">
|
|
2개 이상의 파일을 업로드 시 압축파일 형태로 업로드해주세요
|
|
</span>
|
|
</span>
|
|
</span>
|
|
<span>:</span>
|
|
</label>
|
|
<input type="file" class="hidden" id="info-file" accept=".zip">
|
|
<input type="text" class="border flex-1 p-1 bg-gray-100 ml-2" id="info-filename" readonly>
|
|
<button type="button" class="ml-2 px-3 py-1 bg-blue-500 text-white rounded" id="info-add">추가</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
$('#save-version').on('click', function() {
|
|
const product = $('#product-select').val().replace(/['"]/g, '');
|
|
const family = $('.text-blue-600').text().replace(/['"]/g, '');
|
|
const v1 = $('#ver1').val();
|
|
const v2 = $('#ver2').val();
|
|
const v3 = $('#ver3').val();
|
|
|
|
if(!v1 || !v2 || !v3) {
|
|
alert("외부 버전 모든 칸을 입력하세요");
|
|
return;
|
|
}
|
|
|
|
const external = [v1, v2, v3].join('.');
|
|
|
|
// 실제 전송 (주석처리 상태)
|
|
// $.post('/egbim1/save_version.php', {
|
|
// product_code: product,
|
|
// family_version: family,
|
|
// external_version: external
|
|
// }, function(res) {
|
|
// alert(res.message || '저장 완료');
|
|
// }, 'json');
|
|
});
|
|
|
|
// 전체 선택 체크박스 처리
|
|
$('#select-all').on('change', function() {
|
|
$('.file-checkbox').prop('checked', this.checked);
|
|
});
|
|
|
|
// 신규버전 버튼 → 팝업
|
|
$('#btn-new').on('click', function() {
|
|
$('#upload-modal').removeClass('hidden');
|
|
});
|
|
|
|
// 취소 버튼, 바깥 클릭 → 닫기
|
|
$('#upload-cancel').on('click', function() {
|
|
$('#upload-modal').addClass('hidden');
|
|
});
|
|
$('#upload-modal').on('click', function(e){
|
|
if (e.target === this) $(this).addClass('hidden');
|
|
});
|
|
|
|
// 파일 추가 버튼
|
|
$('#setup-add').on('click', function() { $('#setup-file').click(); });
|
|
$('#patch-add').on('click', function() { $('#patch-file').click(); });
|
|
$('#info-add').on('click', function() { $('#info-file').click(); });
|
|
|
|
// 파일명 표시
|
|
$('#setup-file').on('change', function(){ $('#setup-filename').val(this.files[0]?.name || ''); });
|
|
$('#patch-file').on('change', function(){ $('#patch-filename').val(this.files[0]?.name || ''); });
|
|
$('#info-file').on('change', function(){ $('#info-filename').val(this.files[0]?.name || ''); });
|
|
|
|
//cloudflare 업로드
|
|
async function uploadToR2(file) {
|
|
// 1) 서버에서 presigned URL 요청
|
|
let formData = new FormData();
|
|
formData.append("filename", file.name);
|
|
|
|
let res = await fetch("/egbim1/upload_presign.php", {
|
|
method: "POST",
|
|
body: formData
|
|
});
|
|
|
|
let data = await res.json();
|
|
console.log("Presigned URL:", data.url);
|
|
|
|
// 2) presigned URL로 직접 업로드
|
|
let putRes = await fetch(data.url, {
|
|
method: "PUT",
|
|
body: file
|
|
});
|
|
|
|
if (putRes.ok) {
|
|
alert(file.name + " 업로드 성공!");
|
|
|
|
// 👉 DB 저장 호출 (버전 + 파일 정보)
|
|
$.post('/egbim1/save_version.php', {
|
|
filename: file.name,
|
|
product_code: $('#product-select').val(),
|
|
version: [$('#sw1').val(), $('#sw2').val(), $('#sw3').val()].join('.')
|
|
}, function(res) {
|
|
console.log(res);
|
|
}, 'json');
|
|
|
|
} else {
|
|
alert(file.name + " 업로드 실패!");
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|