source merge
This commit is contained in:
parent
55025dad57
commit
43595d5e72
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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<Object>} 메뉴 상세 정보
|
||||
*/
|
||||
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<Object>} 등록 결과
|
||||
*/
|
||||
@ -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 || ''
|
||||
@ -118,17 +83,26 @@ class MenuService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 메뉴 등록 (registerMenu 별칭)
|
||||
* @param {Object} menuData - 메뉴 정보
|
||||
* @returns {Promise<Object>} 등록 결과
|
||||
*/
|
||||
async registerMenu(menuData) {
|
||||
return await this.createMenu(menuData)
|
||||
}
|
||||
|
||||
/**
|
||||
* 메뉴 수정
|
||||
* @param {number} menuId - 메뉴 ID
|
||||
* @param {Object} menuData - 수정할 메뉴 정보
|
||||
* @returns {Promise<Object>} 수정 결과
|
||||
*/
|
||||
async updateMenu(menuId, menuData) {
|
||||
async updateMenu(menuId, menuData) {
|
||||
try {
|
||||
console.log('=== 메뉴 수정 API 호출 ===')
|
||||
console.log('메뉴 ID:', menuId)
|
||||
console.log('수정 데이터:', menuData)
|
||||
console.log('메뉴 ID:', menuId, '타입:', typeof menuId)
|
||||
console.log('원본 수정 데이터:', menuData)
|
||||
|
||||
if (!menuId || menuId === 'undefined') {
|
||||
throw new Error('올바른 메뉴 ID가 필요합니다')
|
||||
@ -139,14 +113,34 @@ class MenuService {
|
||||
throw new Error('메뉴 ID는 숫자여야 합니다')
|
||||
}
|
||||
|
||||
const requestData = {
|
||||
menuName: menuData.menuName,
|
||||
category: menuData.category,
|
||||
price: parseInt(menuData.price) || 0,
|
||||
description: menuData.description || ''
|
||||
// 데이터 검증 및 정리
|
||||
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('메뉴명, 카테고리, 가격은 필수 입력 사항입니다')
|
||||
}
|
||||
|
||||
console.log('백엔드 전송 데이터:', requestData)
|
||||
// 가격 검증 (숫자이고 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)
|
||||
@ -160,6 +154,93 @@ class MenuService {
|
||||
}
|
||||
} 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<Object>} 업로드 결과
|
||||
*/
|
||||
async uploadMenuImage(menuId, file) {
|
||||
try {
|
||||
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는 숫자여야 합니다')
|
||||
}
|
||||
|
||||
// FormData 생성
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
|
||||
console.log('이미지 업로드 요청 - 메뉴 ID:', numericMenuId)
|
||||
|
||||
// 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)
|
||||
|
||||
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 || '이미지 업로드에 실패했습니다.')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('메뉴 이미지 업로드 실패:', error)
|
||||
return handleApiError(error)
|
||||
}
|
||||
}
|
||||
@ -208,3 +289,221 @@ export default menuService
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
window.menuService = menuService
|
||||
}
|
||||
|
||||
//* src/views/StoreManagementView.vue의 수정된 스크립트 부분
|
||||
// <script setup> 내부의 메뉴 관련 함수들만 수정
|
||||
|
||||
// 메뉴 상세 보기 함수 - 메뉴 목록 데이터 활용
|
||||
const viewMenuDetail = (menu) => {
|
||||
console.log('=== 메뉴 상세 보기 호출 ===')
|
||||
console.log('전달받은 메뉴 객체:', menu)
|
||||
|
||||
// 메뉴 ID 추출 (여러 형태 지원)
|
||||
const menuId = menu.menuId || menu.id
|
||||
|
||||
if (!menuId) {
|
||||
console.error('❌ 메뉴 ID를 찾을 수 없음:', menu)
|
||||
showSnackbar('메뉴 정보가 올바르지 않습니다', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
console.log('✅ 사용할 메뉴 ID:', menuId)
|
||||
|
||||
// API 호출 없이 바로 메뉴 목록의 데이터 사용
|
||||
selectedMenu.value = {
|
||||
...menu,
|
||||
// 호환성을 위해 여러 형태 지원
|
||||
id: menuId,
|
||||
menuId: menuId,
|
||||
name: menu.menuName || menu.name,
|
||||
menuName: menu.menuName || menu.name
|
||||
}
|
||||
|
||||
console.log('✅ 메뉴 상세 정보 설정 완료:', selectedMenu.value)
|
||||
showMenuDetailDialog.value = true
|
||||
}
|
||||
|
||||
// 메뉴 수정 함수
|
||||
const editMenu = (menu) => {
|
||||
console.log('=== 메뉴 수정 호출 ===')
|
||||
console.log('전달받은 메뉴 객체:', menu)
|
||||
|
||||
// 메뉴 ID 추출 및 검증
|
||||
const menuId = menu.menuId || menu.id
|
||||
|
||||
console.log('추출된 메뉴 ID:', menuId, '타입:', typeof menuId)
|
||||
|
||||
if (!menuId) {
|
||||
console.error('❌ 메뉴 ID를 찾을 수 없음')
|
||||
showSnackbar('메뉴 정보가 올바르지 않습니다', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
console.log('✅ 사용할 메뉴 ID:', menuId)
|
||||
|
||||
// 수정 모드로 설정
|
||||
menuEditMode.value = true
|
||||
|
||||
// 폼 데이터 설정 (여러 필드명 지원)
|
||||
menuFormData.value = {
|
||||
menuId: menuId,
|
||||
id: menuId, // 호환성
|
||||
menuName: menu.menuName || menu.name,
|
||||
name: menu.menuName || menu.name, // 호환성
|
||||
category: menu.category,
|
||||
price: menu.price,
|
||||
description: menu.description || '',
|
||||
imageUrl: menu.imageUrl
|
||||
}
|
||||
|
||||
console.log('✅ 수정 폼 데이터 설정 완료:', menuFormData.value)
|
||||
|
||||
// 다이얼로그 표시
|
||||
showMenuDialog.value = true
|
||||
}
|
||||
|
||||
// 메뉴 상세에서 수정 버튼 클릭
|
||||
const editFromDetail = () => {
|
||||
console.log('=== 메뉴 상세에서 수정 버튼 클릭 ===')
|
||||
console.log('selectedMenu.value:', selectedMenu.value)
|
||||
|
||||
if (!selectedMenu.value) {
|
||||
showSnackbar('선택된 메뉴가 없습니다', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
// 메뉴 ID 검증
|
||||
const menuId = selectedMenu.value.menuId || selectedMenu.value.id
|
||||
if (!menuId) {
|
||||
showSnackbar('메뉴 ID를 찾을 수 없습니다', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
console.log('✅ 수정할 메뉴 정보:', {
|
||||
id: menuId,
|
||||
name: selectedMenu.value.menuName || selectedMenu.value.name,
|
||||
category: selectedMenu.value.category
|
||||
})
|
||||
|
||||
// 상세 다이얼로그 닫기
|
||||
closeMenuDetail()
|
||||
|
||||
// 수정 모드로 전환
|
||||
editMenu(selectedMenu.value)
|
||||
}
|
||||
|
||||
// 상세 다이얼로그 닫기
|
||||
const closeMenuDetail = () => {
|
||||
console.log('=== 메뉴 상세 다이얼로그 닫기 ===')
|
||||
showMenuDetailDialog.value = false
|
||||
selectedMenu.value = null
|
||||
}
|
||||
|
||||
// 메뉴 저장 함수 - 이미지 업로드 분리
|
||||
const saveMenuWithImage = async () => {
|
||||
if (saving.value) return
|
||||
|
||||
console.log('=== 메뉴 저장 + 이미지 업로드 시작 ===')
|
||||
saving.value = true
|
||||
|
||||
try {
|
||||
// 메뉴 서비스 임포트
|
||||
const { menuService } = await import('@/services/menu')
|
||||
|
||||
let menuResult
|
||||
|
||||
if (menuEditMode.value) {
|
||||
// 메뉴 수정 - PUT /api/menu/{menuId}
|
||||
const menuId = menuFormData.value.id || menuFormData.value.menuId
|
||||
if (!menuId) {
|
||||
showSnackbar('메뉴 ID가 없습니다', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
console.log('메뉴 수정 API 호출, 메뉴 ID:', menuId)
|
||||
|
||||
// 메뉴 데이터 준비
|
||||
const menuData = {
|
||||
menuName: menuFormData.value.menuName || menuFormData.value.name,
|
||||
category: menuFormData.value.category,
|
||||
price: menuFormData.value.price,
|
||||
description: menuFormData.value.description || ''
|
||||
}
|
||||
|
||||
menuResult = await menuService.updateMenu(menuId, menuData)
|
||||
} else {
|
||||
// 새 메뉴 등록 - POST /api/menu/register
|
||||
const storeId = storeInfo.value?.storeId
|
||||
if (!storeId) {
|
||||
showSnackbar('매장 정보를 찾을 수 없습니다', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
// 메뉴 데이터 준비 (매장 ID 포함)
|
||||
const menuData = {
|
||||
storeId: storeId,
|
||||
menuName: menuFormData.value.menuName || menuFormData.value.name,
|
||||
category: menuFormData.value.category,
|
||||
price: menuFormData.value.price,
|
||||
description: menuFormData.value.description || ''
|
||||
}
|
||||
|
||||
console.log('메뉴 등록 API 호출, 매장 ID:', storeId)
|
||||
menuResult = await menuService.createMenu(menuData)
|
||||
}
|
||||
|
||||
console.log('✅ 메뉴 저장 완료:', menuResult)
|
||||
|
||||
if (!menuResult.success) {
|
||||
showSnackbar(menuResult.message || '메뉴 저장에 실패했습니다', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
// 메뉴 저장 성공 후 이미지 업로드
|
||||
let imageResult = { success: true }
|
||||
|
||||
if (selectedImageFile.value) {
|
||||
console.log('=== 이미지 업로드 시작 ===')
|
||||
|
||||
// 등록된 메뉴의 ID 가져오기
|
||||
const menuId = menuEditMode.value
|
||||
? (menuFormData.value.id || menuFormData.value.menuId)
|
||||
: menuResult.data?.menuId
|
||||
|
||||
if (menuId) {
|
||||
console.log('이미지 업로드 - 메뉴 ID:', menuId)
|
||||
imageResult = await menuService.uploadMenuImage(menuId, selectedImageFile.value)
|
||||
console.log('이미지 업로드 결과:', imageResult)
|
||||
|
||||
if (!imageResult.success) {
|
||||
console.warn('이미지 업로드는 실패했지만 메뉴는 저장됨')
|
||||
showSnackbar('메뉴는 저장되었지만 이미지 업로드에 실패했습니다', 'warning')
|
||||
}
|
||||
} else {
|
||||
console.warn('메뉴 ID를 찾을 수 없어 이미지 업로드 생략')
|
||||
}
|
||||
}
|
||||
|
||||
// 성공 메시지
|
||||
if (menuResult.success && imageResult.success) {
|
||||
showSnackbar(
|
||||
menuEditMode.value ? '메뉴가 수정되었습니다' : '메뉴가 등록되었습니다',
|
||||
'success'
|
||||
)
|
||||
}
|
||||
|
||||
// 다이얼로그 닫기 및 초기화
|
||||
showMenuDialog.value = false
|
||||
menuEditMode.value = false
|
||||
resetMenuForm()
|
||||
|
||||
// 메뉴 목록 새로고침
|
||||
await loadMenus()
|
||||
|
||||
} catch (error) {
|
||||
console.error('메뉴 저장 중 오류:', error)
|
||||
showSnackbar('저장 중 오류가 발생했습니다', 'error')
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
@ -1,18 +1,9 @@
|
||||
<<<<<<< HEAD
|
||||
//* src/services/store.js - 매출 API 수정버전
|
||||
import { storeApi, salesApi, handleApiError, formatSuccessResponse } from './api.js'
|
||||
|
||||
/**
|
||||
* 매장 관련 API 서비스
|
||||
* 유저스토리: STR-005, STR-010, STR-015, STR-020, STR-025, STR-030, STR-035, STR-040
|
||||
=======
|
||||
//* src/services/store.js - 매장 서비스 완전 수정
|
||||
import { storeApi, handleApiError, formatSuccessResponse } from './api.js'
|
||||
|
||||
/**
|
||||
* 매장 관련 API 서비스
|
||||
* 백엔드 Store Controller와 연동 (포트 8082)
|
||||
>>>>>>> 87871709f2bbcdab5df004a3954d6ba0af3cadce
|
||||
*/
|
||||
class StoreService {
|
||||
/**
|
||||
@ -28,22 +19,9 @@ class StoreService {
|
||||
// 백엔드 StoreCreateRequest에 맞는 형태로 변환
|
||||
const requestData = {
|
||||
storeName: storeData.storeName,
|
||||
storeImage: storeData.storeImage,
|
||||
businessType: storeData.businessType,
|
||||
address: storeData.address,
|
||||
phoneNumber: storeData.phoneNumber,
|
||||
<<<<<<< HEAD
|
||||
businessNumber: storeData.businessNumber,
|
||||
instaAccounts: storeData.instaAccounts,
|
||||
blogAccounts: storeData.blogAccounts,
|
||||
businessHours: storeData.businessHours,
|
||||
closedDays: storeData.closedDays,
|
||||
seatCount: storeData.seatCount,
|
||||
description: storeData.description,
|
||||
})
|
||||
|
||||
return formatSuccessResponse(response.data.data, '매장이 등록되었습니다.')
|
||||
=======
|
||||
businessHours: storeData.businessHours,
|
||||
closedDays: storeData.closedDays,
|
||||
seatCount: parseInt(storeData.seatCount) || 0,
|
||||
@ -74,7 +52,6 @@ class StoreService {
|
||||
} else {
|
||||
throw new Error(response.data.message || '매장 등록에 실패했습니다.')
|
||||
}
|
||||
>>>>>>> 87871709f2bbcdab5df004a3954d6ba0af3cadce
|
||||
} catch (error) {
|
||||
console.error('매장 등록 실패:', error)
|
||||
|
||||
@ -154,11 +131,6 @@ class StoreService {
|
||||
*/
|
||||
async updateStore(storeId, storeData) {
|
||||
try {
|
||||
<<<<<<< HEAD
|
||||
const response = await storeApi.put('/', storeData)
|
||||
|
||||
return formatSuccessResponse(response.data.data, '매장 정보가 수정되었습니다.')
|
||||
=======
|
||||
console.log('=== 매장 정보 수정 API 호출 ===')
|
||||
console.log('요청 데이터:', storeData)
|
||||
|
||||
@ -192,7 +164,6 @@ class StoreService {
|
||||
} else {
|
||||
throw new Error(response.data.message || '매장 정보 수정에 실패했습니다.')
|
||||
}
|
||||
>>>>>>> 87871709f2bbcdab5df004a3954d6ba0af3cadce
|
||||
} catch (error) {
|
||||
console.error('매장 정보 수정 실패:', error)
|
||||
return handleApiError(error)
|
||||
@ -201,32 +172,11 @@ class StoreService {
|
||||
|
||||
/**
|
||||
* 매출 정보 조회 (STR-020: 대시보드)
|
||||
<<<<<<< HEAD
|
||||
* ⚠️ 수정: salesApi 사용하고 storeId 매개변수 추가
|
||||
* @param {number} storeId - 매장 ID
|
||||
=======
|
||||
* @param {string} period - 조회 기간 (today, week, month, year)
|
||||
>>>>>>> 87871709f2bbcdab5df004a3954d6ba0af3cadce
|
||||
* @returns {Promise<Object>} 매출 정보
|
||||
*/
|
||||
async getSales(period = 'today') {
|
||||
try {
|
||||
<<<<<<< HEAD
|
||||
// storeId가 없으면 먼저 매장 정보를 조회해서 storeId를 가져옴
|
||||
if (!storeId) {
|
||||
const storeResponse = await this.getStore()
|
||||
if (storeResponse.success && storeResponse.data.storeId) {
|
||||
storeId = storeResponse.data.storeId
|
||||
} else {
|
||||
throw new Error('매장 정보를 찾을 수 없습니다.')
|
||||
}
|
||||
}
|
||||
|
||||
// Sales API 호출 (Store 서비스의 /api/sales/{storeId} 엔드포인트)
|
||||
const response = await salesApi.get(`/${storeId}`)
|
||||
|
||||
return formatSuccessResponse(response.data.data, '매출 정보를 조회했습니다.')
|
||||
=======
|
||||
// 현재는 목업 데이터 반환 (추후 실제 API 연동 시 수정)
|
||||
const mockSalesData = {
|
||||
todaySales: 150000,
|
||||
@ -237,7 +187,6 @@ class StoreService {
|
||||
}
|
||||
|
||||
return formatSuccessResponse(mockSalesData, '매출 정보를 조회했습니다.')
|
||||
>>>>>>> 87871709f2bbcdab5df004a3954d6ba0af3cadce
|
||||
} catch (error) {
|
||||
console.error('매출 정보 조회 실패:', error)
|
||||
return handleApiError(error)
|
||||
@ -245,89 +194,11 @@ class StoreService {
|
||||
}
|
||||
|
||||
/**
|
||||
<<<<<<< HEAD
|
||||
* 메뉴 등록 (STR-030: 메뉴 등록)
|
||||
* ⚠️ 수정: 올바른 API 경로 사용
|
||||
* @param {Object} menuData - 메뉴 정보
|
||||
* @returns {Promise<Object>} 메뉴 등록 결과
|
||||
*/
|
||||
async registerMenu(menuData) {
|
||||
try {
|
||||
// Store 서비스의 Menu API 사용
|
||||
const response = await storeApi.post('/menu/register', {
|
||||
storeId: menuData.storeId,
|
||||
menuName: menuData.menuName,
|
||||
category: menuData.category,
|
||||
price: menuData.price,
|
||||
description: menuData.description,
|
||||
})
|
||||
|
||||
return formatSuccessResponse(response.data.data, '메뉴가 등록되었습니다.')
|
||||
} catch (error) {
|
||||
return handleApiError(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 메뉴 목록 조회 (STR-025: 메뉴 조회)
|
||||
* @param {number} storeId - 매장 ID
|
||||
=======
|
||||
* 메뉴 목록 조회 (개발 예정)
|
||||
>>>>>>> 87871709f2bbcdab5df004a3954d6ba0af3cadce
|
||||
* @returns {Promise<Object>} 메뉴 목록
|
||||
*/
|
||||
async getMenus() {
|
||||
try {
|
||||
<<<<<<< HEAD
|
||||
const response = await storeApi.get(`/menu?storeId=${storeId}`)
|
||||
|
||||
return formatSuccessResponse(response.data.data, '메뉴 목록을 조회했습니다.')
|
||||
} catch (error) {
|
||||
return handleApiError(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 메뉴 수정 (STR-035: 메뉴 수정)
|
||||
* @param {number} menuId - 메뉴 ID
|
||||
* @param {Object} menuData - 수정할 메뉴 정보
|
||||
* @returns {Promise<Object>} 메뉴 수정 결과
|
||||
*/
|
||||
async updateMenu(menuId, menuData) {
|
||||
try {
|
||||
const response = await storeApi.put(`/menu/${menuId}`, menuData)
|
||||
|
||||
return formatSuccessResponse(response.data.data, '메뉴가 수정되었습니다.')
|
||||
} catch (error) {
|
||||
return handleApiError(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 메뉴 삭제 (STR-040: 메뉴 삭제)
|
||||
* @param {number} menuId - 메뉴 ID
|
||||
* @returns {Promise<Object>} 메뉴 삭제 결과
|
||||
*/
|
||||
async deleteMenu(menuId) {
|
||||
try {
|
||||
await storeApi.delete(`/menu/${menuId}`)
|
||||
|
||||
return formatSuccessResponse(null, '메뉴가 삭제되었습니다.')
|
||||
} catch (error) {
|
||||
return handleApiError(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 매장 통계 정보 조회
|
||||
* @returns {Promise<Object>} 매장 통계
|
||||
*/
|
||||
async getStoreStatistics() {
|
||||
try {
|
||||
const response = await storeApi.get('/statistics')
|
||||
|
||||
return formatSuccessResponse(response.data.data, '매장 통계를 조회했습니다.')
|
||||
=======
|
||||
// 현재는 목업 데이터 반환 (추후 실제 API 연동 시 수정)
|
||||
const mockMenus = [
|
||||
{
|
||||
@ -351,7 +222,6 @@ class StoreService {
|
||||
]
|
||||
|
||||
return formatSuccessResponse(mockMenus, '메뉴 목록을 조회했습니다.')
|
||||
>>>>>>> 87871709f2bbcdab5df004a3954d6ba0af3cadce
|
||||
} catch (error) {
|
||||
return handleApiError(error)
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
//* src/store/index.js - Store 스토어 수정 (fetchMenus 메서드 추가)
|
||||
//* src/store/index.js - Store 스토어 (완전한 버전)
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useStoreStore = defineStore('store', {
|
||||
@ -80,7 +80,7 @@ export const useStoreStore = defineStore('store', {
|
||||
},
|
||||
|
||||
/**
|
||||
* 메뉴 목록 조회 - 실제 API 연동 (매장 ID 필요)
|
||||
* 메뉴 목록 조회 - 실제 API 연동 (매장 ID 필요) - ✅ ID 필드 보장
|
||||
*/
|
||||
async fetchMenus() {
|
||||
console.log('=== Store 스토어: 메뉴 목록 조회 시작 ===')
|
||||
@ -106,10 +106,34 @@ export const useStoreStore = defineStore('store', {
|
||||
console.log('Result.message:', result.message)
|
||||
|
||||
if (result.success && result.data) {
|
||||
// ✅ 메뉴 데이터 ID 필드 보장 처리
|
||||
const menusWithId = (result.data || []).map(menu => {
|
||||
// ID 필드가 확실히 있도록 보장
|
||||
const menuId = menu.menuId || menu.id
|
||||
|
||||
if (!menuId) {
|
||||
console.warn('⚠️ 메뉴 ID가 없는 항목 발견:', menu)
|
||||
}
|
||||
|
||||
return {
|
||||
...menu,
|
||||
id: menuId, // ✅ id 필드 확실히 설정
|
||||
menuId: menuId, // ✅ menuId 필드도 설정
|
||||
// 기타 필드들 보장
|
||||
menuName: menu.menuName || menu.name || '이름 없음',
|
||||
category: menu.category || '기타',
|
||||
price: menu.price || 0,
|
||||
description: menu.description || '',
|
||||
available: menu.available !== undefined ? menu.available : true,
|
||||
recommended: menu.recommended !== undefined ? menu.recommended : false,
|
||||
imageUrl: menu.imageUrl || '/images/menu-placeholder.png'
|
||||
}
|
||||
})
|
||||
|
||||
// 메뉴 목록이 있는 경우
|
||||
console.log('✅ 메뉴 목록 설정:', result.data)
|
||||
this.menus = result.data
|
||||
return { success: true, data: result.data }
|
||||
console.log('✅ 메뉴 목록 설정 (ID 보장됨):', menusWithId)
|
||||
this.menus = menusWithId
|
||||
return { success: true, data: menusWithId }
|
||||
} else {
|
||||
// 메뉴가 없거나 조회 실패한 경우
|
||||
console.log('⚠️ 메뉴 목록 없음 또는 조회 실패')
|
||||
|
||||
@ -229,36 +229,30 @@
|
||||
<v-card class="mb-4" elevation="1" v-if="useAI">
|
||||
<v-card-title class="text-h6 py-3">AI 옵션 설정</v-card-title>
|
||||
<v-card-text>
|
||||
<!-- 톤앤매너 -->
|
||||
<!-- 타겟 연령층 - 간단하고 확실한 방법으로 수정 -->
|
||||
<v-select
|
||||
v-model="aiOptions.toneAndManner"
|
||||
:items="toneOptions"
|
||||
label="톤앤매너"
|
||||
v-model="aiOptions.targetAge"
|
||||
:items="targetAgeOptions"
|
||||
label="타겟 연령층"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
class="mb-3"
|
||||
prepend-inner-icon="mdi-account-group"
|
||||
>
|
||||
<template #item="{ props, item }">
|
||||
<v-list-item
|
||||
v-bind="props"
|
||||
:prepend-icon="getAgeIcon(item.value)"
|
||||
:title="item.title"
|
||||
/>
|
||||
|
||||
<!-- 홍보 유형 -->
|
||||
<v-select
|
||||
v-model="aiOptions.promotion"
|
||||
:items="promotionOptions"
|
||||
label="홍보 유형"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
class="mb-3"
|
||||
/>
|
||||
|
||||
<!-- 감정 강도 -->
|
||||
<v-select
|
||||
v-model="aiOptions.emotionIntensity"
|
||||
:items="emotionOptions"
|
||||
label="감정 강도"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
class="mb-3"
|
||||
/>
|
||||
|
||||
</template>
|
||||
<template #selection="{ item }">
|
||||
<v-chip size="small" color="primary" class="ml-1">
|
||||
<v-icon start size="small">{{ getAgeIcon(item.value) }}</v-icon>
|
||||
{{ item.title }}
|
||||
</v-chip>
|
||||
</template>
|
||||
</v-select>
|
||||
<!-- 포토 스타일 (포스터인 경우) -->
|
||||
<v-select
|
||||
v-if="selectedType === 'poster'"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user