store source release
This commit is contained in:
parent
ccdc2c91bb
commit
4be4ba790f
@ -140,8 +140,10 @@ class StoreService {
|
|||||||
businessType: storeData.businessType,
|
businessType: storeData.businessType,
|
||||||
address: storeData.address,
|
address: storeData.address,
|
||||||
phoneNumber: storeData.phoneNumber,
|
phoneNumber: storeData.phoneNumber,
|
||||||
businessHours: storeData.businessHours,
|
// ✅ 수정: businessHours 필드 처리
|
||||||
closedDays: storeData.closedDays,
|
businessHours: storeData.businessHours || `${storeData.openTime || '09:00'}-${storeData.closeTime || '21:00'}`,
|
||||||
|
// ✅ 수정: closedDays 필드 처리
|
||||||
|
closedDays: storeData.closedDays || storeData.holidays || '',
|
||||||
seatCount: parseInt(storeData.seatCount) || 0,
|
seatCount: parseInt(storeData.seatCount) || 0,
|
||||||
instaAccounts: storeData.instaAccounts || '',
|
instaAccounts: storeData.instaAccounts || '',
|
||||||
blogAccounts: storeData.blogAccounts || '',
|
blogAccounts: storeData.blogAccounts || '',
|
||||||
@ -150,9 +152,9 @@ class StoreService {
|
|||||||
|
|
||||||
console.log('백엔드 전송 데이터:', requestData)
|
console.log('백엔드 전송 데이터:', requestData)
|
||||||
|
|
||||||
// PUT 요청 (storeId는 JWT에서 추출하므로 URL에 포함하지 않음)
|
// ✅ 핵심 수정: 슬래시 제거하고 빈 문자열 사용
|
||||||
const response = await storeApi.put('/', requestData)
|
console.log('API 호출 경로: PUT /api/store (baseURL + 빈 문자열)')
|
||||||
|
const response = await storeApi.put('', requestData)
|
||||||
console.log('매장 정보 수정 API 응답:', response.data)
|
console.log('매장 정보 수정 API 응답:', response.data)
|
||||||
|
|
||||||
if (response.data && (response.data.status === 200 || response.data.success !== false)) {
|
if (response.data && (response.data.status === 200 || response.data.success !== false)) {
|
||||||
|
|||||||
@ -356,8 +356,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 매장 등록/수정 다이얼로그 -->
|
<!-- 매장 등록/수정 다이얼로그 -->
|
||||||
<v-dialog v-model="showCreateDialog" max-width="600" persistent>
|
<v-dialog
|
||||||
<v-card>
|
v-model="showCreateDialog"
|
||||||
|
max-width="600"
|
||||||
|
persistent
|
||||||
|
:style="{ zIndex: 2000 }"
|
||||||
|
class="store-dialog"
|
||||||
|
>
|
||||||
|
<v-card class="store-dialog-card">
|
||||||
<v-card-title class="pa-4">
|
<v-card-title class="pa-4">
|
||||||
<div class="d-flex align-center">
|
<div class="d-flex align-center">
|
||||||
<v-icon class="mr-2" color="primary">mdi-store</v-icon>
|
<v-icon class="mr-2" color="primary">mdi-store</v-icon>
|
||||||
@ -367,7 +373,8 @@
|
|||||||
|
|
||||||
<v-divider />
|
<v-divider />
|
||||||
|
|
||||||
<v-card-text class="pa-4">
|
<!-- ✅ 스크롤 가능한 컨텐츠 영역 -->
|
||||||
|
<v-card-text class="pa-4 store-dialog-content">
|
||||||
<v-form ref="storeFormRef" v-model="formValid">
|
<v-form ref="storeFormRef" v-model="formValid">
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="12">
|
<v-col cols="12">
|
||||||
@ -481,7 +488,7 @@
|
|||||||
label="매장 소개"
|
label="매장 소개"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
density="compact"
|
density="compact"
|
||||||
rows="3"
|
rows="2"
|
||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
@ -506,7 +513,7 @@
|
|||||||
</v-btn>
|
</v-btn>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
|
|
||||||
<!-- 메뉴 등록/수정 다이얼로그 -->
|
<!-- 메뉴 등록/수정 다이얼로그 -->
|
||||||
<v-dialog
|
<v-dialog
|
||||||
@ -778,7 +785,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted, watch } from 'vue'
|
import { ref, computed, onMounted, watch, nextTick } from 'vue'
|
||||||
import { useStoreStore } from '@/store/index'
|
import { useStoreStore } from '@/store/index'
|
||||||
|
|
||||||
const storeStore = useStoreStore()
|
const storeStore = useStoreStore()
|
||||||
@ -804,6 +811,7 @@ const menuFormValid = ref(false)
|
|||||||
// 이미지 관련 상태
|
// 이미지 관련 상태
|
||||||
const selectedImageFile = ref(null)
|
const selectedImageFile = ref(null)
|
||||||
const previewImageUrl = ref('')
|
const previewImageUrl = ref('')
|
||||||
|
const forceShowFileInput = ref(false) // ✅ 추가: 파일 입력 강제 표시용
|
||||||
|
|
||||||
// 메뉴 폼 데이터
|
// 메뉴 폼 데이터
|
||||||
const menuFormData = ref({
|
const menuFormData = ref({
|
||||||
@ -881,8 +889,13 @@ const filteredMenus = computed(() => {
|
|||||||
return filtered
|
return filtered
|
||||||
})
|
})
|
||||||
|
|
||||||
// 이미지 미리보기 표시 조건 (computed)
|
// 이미지 미리보기 표시 조건 수정
|
||||||
const shouldShowImagePreview = computed(() => {
|
const shouldShowImagePreview = computed(() => {
|
||||||
|
// ✅ 강제로 파일 입력을 보여줘야 하는 경우
|
||||||
|
if (forceShowFileInput.value) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
// 1순위: 새로 선택한 이미지 미리보기
|
// 1순위: 새로 선택한 이미지 미리보기
|
||||||
if (previewImageUrl.value) {
|
if (previewImageUrl.value) {
|
||||||
return previewImageUrl.value
|
return previewImageUrl.value
|
||||||
@ -895,7 +908,6 @@ const shouldShowImagePreview = computed(() => {
|
|||||||
|
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
|
|
||||||
// ===== 유틸리티 함수들 =====
|
// ===== 유틸리티 함수들 =====
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1016,13 +1028,14 @@ watch(selectedImageFile, (newFile, oldFile) => {
|
|||||||
}
|
}
|
||||||
}, { immediate: false })
|
}, { immediate: false })
|
||||||
|
|
||||||
// v-file-input의 modelValue 변경 감지 함수
|
// ✅ 파일 입력 변경 감지 함수 개선
|
||||||
const onFileInputChange = (file) => {
|
const onFileInputChange = (file) => {
|
||||||
console.log('=== v-file-input v-model 변경 감지 ===')
|
console.log('=== v-file-input v-model 변경 감지 ===')
|
||||||
console.log('전달받은 file:', file)
|
console.log('전달받은 file:', file)
|
||||||
|
|
||||||
if (file) {
|
if (file) {
|
||||||
// selectedImageFile에 할당
|
// 파일이 선택되면 강제 표시 모드 해제
|
||||||
|
forceShowFileInput.value = false
|
||||||
selectedImageFile.value = file
|
selectedImageFile.value = file
|
||||||
onImageFileSelected(file)
|
onImageFileSelected(file)
|
||||||
} else {
|
} else {
|
||||||
@ -1158,17 +1171,21 @@ const uploadMenuImage = async (menuId) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 이미지 선택 초기화 함수
|
// ✅ 개선된 이미지 선택 초기화 함수
|
||||||
const resetImageSelection = () => {
|
const resetImageSelection = () => {
|
||||||
console.log('이미지 선택 초기화')
|
console.log('=== 이미지 선택 초기화 시작 ===')
|
||||||
|
|
||||||
|
// 1. 모든 이미지 관련 상태 초기화
|
||||||
selectedImageFile.value = null
|
selectedImageFile.value = null
|
||||||
previewImageUrl.value = ''
|
previewImageUrl.value = ''
|
||||||
|
|
||||||
// v-file-input도 초기화하기 위해 DOM 조작 추가
|
// 2. 강제로 파일 입력 표시
|
||||||
const fileInput = document.querySelector('input[type="file"]')
|
forceShowFileInput.value = true
|
||||||
if (fileInput) {
|
|
||||||
fileInput.value = ''
|
// 3. Vue의 반응성을 위해 nextTick 사용
|
||||||
}
|
nextTick(() => {
|
||||||
|
console.log('✅ 이미지 선택 초기화 완료 - 파일 입력 표시됨')
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 드래그앤드롭 처리
|
// 드래그앤드롭 처리
|
||||||
@ -1206,7 +1223,7 @@ const resetForm = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 메뉴 폼 리셋 함수
|
// ✅ 메뉴 폼 리셋 함수 개선
|
||||||
const resetMenuForm = () => {
|
const resetMenuForm = () => {
|
||||||
console.log('=== 메뉴 폼 리셋 ===')
|
console.log('=== 메뉴 폼 리셋 ===')
|
||||||
|
|
||||||
@ -1225,6 +1242,7 @@ const resetMenuForm = () => {
|
|||||||
// 이미지 관련 상태 초기화
|
// 이미지 관련 상태 초기화
|
||||||
selectedImageFile.value = null
|
selectedImageFile.value = null
|
||||||
previewImageUrl.value = ''
|
previewImageUrl.value = ''
|
||||||
|
forceShowFileInput.value = false // ✅ 추가
|
||||||
|
|
||||||
if (menuFormRef.value) {
|
if (menuFormRef.value) {
|
||||||
menuFormRef.value.resetValidation()
|
menuFormRef.value.resetValidation()
|
||||||
@ -1273,7 +1291,7 @@ const openCreateMenuDialog = () => {
|
|||||||
showMenuDialog.value = true
|
showMenuDialog.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 메뉴 수정 함수
|
// ✅ 메뉴 수정 함수에서 이미지 상태 올바르게 설정
|
||||||
const editMenu = (menu) => {
|
const editMenu = (menu) => {
|
||||||
console.log('=== 메뉴 수정 호출 ===')
|
console.log('=== 메뉴 수정 호출 ===')
|
||||||
console.log('전달받은 메뉴 객체:', menu)
|
console.log('전달받은 메뉴 객체:', menu)
|
||||||
@ -1309,11 +1327,13 @@ const editMenu = (menu) => {
|
|||||||
imageUrl: menu.image || menu.imageUrl || ''
|
imageUrl: menu.image || menu.imageUrl || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// 이미지 상태 초기화
|
// ✅ 이미지 상태 올바르게 초기화
|
||||||
selectedImageFile.value = null
|
selectedImageFile.value = null
|
||||||
previewImageUrl.value = ''
|
previewImageUrl.value = ''
|
||||||
|
forceShowFileInput.value = false // 기존 이미지를 먼저 보여줌
|
||||||
|
|
||||||
console.log('✅ 메뉴 수정 폼 데이터 설정 완료:', menuFormData.value)
|
console.log('✅ 메뉴 수정 폼 데이터 설정 완료:', menuFormData.value)
|
||||||
|
console.log('✅ 기존 이미지 URL:', menuFormData.value.imageUrl)
|
||||||
showMenuDialog.value = true
|
showMenuDialog.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1372,6 +1392,8 @@ const cancelMenuForm = () => {
|
|||||||
|
|
||||||
// ===== 저장 관련 함수들 =====
|
// ===== 저장 관련 함수들 =====
|
||||||
|
|
||||||
|
// ✅ StoreManagementView.vue의 saveStore 함수 수정
|
||||||
|
|
||||||
// 매장 정보 저장 함수
|
// 매장 정보 저장 함수
|
||||||
const saveStore = async () => {
|
const saveStore = async () => {
|
||||||
if (!storeFormRef.value) {
|
if (!storeFormRef.value) {
|
||||||
@ -1389,17 +1411,19 @@ const saveStore = async () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('매장 정보 저장 시작')
|
console.log('매장 정보 저장 시작')
|
||||||
|
console.log('폼 데이터:', formData.value)
|
||||||
|
|
||||||
// 백엔드 형식에 맞는 데이터 구조로 변환
|
// ✅ 백엔드 형식에 맞는 데이터 구조로 변환
|
||||||
const storeData = {
|
const storeData = {
|
||||||
storeName: formData.value.storeName,
|
storeName: formData.value.storeName,
|
||||||
businessType: formData.value.businessType,
|
businessType: formData.value.businessType,
|
||||||
address: formData.value.address,
|
address: formData.value.address,
|
||||||
phoneNumber: formData.value.phoneNumber || '',
|
phoneNumber: formData.value.phoneNumber || '',
|
||||||
openTime: formData.value.openTime || '09:00',
|
// ✅ 수정: 시간 범위 문자열로 생성
|
||||||
closeTime: formData.value.closeTime || '21:00',
|
businessHours: `${formData.value.openTime || '09:00'}-${formData.value.closeTime || '21:00'}`,
|
||||||
holidays: Array.isArray(formData.value.holidays) ?
|
// ✅ 수정: 휴무일 배열을 문자열로 변환
|
||||||
formData.value.holidays.join(',') : '',
|
closedDays: Array.isArray(formData.value.holidays) ?
|
||||||
|
formData.value.holidays.join(',') : (formData.value.holidays || ''),
|
||||||
seatCount: parseInt(formData.value.seatCount) || 0,
|
seatCount: parseInt(formData.value.seatCount) || 0,
|
||||||
instaAccounts: formData.value.instagramUrl || '',
|
instaAccounts: formData.value.instagramUrl || '',
|
||||||
blogAccounts: formData.value.blogUrl || '',
|
blogAccounts: formData.value.blogUrl || '',
|
||||||
@ -1407,11 +1431,19 @@ const saveStore = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log('백엔드로 전송할 데이터:', storeData)
|
console.log('백엔드로 전송할 데이터:', storeData)
|
||||||
|
console.log('=== 필드별 상세 정보 ===')
|
||||||
|
console.log('storeName:', storeData.storeName, '(타입:', typeof storeData.storeName, ')')
|
||||||
|
console.log('businessType:', storeData.businessType, '(타입:', typeof storeData.businessType, ')')
|
||||||
|
console.log('businessHours:', storeData.businessHours, '(타입:', typeof storeData.businessHours, ')')
|
||||||
|
console.log('closedDays:', storeData.closedDays, '(타입:', typeof storeData.closedDays, ')')
|
||||||
|
console.log('seatCount:', storeData.seatCount, '(타입:', typeof storeData.seatCount, ')')
|
||||||
|
|
||||||
let result
|
let result
|
||||||
if (editMode.value) {
|
if (editMode.value) {
|
||||||
|
console.log('🔄 매장 정보 수정 API 호출')
|
||||||
result = await storeStore.updateStore(storeInfo.value.storeId, storeData)
|
result = await storeStore.updateStore(storeInfo.value.storeId, storeData)
|
||||||
} else {
|
} else {
|
||||||
|
console.log('➕ 매장 정보 등록 API 호출')
|
||||||
result = await storeStore.registerStore(storeData)
|
result = await storeStore.registerStore(storeData)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1437,6 +1469,8 @@ const saveStore = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ✅ 메뉴 수정 후 위치 유지를 위한 saveMenu 함수 개선
|
||||||
|
|
||||||
// 메뉴 저장 함수
|
// 메뉴 저장 함수
|
||||||
const saveMenu = async () => {
|
const saveMenu = async () => {
|
||||||
console.log('=== 메뉴 저장 시작 ===')
|
console.log('=== 메뉴 저장 시작 ===')
|
||||||
@ -1469,6 +1503,7 @@ const saveMenu = async () => {
|
|||||||
|
|
||||||
let menuResult
|
let menuResult
|
||||||
let savedMenuId
|
let savedMenuId
|
||||||
|
let isEdit = menuEditMode.value // ✅ 수정 모드 여부 저장
|
||||||
|
|
||||||
if (menuEditMode.value) {
|
if (menuEditMode.value) {
|
||||||
// 메뉴 수정
|
// 메뉴 수정
|
||||||
@ -1530,21 +1565,33 @@ const saveMenu = async () => {
|
|||||||
|
|
||||||
if (imageUrl) {
|
if (imageUrl) {
|
||||||
console.log('✅ 이미지 업로드 완료:', imageUrl)
|
console.log('✅ 이미지 업로드 완료:', imageUrl)
|
||||||
showSnackbar(`메뉴가 ${menuEditMode.value ? '수정' : '등록'}되었고 이미지도 업로드되었습니다`, 'success')
|
showSnackbar(`메뉴가 ${isEdit ? '수정' : '등록'}되었고 이미지도 업로드되었습니다`, 'success')
|
||||||
} else {
|
} else {
|
||||||
console.warn('⚠️ 이미지 업로드 실패')
|
console.warn('⚠️ 이미지 업로드 실패')
|
||||||
showSnackbar(`메뉴는 ${menuEditMode.value ? '수정' : '등록'}되었지만 이미지 업로드에 실패했습니다`, 'warning')
|
showSnackbar(`메뉴는 ${isEdit ? '수정' : '등록'}되었지만 이미지 업로드에 실패했습니다`, 'warning')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('새 이미지가 선택되지 않아 이미지 업로드 건너뜀')
|
console.log('새 이미지가 선택되지 않아 이미지 업로드 건너뜀')
|
||||||
showSnackbar(`메뉴가 ${menuEditMode.value ? '수정' : '등록'}되었습니다`, 'success')
|
showSnackbar(`메뉴가 ${isEdit ? '수정' : '등록'}되었습니다`, 'success')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 다이얼로그 닫기 및 목록 새로고침
|
// ✅ 다이얼로그 닫기 및 상태 초기화
|
||||||
showMenuDialog.value = false
|
showMenuDialog.value = false
|
||||||
menuEditMode.value = false
|
menuEditMode.value = false
|
||||||
resetMenuForm()
|
resetMenuForm()
|
||||||
await loadMenus()
|
|
||||||
|
// ✅ 메뉴 목록 새로고침 (수정 모드일 때는 지연 없이 즉시)
|
||||||
|
if (isEdit) {
|
||||||
|
// 수정인 경우: 즉시 새로고침하여 위치 유지
|
||||||
|
await loadMenus()
|
||||||
|
console.log('✅ 메뉴 수정 완료 - 목록 새로고침됨 (위치 유지)')
|
||||||
|
} else {
|
||||||
|
// 신규 등록인 경우: 약간의 지연 후 새로고침 (새 메뉴가 맨 앞에 추가됨)
|
||||||
|
setTimeout(async () => {
|
||||||
|
await loadMenus()
|
||||||
|
console.log('✅ 메뉴 등록 완료 - 목록 새로고침됨')
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ 메뉴 저장 중 예외 발생:', error)
|
console.error('❌ 메뉴 저장 중 예외 발생:', error)
|
||||||
@ -2136,4 +2183,56 @@ onMounted(async () => {
|
|||||||
.dialog-content::-webkit-scrollbar-thumb:hover {
|
.dialog-content::-webkit-scrollbar-thumb:hover {
|
||||||
background: #a8a8a8;
|
background: #a8a8a8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ✅ 매장 다이얼로그 스타일 추가 - Style 부분에 추가 */
|
||||||
|
|
||||||
|
/* 매장 다이얼로그 전용 스타일 */
|
||||||
|
.store-dialog .v-overlay__content {
|
||||||
|
max-height: 90vh !important;
|
||||||
|
margin: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-dialog-card {
|
||||||
|
max-height: 90vh !important;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-dialog-card .store-dialog-content {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: calc(90vh - 120px); /* 헤더와 푸터 공간 제외 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 모바일에서 매장 다이얼로그 최적화 */
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.store-dialog .v-overlay__content {
|
||||||
|
margin: 16px;
|
||||||
|
max-height: 95vh !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-dialog-card .store-dialog-content {
|
||||||
|
max-height: calc(95vh - 100px);
|
||||||
|
padding: 16px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 매장 다이얼로그 스크롤바 스타일 */
|
||||||
|
.store-dialog-content::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-dialog-content::-webkit-scrollbar-track {
|
||||||
|
background: #f1f1f1;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-dialog-content::-webkit-scrollbar-thumb {
|
||||||
|
background: #c1c1c1;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-dialog-content::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #a8a8a8;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Loading…
x
Reference in New Issue
Block a user