| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- import axios from 'axios'
- import { useLoading } from './useLoading'
- // API Base URL (환경변수 또는 기본값)
- const API_BASE_URL = process.env.NUXT_PUBLIC_API_BASE || 'https://gojinaudi.mycafe24.com/api'
- // Axios 인스턴스 생성
- const apiClient = axios.create({
- baseURL: API_BASE_URL,
- timeout: 30000,
- headers: {
- 'Content-Type': 'application/json'
- }
- })
- // 로딩 카운터 (동시에 여러 요청이 있을 수 있으므로)
- let pendingRequests = 0
- const { showLoading, hideLoading } = useLoading()
- // Request Interceptor (토큰 자동 추가 + 로딩 시작)
- apiClient.interceptors.request.use(
- (config) => {
- // 로딩 카운터 증가
- pendingRequests++
- if (pendingRequests === 1) {
- showLoading()
- }
- if (typeof window !== 'undefined' && typeof localStorage !== 'undefined') {
- const token = localStorage.getItem('admin_token')
- if (token) {
- config.headers.Authorization = `Bearer ${token}`
- console.log('[useApi] Request with token:', config.url, token.substring(0, 20) + '...')
- } else {
- console.log('[useApi] Request without token:', config.url)
- }
- }
- return config
- },
- (error) => {
- // 에러 발생시에도 카운터 감소
- pendingRequests--
- if (pendingRequests === 0) {
- hideLoading()
- }
- return Promise.reject(error)
- }
- )
- // Response Interceptor (에러 처리 + 로딩 종료)
- apiClient.interceptors.response.use(
- (response) => {
- // 로딩 카운터 감소
- pendingRequests--
- if (pendingRequests === 0) {
- hideLoading()
- }
- console.log('[useApi] Response:', response.config.url, response.status)
- return response
- },
- (error) => {
- // 에러 시에도 카운터 감소
- pendingRequests--
- if (pendingRequests === 0) {
- hideLoading()
- }
- const status = error.response?.status
- const url = error.config?.url
- console.log('[useApi] Error:', {
- url,
- status,
- message: error.message,
- hasToken: !!localStorage.getItem('admin_token')
- })
- // 401 에러만 토큰 삭제 및 로그아웃 처리
- if (status === 401) {
- console.log('[useApi] 401 Unauthorized - 토큰 삭제 및 로그아웃')
- if (typeof window !== 'undefined') {
- localStorage.removeItem('admin_token')
- localStorage.removeItem('admin_user')
- window.location.href = '/admin'
- }
- } else {
- console.log('[useApi] 401이 아닌 에러 - 토큰 유지')
- }
- return Promise.reject(error)
- }
- )
- export const useApi = () => {
- // GET 요청
- const get = async (url, config = {}) => {
- try {
- const response = await apiClient.get(url, config)
- // 전체 응답 반환: { success, data, message }
- return { data: response.data, error: null }
- } catch (error) {
- return { data: null, error: error.response?.data || error.message }
- }
- }
- // POST 요청
- const post = async (url, data = {}) => {
- try {
- const response = await apiClient.post(url, data)
- // 전체 응답 반환: { success, data, message }
- return { data: response.data, error: null }
- } catch (error) {
- return { data: null, error: error.response?.data || error.message }
- }
- }
- // PUT 요청
- const put = async (url, data = {}) => {
- try {
- const response = await apiClient.put(url, data)
- // 전체 응답 반환: { success, data, message }
- return { data: response.data, error: null }
- } catch (error) {
- return { data: null, error: error.response?.data || error.message }
- }
- }
- // DELETE 요청
- const del = async (url) => {
- try {
- const response = await apiClient.delete(url)
- // 전체 응답 반환: { success, data, message }
- return { data: response.data, error: null }
- } catch (error) {
- return { data: null, error: error.response?.data || error.message }
- }
- }
- // 파일 업로드
- const upload = async (url, formData) => {
- try {
- const response = await apiClient.post(url, formData, {
- headers: {
- 'Content-Type': 'multipart/form-data'
- }
- })
- // 전체 응답 반환: { success, data, message }
- return { data: response.data, error: null }
- } catch (error) {
- return { data: null, error: error.response?.data || error.message }
- }
- }
- return {
- get,
- post,
- put,
- del,
- upload
- }
- }
|