diff --git a/src/services/api.js b/src/services/api.js index 9273a97..63700c4 100644 --- a/src/services/api.js +++ b/src/services/api.js @@ -6,7 +6,6 @@ const getApiUrls = () => { const config = window.__runtime_config__ || {} return { GATEWAY_URL: config.GATEWAY_URL || 'http://20.1.2.3', -<<<<<<< HEAD AUTH_URL: config.AUTH_URL || 'http://localhost:8081/api/auth', MEMBER_URL: config.MEMBER_URL || 'http://localhost:8081/api/member', STORE_URL: config.STORE_URL || 'http://localhost:8082/api/store', @@ -16,7 +15,6 @@ const getApiUrls = () => { SALES_URL: config.SALES_URL || 'http://localhost:8082/api/sales', // ⚠️ 수정: 추천 API는 ai-recommend 서비스 (포트 8084) RECOMMEND_URL: config.RECOMMEND_URL || 'http://localhost:8084/api/recommendations', -======= AUTH_URL: 'http://localhost:8081/api/auth', MEMBER_URL: 'http://localhost:8081/api/member', STORE_URL: config.STORE_URL || 'http://localhost:8082/api/store', @@ -24,7 +22,6 @@ const getApiUrls = () => { MENU_URL: config.MENU_URL || 'http://localhost:8082/api/menu', SALES_URL: config.SALES_URL || 'http://localhost:8082/api/sales', RECOMMEND_URL: config.RECOMMEND_URL || 'http://20.1.2.3/api/recommendation', ->>>>>>> 87871709f2bbcdab5df004a3954d6ba0af3cadce } } diff --git a/src/services/menu.js b/src/services/menu.js index d911e78..1ecb3e7 100644 --- a/src/services/menu.js +++ b/src/services/menu.js @@ -1,5 +1,5 @@ -// src/services/menu.js - 메뉴 관련 API 서비스 -import { menuApi, handleApiError, formatSuccessResponse } from './api.js' +//* src/services/menu.js - 백엔드 수정 없이 프론트엔드만 수정 +import { menuApi, apiWithImage, handleApiError, formatSuccessResponse } from './api.js' /** * 메뉴 관련 API 서비스 @@ -48,42 +48,7 @@ class MenuService { } /** - * 메뉴 상세 조회 - * @param {number} menuId - 메뉴 ID - * @returns {Promise} 메뉴 상세 정보 - */ - async getMenuDetail(menuId) { - try { - console.log('=== 메뉴 상세 조회 API 호출 ===') - console.log('메뉴 ID:', menuId) - - if (!menuId || menuId === 'undefined') { - throw new Error('올바른 메뉴 ID가 필요합니다') - } - - const numericMenuId = parseInt(menuId) - if (isNaN(numericMenuId)) { - throw new Error('메뉴 ID는 숫자여야 합니다') - } - - // GET /api/menu/{menuId} - const response = await menuApi.get(`/${numericMenuId}`) - - console.log('메뉴 상세 조회 API 응답:', response.data) - - if (response.data && response.data.status === 200) { - return formatSuccessResponse(response.data.data, '메뉴 상세 정보를 조회했습니다.') - } else { - throw new Error(response.data.message || '메뉴를 찾을 수 없습니다.') - } - } catch (error) { - console.error('메뉴 상세 조회 실패:', error) - return handleApiError(error) - } - } - - /** - * 메뉴 등록 + * 메뉴 등록 (createMenu) * @param {Object} menuData - 메뉴 정보 * @returns {Promise} 등록 결과 */ @@ -94,7 +59,7 @@ class MenuService { const requestData = { storeId: menuData.storeId, - menuName: menuData.menuName, + menuName: menuData.menuName || menuData.name, category: menuData.category, price: parseInt(menuData.price) || 0, description: menuData.description || '' @@ -119,47 +84,163 @@ class MenuService { } /** - * 메뉴 수정 - * @param {number} menuId - 메뉴 ID - * @param {Object} menuData - 수정할 메뉴 정보 - * @returns {Promise} 수정 결과 + * 메뉴 등록 (registerMenu 별칭) + * @param {Object} menuData - 메뉴 정보 + * @returns {Promise} 등록 결과 */ - async updateMenu(menuId, menuData) { + async registerMenu(menuData) { + return await this.createMenu(menuData) + } + + /** + * 메뉴 수정 + * @param {number} menuId - 메뉴 ID + * @param {Object} menuData - 수정할 메뉴 정보 + * @returns {Promise} 수정 결과 + */ +async updateMenu(menuId, menuData) { + try { + console.log('=== 메뉴 수정 API 호출 ===') + console.log('메뉴 ID:', menuId, '타입:', typeof menuId) + console.log('원본 수정 데이터:', menuData) + + if (!menuId || menuId === 'undefined') { + throw new Error('올바른 메뉴 ID가 필요합니다') + } + + const numericMenuId = parseInt(menuId) + if (isNaN(numericMenuId)) { + throw new Error('메뉴 ID는 숫자여야 합니다') + } + + // 데이터 검증 및 정리 + const menuName = menuData.menuName || menuData.name + const category = menuData.category + const price = menuData.price + const description = menuData.description || '' + + // 필수 필드 검증 + if (!menuName || !category || price === undefined || price === null) { + console.error('필수 필드 누락:', { menuName, category, price, description }) + throw new Error('메뉴명, 카테고리, 가격은 필수 입력 사항입니다') + } + + // 가격 검증 (숫자이고 0 이상) + const numericPrice = parseInt(price) + if (isNaN(numericPrice) || numericPrice < 0) { + throw new Error('올바른 가격을 입력해주세요') + } + + // 백엔드 MenuUpdateRequest DTO에 맞는 데이터 구조 + const requestData = { + menuName: menuName.trim(), + category: category.trim(), + price: numericPrice, + description: description.trim() + } + + console.log('검증된 백엔드 전송 데이터:', requestData) + console.log('✅ 검증된 메뉴 ID:', numericMenuId) + + // PUT /api/menu/{menuId} + const response = await menuApi.put(`/${numericMenuId}`, requestData) + + console.log('메뉴 수정 API 응답:', response.data) + + if (response.data && response.data.status === 200) { + return formatSuccessResponse(response.data.data, '메뉴가 성공적으로 수정되었습니다.') + } else { + throw new Error(response.data.message || '메뉴 수정에 실패했습니다.') + } + } catch (error) { + console.error('메뉴 수정 실패:', error) + + // HTTP 응답 에러 상세 디버깅 + if (error.response) { + console.error('=== HTTP 응답 에러 상세 ===') + console.error('상태 코드:', error.response.status) + console.error('상태 텍스트:', error.response.statusText) + console.error('응답 데이터:', error.response.data) + console.error('요청 URL:', error.config?.url) + console.error('요청 메서드:', error.config?.method) + console.error('요청 데이터:', error.config?.data) + + // 400 에러 (잘못된 요청) 처리 + if (error.response.status === 400) { + const errorMessage = error.response.data?.message || '입력 데이터가 올바르지 않습니다.' + console.error('백엔드 validation 에러:', errorMessage) + + return { + success: false, + message: errorMessage, + error: error.response.data + } + } + + // 500 오류 처리 + if (error.response.status === 500) { + const errorMessage = error.response.data?.message || '서버 내부 오류가 발생했습니다.' + console.error('백엔드 에러 메시지:', errorMessage) + + return { + success: false, + message: errorMessage, + error: error.response.data + } + } + } + + return handleApiError(error) + } +} + + + /** + * 메뉴 이미지 업로드 + * @param {number} menuId - 메뉴 ID + * @param {File} file - 이미지 파일 + * @returns {Promise} 업로드 결과 + */ + async uploadMenuImage(menuId, file) { try { - console.log('=== 메뉴 수정 API 호출 ===') - console.log('메뉴 ID:', menuId) - console.log('수정 데이터:', menuData) + console.log('=== 메뉴 이미지 업로드 API 호출 ===') + console.log('메뉴 ID:', menuId, '파일:', file?.name) if (!menuId || menuId === 'undefined') { throw new Error('올바른 메뉴 ID가 필요합니다') } + if (!file) { + throw new Error('업로드할 파일이 필요합니다') + } + const numericMenuId = parseInt(menuId) if (isNaN(numericMenuId)) { throw new Error('메뉴 ID는 숫자여야 합니다') } - const requestData = { - menuName: menuData.menuName, - category: menuData.category, - price: parseInt(menuData.price) || 0, - description: menuData.description || '' - } + // FormData 생성 + const formData = new FormData() + formData.append('file', file) - console.log('백엔드 전송 데이터:', requestData) + console.log('이미지 업로드 요청 - 메뉴 ID:', numericMenuId) - // PUT /api/menu/{menuId} - const response = await menuApi.put(`/${numericMenuId}`, requestData) + // POST /api/images/menu/{menuId} + const response = await apiWithImage.post(`/images/menu/${numericMenuId}`, formData, { + headers: { + 'Content-Type': 'multipart/form-data' + } + }) - console.log('메뉴 수정 API 응답:', response.data) + console.log('메뉴 이미지 업로드 API 응답:', response.data) - if (response.data && response.data.status === 200) { - return formatSuccessResponse(response.data.data, '메뉴가 성공적으로 수정되었습니다.') + if (response.data && (response.data.status === 200 || response.data.success !== false)) { + return formatSuccessResponse(response.data.data || response.data, '메뉴 이미지가 업로드되었습니다.') } else { - throw new Error(response.data.message || '메뉴 수정에 실패했습니다.') + throw new Error(response.data.message || '이미지 업로드에 실패했습니다.') } } catch (error) { - console.error('메뉴 수정 실패:', error) + console.error('메뉴 이미지 업로드 실패:', error) return handleApiError(error) } } @@ -207,4 +288,222 @@ export default menuService // 디버깅을 위한 전역 노출 (개발 환경에서만) if (process.env.NODE_ENV === 'development') { window.menuService = menuService +} + +//* src/views/StoreManagementView.vue의 수정된 스크립트 부분 +// \ No newline at end of file