feat: 5장 사진 지원 및 엑셀 내보내기 UI 개선
- 신고 및 완료 사진 5장 지원 (photo_path3, photo_path4, photo_path5 추가) - 엑셀 일일 리포트 개선: - 사진 5장 모두 한 행에 일렬 배치 (A, C, E, G, I 열) - 상태별 색상 구분 (지연중: 빨강, 진행중: 노랑, 완료: 진한 초록) - 우선순위 기반 정렬 (지연중 → 진행중 → 완료됨) - 프로젝트 현황 통계 박스 UI 개선 (색상 구분) - 프론트엔드 모든 페이지 5장 사진 표시 (flex-wrap 레이아웃) - 관리함, 수신함, 현황판, 신고내용 확인 페이지 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -851,10 +851,27 @@
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">업로드 사진</label>
|
||||
<div class="flex gap-2">
|
||||
${issue.photo_path ? `<img src="${issue.photo_path}" class="w-20 h-20 object-cover rounded-lg cursor-pointer border-2 border-gray-200 hover:border-blue-400 transition-colors" onclick="openPhotoModal('${issue.photo_path}')" alt="업로드 사진 1">` : '<div class="w-20 h-20 bg-gray-100 rounded-lg flex items-center justify-center text-gray-400 text-xs border-2 border-dashed border-gray-300">사진 없음</div>'}
|
||||
${issue.photo_path2 ? `<img src="${issue.photo_path2}" class="w-20 h-20 object-cover rounded-lg cursor-pointer border-2 border-gray-200 hover:border-blue-400 transition-colors" onclick="openPhotoModal('${issue.photo_path2}')" alt="업로드 사진 2">` : '<div class="w-20 h-20 bg-gray-100 rounded-lg flex items-center justify-center text-gray-400 text-xs border-2 border-dashed border-gray-300">사진 없음</div>'}
|
||||
</div>
|
||||
${(() => {
|
||||
const photos = [
|
||||
issue.photo_path,
|
||||
issue.photo_path2,
|
||||
issue.photo_path3,
|
||||
issue.photo_path4,
|
||||
issue.photo_path5
|
||||
].filter(p => p);
|
||||
|
||||
if (photos.length === 0) {
|
||||
return '<div class="w-20 h-20 bg-gray-100 rounded-lg flex items-center justify-center text-gray-400 text-xs border-2 border-dashed border-gray-300">사진 없음</div>';
|
||||
}
|
||||
|
||||
return `
|
||||
<div class="flex flex-wrap gap-2">
|
||||
${photos.map((path, idx) => `
|
||||
<img src="${path}" class="w-20 h-20 object-cover rounded-lg cursor-pointer border-2 border-gray-200 hover:border-blue-400 transition-colors" onclick="openPhotoModal('${path}')" alt="업로드 사진 ${idx + 1}">
|
||||
`).join('')}
|
||||
</div>
|
||||
`;
|
||||
})()}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -903,11 +920,27 @@
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<label class="text-xs text-purple-600 font-medium">완료 사진</label>
|
||||
${issue.completion_photo_path ? `
|
||||
<div class="mt-1">
|
||||
<img src="${issue.completion_photo_path}" class="w-24 h-24 object-cover rounded-lg cursor-pointer border-2 border-purple-200 hover:border-purple-400 transition-colors" onclick="openPhotoModal('${issue.completion_photo_path}')" alt="완료 사진">
|
||||
</div>
|
||||
` : '<p class="text-xs text-gray-500 mt-1">완료 사진 없음</p>'}
|
||||
${(() => {
|
||||
const photos = [
|
||||
issue.completion_photo_path,
|
||||
issue.completion_photo_path2,
|
||||
issue.completion_photo_path3,
|
||||
issue.completion_photo_path4,
|
||||
issue.completion_photo_path5
|
||||
].filter(p => p);
|
||||
|
||||
if (photos.length === 0) {
|
||||
return '<p class="text-xs text-gray-500 mt-1">완료 사진 없음</p>';
|
||||
}
|
||||
|
||||
return `
|
||||
<div class="mt-1 flex flex-wrap gap-2">
|
||||
${photos.map(path => `
|
||||
<img src="${path}" class="w-20 h-20 object-cover rounded-lg cursor-pointer border-2 border-purple-200 hover:border-purple-400 transition-colors" onclick="openPhotoModal('${path}')" alt="완료 사진">
|
||||
`).join('')}
|
||||
</div>
|
||||
`;
|
||||
})()}
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-xs text-purple-600 font-medium">완료 코멘트</label>
|
||||
@@ -1015,20 +1048,27 @@
|
||||
<!-- 완료 사진 -->
|
||||
<div>
|
||||
<label class="text-xs text-green-600 font-medium">완료 사진</label>
|
||||
${issue.completion_photo_path ?
|
||||
(issue.completion_photo_path.toLowerCase().endsWith('.heic') ?
|
||||
`<div class="mt-1 flex items-center space-x-2">
|
||||
<div class="w-16 h-16 bg-green-100 rounded-lg flex items-center justify-center border border-green-200">
|
||||
<i class="fas fa-image text-green-500"></i>
|
||||
</div>
|
||||
<a href="${issue.completion_photo_path}" download class="text-xs text-blue-500 hover:text-blue-700 underline">HEIC 다운로드</a>
|
||||
</div>` :
|
||||
`<div class="mt-1">
|
||||
<img src="${issue.completion_photo_path}" class="w-16 h-16 object-cover rounded-lg cursor-pointer border-2 border-green-200 hover:border-green-400 transition-colors" onclick="openPhotoModal('${issue.completion_photo_path}')" alt="완료 사진">
|
||||
</div>`
|
||||
) :
|
||||
'<p class="text-xs text-gray-500 mt-1">완료 사진 없음</p>'
|
||||
}
|
||||
${(() => {
|
||||
const photos = [
|
||||
issue.completion_photo_path,
|
||||
issue.completion_photo_path2,
|
||||
issue.completion_photo_path3,
|
||||
issue.completion_photo_path4,
|
||||
issue.completion_photo_path5
|
||||
].filter(p => p);
|
||||
|
||||
if (photos.length === 0) {
|
||||
return '<p class="text-xs text-gray-500 mt-1">완료 사진 없음</p>';
|
||||
}
|
||||
|
||||
return `
|
||||
<div class="mt-1 flex flex-wrap gap-2">
|
||||
${photos.map(path => `
|
||||
<img src="${path}" class="w-16 h-16 object-cover rounded-lg cursor-pointer border-2 border-green-200 hover:border-green-400 transition-colors" onclick="openPhotoModal('${path}')" alt="완료 사진">
|
||||
`).join('')}
|
||||
</div>
|
||||
`;
|
||||
})()}
|
||||
</div>
|
||||
<!-- 완료 코멘트 -->
|
||||
<div>
|
||||
@@ -1052,10 +1092,27 @@
|
||||
<i class="fas fa-camera text-gray-500 mr-2"></i>
|
||||
업로드 사진
|
||||
</h4>
|
||||
<div class="flex gap-2">
|
||||
${issue.photo_path ? `<img src="${issue.photo_path}" class="w-20 h-20 object-cover rounded-lg cursor-pointer border-2 border-gray-200" onclick="openPhotoModal('${issue.photo_path}')" alt="업로드 사진 1">` : '<div class="w-20 h-20 bg-gray-100 rounded-lg flex items-center justify-center text-gray-400 text-xs">사진 없음</div>'}
|
||||
${issue.photo_path2 ? `<img src="${issue.photo_path2}" class="w-20 h-20 object-cover rounded-lg cursor-pointer border-2 border-gray-200" onclick="openPhotoModal('${issue.photo_path2}')" alt="업로드 사진 2">` : '<div class="w-20 h-20 bg-gray-100 rounded-lg flex items-center justify-center text-gray-400 text-xs">사진 없음</div>'}
|
||||
</div>
|
||||
${(() => {
|
||||
const photos = [
|
||||
issue.photo_path,
|
||||
issue.photo_path2,
|
||||
issue.photo_path3,
|
||||
issue.photo_path4,
|
||||
issue.photo_path5
|
||||
].filter(p => p);
|
||||
|
||||
if (photos.length === 0) {
|
||||
return '<div class="w-20 h-20 bg-gray-100 rounded-lg flex items-center justify-center text-gray-400 text-xs">사진 없음</div>';
|
||||
}
|
||||
|
||||
return `
|
||||
<div class="flex flex-wrap gap-2">
|
||||
${photos.map((path, idx) => `
|
||||
<img src="${path}" class="w-20 h-20 object-cover rounded-lg cursor-pointer border-2 border-gray-200" onclick="openPhotoModal('${path}')" alt="업로드 사진 ${idx + 1}">
|
||||
`).join('')}
|
||||
</div>
|
||||
`;
|
||||
})()}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -1402,10 +1459,27 @@
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">업로드 사진</label>
|
||||
<div class="flex gap-2">
|
||||
${issue.photo_path ? `<img src="${issue.photo_path}" class="w-20 h-20 object-cover rounded cursor-pointer" onclick="openPhotoModal('${issue.photo_path}')" alt="업로드 사진 1">` : '<div class="w-20 h-20 bg-gray-200 rounded flex items-center justify-center text-gray-500 text-xs">없음</div>'}
|
||||
${issue.photo_path2 ? `<img src="${issue.photo_path2}" class="w-20 h-20 object-cover rounded cursor-pointer" onclick="openPhotoModal('${issue.photo_path2}')" alt="업로드 사진 2">` : '<div class="w-20 h-20 bg-gray-200 rounded flex items-center justify-center text-gray-500 text-xs">없음</div>'}
|
||||
</div>
|
||||
${(() => {
|
||||
const photos = [
|
||||
issue.photo_path,
|
||||
issue.photo_path2,
|
||||
issue.photo_path3,
|
||||
issue.photo_path4,
|
||||
issue.photo_path5
|
||||
].filter(p => p);
|
||||
|
||||
if (photos.length === 0) {
|
||||
return '<div class="w-20 h-20 bg-gray-200 rounded flex items-center justify-center text-gray-500 text-xs">없음</div>';
|
||||
}
|
||||
|
||||
return `
|
||||
<div class="flex flex-wrap gap-2">
|
||||
${photos.map((path, idx) => `
|
||||
<img src="${path}" class="w-20 h-20 object-cover rounded cursor-pointer border-2 border-gray-300 hover:border-blue-400 transition-colors" onclick="openPhotoModal('${path}')" alt="업로드 사진 ${idx + 1}">
|
||||
`).join('')}
|
||||
</div>
|
||||
`;
|
||||
})()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1454,13 +1528,37 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">완료 사진</label>
|
||||
<div class="flex items-center gap-3">
|
||||
${issue.completion_photo_path ?
|
||||
`<img src="${issue.completion_photo_path}" class="w-20 h-20 object-cover rounded cursor-pointer" onclick="openPhotoModal('${issue.completion_photo_path}')" alt="완료 사진">` :
|
||||
'<div class="w-20 h-20 bg-gray-200 rounded flex items-center justify-center text-gray-500 text-xs">없음</div>'
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">완료 사진 (최대 5장)</label>
|
||||
|
||||
<!-- 기존 완료 사진 표시 -->
|
||||
${(() => {
|
||||
const photos = [
|
||||
issue.completion_photo_path,
|
||||
issue.completion_photo_path2,
|
||||
issue.completion_photo_path3,
|
||||
issue.completion_photo_path4,
|
||||
issue.completion_photo_path5
|
||||
].filter(p => p);
|
||||
|
||||
if (photos.length > 0) {
|
||||
return `
|
||||
<div class="mb-3">
|
||||
<p class="text-xs text-gray-600 mb-2">현재 완료 사진 (${photos.length}장)</p>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
${photos.map(path => `
|
||||
<img src="${path}" class="w-16 h-16 object-cover rounded cursor-pointer border-2 border-gray-300 hover:border-blue-400 transition-colors" onclick="openPhotoModal('${path}')" alt="완료 사진">
|
||||
`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
<input type="file" id="modal_completion_photo" accept="image/*" class="flex-1 text-sm">
|
||||
return '';
|
||||
})()}
|
||||
|
||||
<!-- 사진 업로드 (최대 5장) -->
|
||||
<div class="space-y-2">
|
||||
<input type="file" id="modal_completion_photo" accept="image/*" multiple class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-lg file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100">
|
||||
<p class="text-xs text-gray-500">※ 최대 5장까지 업로드 가능합니다. 새로운 사진을 업로드하면 기존 사진을 모두 교체합니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1488,11 +1586,20 @@
|
||||
}
|
||||
});
|
||||
|
||||
// 완료 사진 처리
|
||||
const photoFile = document.getElementById('modal_completion_photo').files[0];
|
||||
if (photoFile) {
|
||||
const base64 = await fileToBase64(photoFile);
|
||||
updates.completion_photo = base64;
|
||||
// 완료 사진 처리 (최대 5장)
|
||||
const photoInput = document.getElementById('modal_completion_photo');
|
||||
const photoFiles = photoInput.files;
|
||||
|
||||
if (photoFiles && photoFiles.length > 0) {
|
||||
const maxPhotos = Math.min(photoFiles.length, 5);
|
||||
|
||||
for (let i = 0; i < maxPhotos; i++) {
|
||||
const base64 = await fileToBase64(photoFiles[i]);
|
||||
const fieldName = i === 0 ? 'completion_photo' : `completion_photo${i + 1}`;
|
||||
updates[fieldName] = base64;
|
||||
}
|
||||
|
||||
console.log(`📸 ${maxPhotos}장의 완료 사진 처리 완료`);
|
||||
}
|
||||
|
||||
console.log('Modal sending updates:', updates);
|
||||
@@ -1869,10 +1976,27 @@
|
||||
|
||||
<div class="bg-gray-50 p-4 rounded-lg">
|
||||
<h4 class="font-semibold text-gray-800 mb-3">업로드 사진</h4>
|
||||
<div class="flex gap-2">
|
||||
${issue.photo_path ? `<img src="${issue.photo_path}" class="w-20 h-20 object-cover rounded-lg cursor-pointer border-2 border-gray-200" onclick="openPhotoModal('${issue.photo_path}')" alt="업로드 사진 1">` : '<div class="w-20 h-20 bg-gray-100 rounded-lg flex items-center justify-center text-gray-400 text-xs">사진 없음</div>'}
|
||||
${issue.photo_path2 ? `<img src="${issue.photo_path2}" class="w-20 h-20 object-cover rounded-lg cursor-pointer border-2 border-gray-200" onclick="openPhotoModal('${issue.photo_path2}')" alt="업로드 사진 2">` : '<div class="w-20 h-20 bg-gray-100 rounded-lg flex items-center justify-center text-gray-400 text-xs">사진 없음</div>'}
|
||||
</div>
|
||||
${(() => {
|
||||
const photos = [
|
||||
issue.photo_path,
|
||||
issue.photo_path2,
|
||||
issue.photo_path3,
|
||||
issue.photo_path4,
|
||||
issue.photo_path5
|
||||
].filter(p => p);
|
||||
|
||||
if (photos.length === 0) {
|
||||
return '<div class="w-20 h-20 bg-gray-100 rounded-lg flex items-center justify-center text-gray-400 text-xs">사진 없음</div>';
|
||||
}
|
||||
|
||||
return `
|
||||
<div class="flex flex-wrap gap-2">
|
||||
${photos.map((path, idx) => `
|
||||
<img src="${path}" class="w-20 h-20 object-cover rounded-lg cursor-pointer border-2 border-gray-200 hover:border-blue-400 transition-colors" onclick="openPhotoModal('${path}')" alt="업로드 사진 ${idx + 1}">
|
||||
`).join('')}
|
||||
</div>
|
||||
`;
|
||||
})()}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1923,32 +2047,57 @@
|
||||
<h4 class="font-semibold text-purple-800 mb-3">완료 신청 정보</h4>
|
||||
<div class="space-y-3">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">완료 사진</label>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">완료 사진 (최대 5장)</label>
|
||||
<div class="space-y-3">
|
||||
${issue.completion_photo_path ? `
|
||||
<div class="flex items-center space-x-3">
|
||||
<img src="${issue.completion_photo_path}" class="w-24 h-24 object-cover rounded-lg cursor-pointer border-2 border-purple-200 hover:border-purple-400 transition-colors" onclick="openPhotoModal('${issue.completion_photo_path}')" alt="현재 완료 사진">
|
||||
<div class="flex-1">
|
||||
<p class="text-sm text-gray-600 mb-1">현재 완료 사진</p>
|
||||
<p class="text-xs text-gray-500">클릭하면 크게 볼 수 있습니다</p>
|
||||
</div>
|
||||
</div>
|
||||
` : `
|
||||
<div class="flex items-center justify-center w-24 h-24 bg-gray-100 border-2 border-dashed border-gray-300 rounded-lg">
|
||||
<div class="text-center">
|
||||
<i class="fas fa-camera text-gray-400 text-lg mb-1"></i>
|
||||
<p class="text-xs text-gray-500">사진 없음</p>
|
||||
</div>
|
||||
</div>
|
||||
`}
|
||||
${(() => {
|
||||
const photos = [
|
||||
issue.completion_photo_path,
|
||||
issue.completion_photo_path2,
|
||||
issue.completion_photo_path3,
|
||||
issue.completion_photo_path4,
|
||||
issue.completion_photo_path5
|
||||
].filter(p => p);
|
||||
|
||||
if (photos.length > 0) {
|
||||
return `
|
||||
<div class="mb-3">
|
||||
<p class="text-xs text-gray-600 mb-2">현재 완료 사진 (${photos.length}장)</p>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
${photos.map(path => `
|
||||
<img src="${path}" class="w-20 h-20 object-cover rounded-lg cursor-pointer border-2 border-purple-200 hover:border-purple-400 transition-colors" onclick="openPhotoModal('${path}')" alt="완료 사진">
|
||||
`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
return `
|
||||
<div class="flex items-center justify-center w-24 h-24 bg-gray-100 border-2 border-dashed border-gray-300 rounded-lg mb-3">
|
||||
<div class="text-center">
|
||||
<i class="fas fa-camera text-gray-400 text-lg mb-1"></i>
|
||||
<p class="text-xs text-gray-500">사진 없음</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
})()}
|
||||
<div class="flex items-center space-x-2">
|
||||
<input type="file" id="edit-completion-photo-${issue.id}" accept="image/*" class="hidden">
|
||||
<input type="file" id="edit-completion-photo-${issue.id}" accept="image/*" multiple class="hidden">
|
||||
<button type="button" onclick="document.getElementById('edit-completion-photo-${issue.id}').click()" class="flex items-center px-4 py-2 bg-purple-500 text-white rounded-lg hover:bg-purple-600 transition-colors text-sm">
|
||||
<i class="fas fa-upload mr-2"></i>
|
||||
${issue.completion_photo_path ? '사진 교체' : '사진 업로드'}
|
||||
${(() => {
|
||||
const photoCount = [
|
||||
issue.completion_photo_path,
|
||||
issue.completion_photo_path2,
|
||||
issue.completion_photo_path3,
|
||||
issue.completion_photo_path4,
|
||||
issue.completion_photo_path5
|
||||
].filter(p => p).length;
|
||||
return photoCount > 0 ? '사진 교체' : '사진 업로드';
|
||||
})()}
|
||||
</button>
|
||||
<span id="photo-filename-${issue.id}" class="text-sm text-gray-600"></span>
|
||||
</div>
|
||||
<p class="text-xs text-gray-500">※ 최대 5장까지 업로드 가능합니다. 새로운 사진을 업로드하면 기존 사진을 모두 교체합니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
@@ -1995,8 +2144,9 @@
|
||||
|
||||
if (fileInput && filenameSpan) {
|
||||
fileInput.addEventListener('change', function(e) {
|
||||
if (e.target.files && e.target.files[0]) {
|
||||
filenameSpan.textContent = e.target.files[0].name;
|
||||
if (e.target.files && e.target.files.length > 0) {
|
||||
const fileCount = Math.min(e.target.files.length, 5);
|
||||
filenameSpan.textContent = `${fileCount}개 파일 선택됨`;
|
||||
filenameSpan.className = 'text-sm text-green-600 font-medium';
|
||||
} else {
|
||||
filenameSpan.textContent = '';
|
||||
@@ -2038,31 +2188,38 @@
|
||||
// 완료 신청 정보 (완료 대기 상태일 때만)
|
||||
const completionCommentElement = document.getElementById(`edit-completion-comment-${issueId}`);
|
||||
const completionPhotoElement = document.getElementById(`edit-completion-photo-${issueId}`);
|
||||
|
||||
|
||||
let completionComment = null;
|
||||
let completionPhoto = null;
|
||||
|
||||
const completionPhotos = {}; // 완료 사진들을 저장할 객체
|
||||
|
||||
if (completionCommentElement) {
|
||||
completionComment = completionCommentElement.value.trim();
|
||||
}
|
||||
|
||||
if (completionPhotoElement && completionPhotoElement.files[0]) {
|
||||
|
||||
// 완료 사진 처리 (최대 5장)
|
||||
if (completionPhotoElement && completionPhotoElement.files.length > 0) {
|
||||
try {
|
||||
const file = completionPhotoElement.files[0];
|
||||
console.log('🔍 업로드할 파일 정보:', {
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
type: file.type,
|
||||
lastModified: file.lastModified
|
||||
});
|
||||
|
||||
const base64 = await fileToBase64(file);
|
||||
console.log('🔍 Base64 변환 완료 - 전체 길이:', base64.length);
|
||||
console.log('🔍 Base64 헤더:', base64.substring(0, 50));
|
||||
|
||||
completionPhoto = base64.split(',')[1]; // Base64 데이터만 추출
|
||||
console.log('🔍 헤더 제거 후 길이:', completionPhoto.length);
|
||||
console.log('🔍 전송할 Base64 시작 부분:', completionPhoto.substring(0, 50));
|
||||
const files = completionPhotoElement.files;
|
||||
const maxPhotos = Math.min(files.length, 5);
|
||||
|
||||
console.log(`🔍 총 ${maxPhotos}개의 완료 사진 업로드 시작`);
|
||||
|
||||
for (let i = 0; i < maxPhotos; i++) {
|
||||
const file = files[i];
|
||||
console.log(`🔍 파일 ${i + 1} 정보:`, {
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
type: file.type
|
||||
});
|
||||
|
||||
const base64 = await fileToBase64(file);
|
||||
const base64Data = base64.split(',')[1]; // Base64 데이터만 추출
|
||||
|
||||
const fieldName = i === 0 ? 'completion_photo' : `completion_photo${i + 1}`;
|
||||
completionPhotos[fieldName] = base64Data;
|
||||
|
||||
console.log(`✅ 파일 ${i + 1} 변환 완료 (${fieldName})`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('파일 변환 오류:', error);
|
||||
alert('완료 사진 업로드 중 오류가 발생했습니다.');
|
||||
@@ -2091,8 +2248,9 @@
|
||||
if (completionComment !== null) {
|
||||
requestBody.completion_comment = completionComment || null;
|
||||
}
|
||||
if (completionPhoto !== null) {
|
||||
requestBody.completion_photo = completionPhoto;
|
||||
// 완료 사진들 추가 (최대 5장)
|
||||
for (const [key, value] of Object.entries(completionPhotos)) {
|
||||
requestBody[key] = value;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user